summaryrefslogtreecommitdiffstats
path: root/main/cyrus-sasl/cyrus-sasl-2.1.19-checkpw.c.patch
blob: f7bf44b79416936b5b29a55a633617fb931f5499 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
diff -ur ../cyrus-sasl-2.1.19.orig/lib/Makefile.in ./lib/Makefile.in
--- ../cyrus-sasl-2.1.19.orig/lib/Makefile.in	2004-07-02 21:40:15.000000000 +0200
+++ ./lib/Makefile.in	2004-09-07 13:21:22.746680576 +0200
@@ -120,7 +120,7 @@
 JAVA_TRUE = @JAVA_TRUE@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = -lcrypt @LIBS@
 LIBTOOL = @LIBTOOL@
 LIB_CRYPT = @LIB_CRYPT@
 LIB_DES = @LIB_DES@
diff -ur ../cyrus-sasl-2.1.19.orig/lib/checkpw.c ./lib/checkpw.c
--- ../cyrus-sasl-2.1.19.orig/lib/checkpw.c	2004-03-17 14:58:13.000000000 +0100
+++ ./lib/checkpw.c	2004-09-07 13:21:12.645916147 +0200
@@ -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;
+}
+