--- pam_mysql_orig.c 2011-09-15 17:00:35.099602372 +0200 +++ pam_mysql.c 2011-09-15 16:55:36.347064514 +0200 @@ -176,6 +176,8 @@ #define PLEASE_ENTER_NEW_PASSWORD "(New) Password:" #define PLEASE_REENTER_NEW_PASSWORD "Retype (New) Password:" + + /* {{{ consts */ enum _pam_mysql_err_t { PAM_MYSQL_ERR_SUCCESS = 0, @@ -700,7 +702,11 @@ case 4: *pretval = "sha1"; break; - + + case 5: + *pretval = "redmine"; + break; + default: *pretval = NULL; } @@ -736,6 +742,10 @@ *(int *)val = 4; return PAM_MYSQL_ERR_SUCCESS; } + if (strcmp(newval_str, "5") == 0 || strcasecmp(newval_str, "redmine") == 0) { + *(int *)val = 5; + return PAM_MYSQL_ERR_SUCCESS; + } *(int *)val = 0; @@ -2589,7 +2599,7 @@ } if (ctx->verbose) { - syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "%s", query.p); + syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "running query: %s", query.p); } #ifdef HAVE_MYSQL_REAL_QUERY @@ -2685,7 +2695,7 @@ #ifdef HAVE_PAM_MYSQL_SHA1_DATA char buf[41]; pam_mysql_sha1_data((unsigned char*)passwd, strlen(passwd), - buf); + buf); vresult = strcmp(row[0], buf); { char *p = buf - 1; @@ -2696,6 +2706,58 @@ #endif } break; +// REDMINE SPECIFIC +// Password encryption is: +// SHA1(salt.SHA1(password)) + case 5: { + // First we need the user salt + // It is added in the password: + // | + char *p; + char *salt; + char *password; + int i = 1; + + // Splitting password on | + p = strtok (row[0],"|"); + + // Getting substrings + while (p != NULL) + { + // Token is the 2nd part of the string + if (i == 1) { + password = p; + } + else if (i == 2) { + salt = p; + syslog(LOG_AUTHPRIV | LOG_INFO, PAM_MYSQL_LOG_PREFIX "User salt was found: %s", salt); + } + p = strtok (NULL, "|,"); + i = i + 1; + } + + if (strlen(salt) == 0 || strlen(password) == 0) { + syslog(LOG_AUTHPRIV | LOG_INFO, PAM_MYSQL_LOG_PREFIX "Could not extract password or salt from view"); + break; + } + + // Hashing user input password only + char hashed[41]; + pam_mysql_sha1_data((unsigned char*)passwd, strlen(passwd), hashed); + + // Then hashing + + char buf[41]; + strcat(salt, hashed); + pam_mysql_sha1_data((unsigned char*)salt, strlen(salt), buf); + + vresult = strcmp(password, buf); + { + char *p = buf - 1; + while (*(++p)) *p = '\0'; + } + + } break; + default: { } } @@ -2881,6 +2943,11 @@ goto out; #endif break; + + + case 5: + syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "Unable to change password when using Redmine crypt type"); + break; default: encrypted_passwd = NULL;