|
postfixadmin mysql dovecot sasl - jak odczytac hasła w md5?
pixolated - 12-03-2007 12:53
DEBIAN SARGE r3.1
Mam skonfigurowany serwer pocztowy w ww konfiguracji. Gdy hasla sa przechowywane w bazie "cleartext" wszystko smiga. Chcialbym natomiast aby hasla w bazie byly kodowane (w postfixadmin jest cos takiego jak md5crypt).
Tu pojawia sie problem przy autentykacji gdyz auxprop jest ograniczony do hasel kodowanych w cram/digest-md5.
Czy ktos sie orientuje w jaki sposob wyciagnac z bazy i z sukcesem porownac zakodowane hasla. Moze jest jakas wtyczka do sasla do odczytu hasel w md5.
Gdzies znalazlem info o tym, ze nada sie nada do tego:
cyrus-sasl-2.1.21.tar.gz z patchem cyrus-sasl-2.1.19-checkpw.c.patch ale nie udalo mi sie tego skompilowac i uruchomic.
Moze ktos mial taki problem i wie jak w debianie mozna to zrobic za pomoca gotowych pakietow?
Pozdrawiam
joannes - 12-03-2007 13:09
Mam przerobionego patcha do wersji 2.1.22 jako 0016_checkpw.dpatch lub skonfiguruj sasla do obsługi rimap. Jak chcesz gotowe paczki, to pisz na prv. #! /bin/sh /usr/share/dpatch/dpatch-run ## 0016_checkpw.dpatch by <fabbe@debian.org> ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: decode64 does not cover all cases that can arise in practise. ## DP: This patch fixes the case where no padding characters are needed ## DP: but the input string is terminated by CRLF, CR or LF.
@DPATCH@ diff -urNad trunk~/configure.in trunk/configure.in --- trunk~/configure.in 2006-05-18 21:06:13.000000000 +0200 +++ trunk/configure.in 2006-12-15 13:43:22.000000000 +0100 @@ -1067,6 +1067,9 @@ dnl do we need to link in -lresolv? AC_CHECK_LIB(resolv, inet_aton)
+dnl do we need to link in -lcrypt? +AC_CHECK_LIB(crypt, inet_aton) + dnl Check for getaddrinfo GETADDRINFOOBJS="" sasl_cv_getaddrinfo=yes diff -urNad trunk~/lib/checkpw.c trunk/lib/checkpw.c --- trunk~/lib/checkpw.c 2006-03-13 19:30:41.000000000 +0100 +++ trunk/lib/checkpw.c 2006-12-15 13:43:22.000000000 +0100 @@ -94,6 +94,23 @@ # endif #endif
+/****************************** + * crypt(3) patch start * + ******************************/ +char *crypt(const char *key, const char *salt); + +/* cleartext password formats */ +#define PASSWORD_FORMAT_CLEARTEXT 1 +#define PASSWORD_FORMAT_CRYPT 2 +#define PASSWORD_FORMAT_CRYPTTRAD 3 +#define PASSWORD_SALT_BUF_LEN 22 + +/* weeds out crypt(3) password's salt */ +int _sasl_get_salt (char *dest, char *src, int format); + +/****************************** + * crypt(3) patch stop * + ******************************/
/* we store the following secret to check plaintext passwords: * @@ -143,7 +160,51 @@ "*cmusaslsecretPLAIN", NULL }; struct propval auxprop_values[3]; - + + /****************************** + * crypt(3) patch start * + * for password format check * + ******************************/ + sasl_getopt_t *getopt; + void *context; + const char *p = NULL; + /** + * MD5: 12 char salt + * BLOWFISH: 16 char salt + */ + char salt[PASSWORD_SALT_BUF_LEN]; + int password_format; + + /* get password format from auxprop configuration */ + if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) { + getopt(context, NULL, "password_format", &p, NULL); + } + + /* set password format */ + if (p) { + /* + memset(pass_format_str, '\0', PASSWORD_FORMAT_STR_LEN); + strncpy(pass_format_str, p, (PASSWORD_FORMAT_STR_LEN - 1)); + */ + /* modern, modular crypt(3) */ + if (strncmp(p, "crypt", 11) == 0) + password_format = PASSWORD_FORMAT_CRYPT; + /* traditional crypt(3) */ + else if (strncmp(p, "crypt_trad", 11) == 0) + password_format = PASSWORD_FORMAT_CRYPTTRAD; + /* cleartext password */ + else + password_format = PASSWORD_FORMAT_CLEARTEXT; + } else { + /* cleartext password */ + password_format = PASSWORD_FORMAT_CLEARTEXT; + } + + /****************************** + * crypt(3) patch stop * + * for password format check * + ******************************/ + if (!conn || !userstr) return SASL_BADPARAM;
@@ -180,14 +241,31 @@ goto done; }
- /* At the point this has been called, the username has been canonified - * and we've done the auxprop lookup. This should be easy. */ - if(auxprop_values[0].name - && auxprop_values[0].values - && auxprop_values[0].values[0] - && !strcmp(auxprop_values[0].values[0], passwd)) { - /* We have a plaintext version and it matched! */ - return SASL_OK; + + /****************************** + * crypt(3) patch start * + ******************************/ + + /* get salt */ + _sasl_get_salt(salt, (char *) auxprop_values[0].values[0], password_format); + + /* crypt(3)-ed password? */ + if (password_format != PASSWORD_FORMAT_CLEARTEXT) { + /* compare password */ + if (auxprop_values[0].name && auxprop_values[0].values && auxprop_values[0].values[0] && strcmp(crypt(passwd, salt), auxprop_values[0].values[0]) == 0) + return SASL_OK; + else + ret = SASL_BADAUTH; + } + else if (password_format == PASSWORD_FORMAT_CLEARTEXT) { + /* compare passwords */ + if (auxprop_values[0].name && auxprop_values[0].values && auxprop_values[0].values[0] && strcmp(auxprop_values[0].values[0], passwd) == 0) + return SASL_OK; + else + ret = SASL_BADAUTH; + /****************************** + * crypt(3) patch stop * + ******************************/ } else if(auxprop_values[1].name && auxprop_values[1].values && auxprop_values[1].values[0]) { @@ -975,3 +1053,37 @@ #endif { NULL, NULL } }; + +/* weeds out crypt(3) password's salt */ +int _sasl_get_salt (char *dest, char *src, int format) { + int num; /* how many characters is salt long? */ + switch (format) { + case PASSWORD_FORMAT_CRYPT: + /* md5 crypt */ + if (src[1] == '1') + num = 12; + /* blowfish crypt */ + else if (src[1] == '2') + num = (src[1] == '2' && src[2] == 'a') ? 17 : 16; + /* traditional crypt */ + else + num = 2; + break; + + case PASSWORD_FORMAT_CRYPTTRAD: + num = 2; + break; + + default: + return 1; + } + + /* destroy destination */ + memset(dest, '\0', (num + 1)); + + /* copy salt to destination */ + strncpy(dest, src, num); + + return 1; +} +
zanotowane.pldoc.pisz.plpdf.pisz.plminister.pev.pl
|