76
76
int password_verify(const char *plaintext, const char *user, const char *scheme,
77
const unsigned char *raw_password, size_t size)
77
const unsigned char *raw_password, size_t size,
79
80
const struct password_scheme *s;
80
81
enum password_encoding encoding;
81
82
const unsigned char *generated;
82
83
size_t generated_size;
84
86
s = password_scheme_lookup(scheme, &encoding);
88
*error_r = "Unknown password scheme";
88
if (s->password_verify != NULL)
89
return s->password_verify(plaintext, user, raw_password, size);
91
/* generic verification handler: generate the password and compare it
92
to the one in database */
93
s->password_generate(plaintext, user, &generated, &generated_size);
94
return size != generated_size ? 0 :
95
memcmp(generated, raw_password, size) == 0;
92
if (s->password_verify != NULL) {
93
ret = s->password_verify(plaintext, user, raw_password, size,
96
/* generic verification handler: generate the password and
97
compare it to the one in database */
98
s->password_generate(plaintext, user,
99
&generated, &generated_size);
100
ret = size != generated_size ? 0 :
101
memcmp(generated, raw_password, size) == 0 ? 1 : 0;
105
*error_r = "Password mismatch";
98
109
const char *password_get_scheme(const char **password)
302
313
if (password_verify(plain_password, user, schemes[i]->name,
303
raw_password, raw_password_size) > 0)
314
raw_password, raw_password_size,
304
316
return schemes[i]->name;
309
bool crypt_verify(const char *plaintext, const char *user ATTR_UNUSED,
310
const unsigned char *raw_password, size_t size)
321
int crypt_verify(const char *plaintext, const char *user ATTR_UNUSED,
322
const unsigned char *raw_password, size_t size,
323
const char **error_r)
312
325
const char *password, *crypted;
315
328
/* the default mycrypt() handler would return match */
319
332
password = t_strndup(raw_password, size);
320
333
crypted = mycrypt(plaintext, password);
321
334
if (crypted == NULL) {
322
335
/* really shouldn't happen unless the system is broken */
323
i_error("crypt() failed: %m");
336
*error_r = t_strdup_printf("crypt() failed: %m");
327
return strcmp(crypted, password) == 0;
340
return strcmp(crypted, password) == 0 ? 1 : 0;
340
353
*size_r = strlen(password);
344
357
md5_verify(const char *plaintext, const char *user,
345
const unsigned char *raw_password, size_t size)
358
const unsigned char *raw_password, size_t size, const char **error_r)
347
360
const char *password, *str, *error;
348
361
const unsigned char *md5_password;
352
365
if (strncmp(password, "$1$", 3) == 0) {
354
367
str = password_generate_md5_crypt(plaintext, password);
355
return strcmp(str, password) == 0;
368
return strcmp(str, password) == 0 ? 1 : 0;
356
369
} else if (password_decode(password, "PLAIN-MD5",
357
370
&md5_password, &md5_size, &error) < 0) {
358
i_error("md5_verify(%s): Not a valid MD5-CRYPT or "
359
"PLAIN-MD5 password", user);
371
*error_r = "Not a valid MD5-CRYPT or PLAIN-MD5 password";
362
374
return password_verify(plaintext, user, "PLAIN-MD5",
363
md5_password, md5_size) > 0;
375
md5_password, md5_size, error_r);
368
380
md5_crypt_verify(const char *plaintext, const char *user ATTR_UNUSED,
369
const unsigned char *raw_password, size_t size)
381
const unsigned char *raw_password, size_t size,
382
const char **error_r ATTR_UNUSED)
371
384
const char *password, *str;
373
386
password = t_strndup(raw_password, size);
374
387
str = password_generate_md5_crypt(plaintext, password);
375
return strcmp(str, password) == 0;
388
return strcmp(str, password) == 0 ? 1 : 0;
453
466
*size_r = SHA1_RESULTLEN + SSHA_SALT_LEN;
456
static bool ssha_verify(const char *plaintext, const char *user,
457
const unsigned char *raw_password, size_t size)
469
static int ssha_verify(const char *plaintext, const char *user ATTR_UNUSED,
470
const unsigned char *raw_password, size_t size,
471
const char **error_r)
459
473
unsigned char sha1_digest[SHA1_RESULTLEN];
460
474
struct sha1_ctxt ctx;
462
476
/* format: <SHA1 hash><salt> */
463
477
if (size <= SHA1_RESULTLEN) {
464
i_error("ssha_verify(%s): SSHA password too short", user);
478
*error_r = "SSHA password is too short";
469
483
sha1_loop(&ctx, plaintext, strlen(plaintext));
470
484
sha1_loop(&ctx, raw_password + SHA1_RESULTLEN, size - SHA1_RESULTLEN);
471
485
sha1_result(&ctx, sha1_digest);
472
return memcmp(sha1_digest, raw_password, SHA1_RESULTLEN) == 0;
486
return memcmp(sha1_digest, raw_password, SHA1_RESULTLEN) == 0 ? 1 : 0;
493
507
*size_r = SHA256_RESULTLEN + SSHA256_SALT_LEN;
496
static bool ssha256_verify(const char *plaintext, const char *user,
497
const unsigned char *raw_password, size_t size)
510
static int ssha256_verify(const char *plaintext, const char *user ATTR_UNUSED,
511
const unsigned char *raw_password, size_t size,
512
const char **error_r)
499
514
unsigned char sha256_digest[SHA256_RESULTLEN];
500
515
struct sha256_ctx ctx;
502
517
/* format: <SHA256 hash><salt> */
503
518
if (size <= SHA256_RESULTLEN) {
504
i_error("ssha256_verify(%s): SSHA256 password too short", user);
519
*error_r = "SSHA256 password is too short";
508
523
sha256_init(&ctx);
510
525
sha256_loop(&ctx, raw_password + SHA256_RESULTLEN,
511
526
size - SHA256_RESULTLEN);
512
527
sha256_result(&ctx, sha256_digest);
513
return memcmp(sha256_digest, raw_password, SHA256_RESULTLEN) == 0;
528
return memcmp(sha256_digest, raw_password,
529
SHA256_RESULTLEN) == 0 ? 1 : 0;
534
550
*size_r = SHA512_RESULTLEN + SSHA512_SALT_LEN;
537
static bool ssha512_verify(const char *plaintext, const char *user,
538
const unsigned char *raw_password, size_t size)
553
static int ssha512_verify(const char *plaintext, const char *user ATTR_UNUSED,
554
const unsigned char *raw_password, size_t size,
555
const char **error_r)
540
557
unsigned char sha512_digest[SHA512_RESULTLEN];
541
558
struct sha512_ctx ctx;
543
560
/* format: <SHA512 hash><salt> */
544
561
if (size <= SHA512_RESULTLEN) {
545
i_error("ssha512_verify(%s): SSHA512 password too short", user);
562
*error_r = "SSHA512 password is too short";
549
566
sha512_init(&ctx);
551
568
sha512_loop(&ctx, raw_password + SHA512_RESULTLEN,
552
569
size - SHA512_RESULTLEN);
553
570
sha512_result(&ctx, sha512_digest);
554
return memcmp(sha512_digest, raw_password, SHA512_RESULTLEN) == 0;
571
return memcmp(sha512_digest, raw_password,
572
SHA512_RESULTLEN) == 0 ? 1 : 0;
575
593
*size_r = MD5_RESULTLEN + SMD5_SALT_LEN;
578
static bool smd5_verify(const char *plaintext, const char *user,
579
const unsigned char *raw_password, size_t size)
596
static int smd5_verify(const char *plaintext, const char *user ATTR_UNUSED,
597
const unsigned char *raw_password, size_t size,
598
const char **error_r)
581
600
unsigned char md5_digest[MD5_RESULTLEN];
582
601
struct md5_context ctx;
584
603
/* format: <MD5 hash><salt> */
585
604
if (size <= MD5_RESULTLEN) {
586
i_error("smd5_verify(%s): SMD5 password too short", user);
605
*error_r = "SMD5 password is too short";
591
610
md5_update(&ctx, plaintext, strlen(plaintext));
592
611
md5_update(&ctx, raw_password + MD5_RESULTLEN, size - MD5_RESULTLEN);
593
612
md5_final(&ctx, md5_digest);
594
return memcmp(md5_digest, raw_password, MD5_RESULTLEN) == 0;
613
return memcmp(md5_digest, raw_password, MD5_RESULTLEN) == 0 ? 1 : 0;
602
621
*size_r = strlen(plaintext);
625
plain_trunc_verify(const char *plaintext, const char *user ATTR_UNUSED,
626
const unsigned char *raw_password, size_t size,
627
const char **error_r)
629
unsigned int i, plaintext_len, trunc_len = 0;
631
/* format: <length>-<password> */
632
for (i = 0; i < size; i++) {
633
if (raw_password[i] >= '0' && raw_password[i] <= '9')
634
trunc_len = trunc_len*10 + raw_password[i]-'0';
638
if (i == size || raw_password[i] != '-') {
639
*error_r = "PLAIN-TRUNC missing length: prefix";
644
plaintext_len = strlen(plaintext);
645
if (size-i == trunc_len && plaintext_len >= trunc_len) {
646
/* possibly truncated password. allow the given password as
647
long as the prefix matches. */
648
return memcmp(raw_password+i, plaintext, trunc_len) == 0 ? 1 : 0;
650
return plaintext_len == size-i &&
651
memcmp(raw_password+i, plaintext, plaintext_len) == 0 ? 1 : 0;
606
655
cram_md5_generate(const char *plaintext, const char *user ATTR_UNUSED,
607
656
const unsigned char **raw_password_r, size_t *size_r)
700
749
*size_r = NTLMSSP_HASH_SIZE;
703
static bool otp_verify(const char *plaintext, const char *user ATTR_UNUSED,
704
const unsigned char *raw_password, size_t size)
752
static int otp_verify(const char *plaintext, const char *user ATTR_UNUSED,
753
const unsigned char *raw_password, size_t size,
754
const char **error_r)
706
const char *password;
756
const char *password, *generated;
708
758
password = t_strndup(raw_password, size);
709
return strcasecmp(password,
710
password_generate_otp(plaintext, password, -1)) == 0;
759
if (password_generate_otp(plaintext, password, -1, &generated) < 0) {
760
*error_r = "Invalid OTP data in passdb";
764
return strcasecmp(password, generated) == 0 ? 1 : 0;
717
771
const char *password;
719
password = password_generate_otp(plaintext, NULL, OTP_HASH_SHA1);
773
if (password_generate_otp(plaintext, NULL, OTP_HASH_SHA1, &password) < 0)
720
775
*raw_password_r = (const unsigned char *)password;
721
776
*size_r = strlen(password);
728
783
const char *password;
730
password = password_generate_otp(plaintext, NULL, OTP_HASH_MD4);
785
if (password_generate_otp(plaintext, NULL, OTP_HASH_MD4, &password) < 0)
731
787
*raw_password_r = (const unsigned char *)password;
732
788
*size_r = strlen(password);
762
818
{ "SSHA512", PW_ENCODING_BASE64, 0, ssha512_verify, ssha512_generate },
763
819
{ "PLAIN", PW_ENCODING_NONE, 0, NULL, plain_generate },
764
820
{ "CLEARTEXT", PW_ENCODING_NONE, 0, NULL, plain_generate },
821
{ "PLAIN-TRUNC", PW_ENCODING_NONE, 0, plain_trunc_verify, plain_generate },
765
822
{ "CRAM-MD5", PW_ENCODING_HEX, CRAM_MD5_CONTEXTLEN,
766
823
NULL, cram_md5_generate },
767
824
{ "HMAC-MD5", PW_ENCODING_HEX, CRAM_MD5_CONTEXTLEN,