Project

General

Profile

RE: Redmine + SVN + PAM_MYSQL = NOT Possible ยป patch.txt

pam_mysql.c patch for version pam_mysql-0.7RC1 - Axel dV, 2011-09-15 17:09

 
1
--- pam_mysql_orig.c	2011-09-15 17:00:35.099602372 +0200
2
+++ pam_mysql.c	2011-09-15 16:55:36.347064514 +0200
3
@@ -176,6 +176,8 @@
4
 #define PLEASE_ENTER_NEW_PASSWORD "(New) Password:"
5
 #define PLEASE_REENTER_NEW_PASSWORD "Retype (New) Password:"
6
 
7
+
8
+
9
 /* {{{ consts  */
10
 enum _pam_mysql_err_t {
11
 	PAM_MYSQL_ERR_SUCCESS = 0,
12
@@ -700,7 +702,11 @@
13
 		case 4:
14
 			*pretval = "sha1";
15
 			break;
16
-
17
+		
18
+		case 5: 
19
+			*pretval = "redmine";
20
+			break;
21
+			
22
 		default:
23
 			*pretval = NULL;
24
 	}
25
@@ -736,6 +742,10 @@
26
 		*(int *)val = 4;
27
 		return PAM_MYSQL_ERR_SUCCESS;
28
 	}
29
+	if (strcmp(newval_str, "5") == 0 || strcasecmp(newval_str, "redmine") == 0) {
30
+		*(int *)val = 5;
31
+		return PAM_MYSQL_ERR_SUCCESS;
32
+	}
33
 
34
 	*(int *)val = 0;
35
 
36
@@ -2589,7 +2599,7 @@
37
 	}
38
 
39
 	if (ctx->verbose) {
40
-		syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "%s", query.p);
41
+		syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "running query: %s", query.p);
42
 	}
43
 
44
 #ifdef HAVE_MYSQL_REAL_QUERY
45
@@ -2685,7 +2695,7 @@
46
 #ifdef HAVE_PAM_MYSQL_SHA1_DATA
47
 					char buf[41];
48
 					pam_mysql_sha1_data((unsigned char*)passwd, strlen(passwd),
49
-							buf);
50
+							buf);					
51
 					vresult = strcmp(row[0], buf);
52
 					{
53
 						char *p = buf - 1;
54
@@ -2696,6 +2706,58 @@
55
 #endif
56
 				} break;
57
 
58
+// REDMINE SPECIFIC
59
+// Password encryption is:
60
+// SHA1(salt.SHA1(password))
61
+				case 5: {
62
+					// First we need the user salt
63
+					// It is added in the password:
64
+					// <password>|<salt>
65
+					char *p;
66
+					char *salt;
67
+					char *password;
68
+					int i = 1;
69
+
70
+					// Splitting password on |
71
+					p = strtok (row[0],"|");
72
+
73
+					// Getting substrings
74
+					while (p != NULL)
75
+					{	
76
+						// Token is the 2nd part of the string
77
+						if (i == 1) {
78
+							password = p;
79
+						}
80
+						else if (i == 2) {
81
+							salt = p;
82
+							syslog(LOG_AUTHPRIV | LOG_INFO, PAM_MYSQL_LOG_PREFIX "User salt was found: %s", salt);
83
+						}
84
+						p = strtok (NULL, "|,");	
85
+						i = i + 1;
86
+					}
87
+					
88
+					if (strlen(salt) == 0 || strlen(password) == 0) {
89
+						syslog(LOG_AUTHPRIV | LOG_INFO, PAM_MYSQL_LOG_PREFIX "Could not extract password or salt from view");
90
+						break;
91
+					}
92
+					
93
+					// Hashing user input password only
94
+					char hashed[41];
95
+					pam_mysql_sha1_data((unsigned char*)passwd, strlen(passwd), hashed);
96
+					
97
+					// Then hashing <salt> + <hashed password>
98
+					char buf[41];
99
+					strcat(salt, hashed);
100
+					pam_mysql_sha1_data((unsigned char*)salt, strlen(salt), buf);
101
+					
102
+					vresult = strcmp(password, buf);
103
+					{
104
+						char *p = buf - 1;
105
+						while (*(++p)) *p = '\0';
106
+					}					
107
+					
108
+				} break;
109
+
110
 				default: {
111
 				}
112
 			}
113
@@ -2881,6 +2943,11 @@
114
 				goto out;
115
 #endif
116
 				break;
117
+				
118
+			
119
+			case 5:
120
+				syslog(LOG_AUTHPRIV | LOG_ERR, PAM_MYSQL_LOG_PREFIX "Unable to change password when using Redmine crypt type");
121
+			break;
122
 
123
 			default:
124
 				encrypted_passwd = NULL;
    (1-1/1)