]> git.pld-linux.org Git - packages/lighttpd.git/blame - lighttpd-apr1.patch
- updated to 1.4.13
[packages/lighttpd.git] / lighttpd-apr1.patch
CommitLineData
332e71e1
ER
1--- lighttpd-1.4.12/src/http_auth.c 2006-09-26 11:35:18.617105290 +0300
2+++ lighttpd-1.4.12/src/http_auth.c 2006-09-26 11:43:39.928372212 +0300
1bd1c0e4
ER
3@@ -39,6 +39,17 @@
4 # include "md5.h"
5 #endif
6
7+/*
8+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
9+ * MD5 crypt() function, which is licenced as follows:
10+ * ----------------------------------------------------------------------------
11+ * "THE BEER-WARE LICENSE" (Revision 42):
12+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
13+ * can do whatever you want with this stuff. If we meet some day, and you think
14+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
15+ * ----------------------------------------------------------------------------
16+ */
17+
18 handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
19
20 static const char base64_pad = '=';
332e71e1 21@@ -405,6 +416,178 @@
1bd1c0e4
ER
22 return -1;
23 }
24
25+#define APR_MD5_DIGESTSIZE 16
26+#define APR1_ID "$apr1$"
27+
28+/*
29+ * The following MD5 password encryption code was largely borrowed from
30+ * the FreeBSD 3.0 /usr/src/lib/libcrypt/crypt.c file, which is
31+ * licenced as stated at the top of this file.
32+ */
33+
34+static void to64(char *s, unsigned long v, int n)
35+{
36+ static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */
37+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
38+
39+ while (--n >= 0) {
40+ *s++ = itoa64[v&0x3f];
41+ v >>= 6;
42+ }
43+}
44+
45+static void apr_md5_encode(const char *pw, const char *salt, char *result, size_t nbytes) {
46+ /*
47+ * Minimum size is 8 bytes for salt, plus 1 for the trailing NUL,
48+ * plus 4 for the '$' separators, plus the password hash itself.
49+ * Let's leave a goodly amount of leeway.
50+ */
51+
52+ char passwd[120], *p;
53+ const char *sp, *ep;
54+ unsigned char final[APR_MD5_DIGESTSIZE];
55+ ssize_t sl, pl, i;
56+ MD5_CTX ctx, ctx1;
57+ unsigned long l;
58+
59+ /*
60+ * Refine the salt first. It's possible we were given an already-hashed
61+ * string as the salt argument, so extract the actual salt value from it
62+ * if so. Otherwise just use the string up to the first '$' as the salt.
63+ */
64+ sp = salt;
65+
66+ /*
67+ * If it starts with the magic string, then skip that.
68+ */
69+ if (!strncmp(sp, APR1_ID, strlen(APR1_ID))) {
70+ sp += strlen(APR1_ID);
71+ }
72+
73+ /*
74+ * It stops at the first '$' or 8 chars, whichever comes first
75+ */
76+ for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++) {
77+ continue;
78+ }
79+
80+ /*
81+ * Get the length of the true salt
82+ */
83+ sl = ep - sp;
84+
85+ /*
86+ * 'Time to make the doughnuts..'
87+ */
88+ MD5_Init(&ctx);
89+
90+ /*
91+ * The password first, since that is what is most unknown
92+ */
93+ MD5_Update(&ctx, pw, strlen(pw));
94+
95+ /*
96+ * Then our magic string
97+ */
98+ MD5_Update(&ctx, APR1_ID, strlen(APR1_ID));
99+
100+ /*
101+ * Then the raw salt
102+ */
103+ MD5_Update(&ctx, sp, sl);
104+
105+ /*
106+ * Then just as many characters of the MD5(pw, salt, pw)
107+ */
108+ MD5_Init(&ctx1);
109+ MD5_Update(&ctx1, pw, strlen(pw));
110+ MD5_Update(&ctx1, sp, sl);
111+ MD5_Update(&ctx1, pw, strlen(pw));
112+ MD5_Final(final, &ctx1);
113+ for (pl = strlen(pw); pl > 0; pl -= APR_MD5_DIGESTSIZE) {
114+ MD5_Update(&ctx, final,
115+ (pl > APR_MD5_DIGESTSIZE) ? APR_MD5_DIGESTSIZE : pl);
116+ }
117+
118+ /*
119+ * Don't leave anything around in vm they could use.
120+ */
121+ memset(final, 0, sizeof(final));
122+
123+ /*
124+ * Then something really weird...
125+ */
126+ for (i = strlen(pw); i != 0; i >>= 1) {
127+ if (i & 1) {
128+ MD5_Update(&ctx, final, 1);
129+ }
130+ else {
131+ MD5_Update(&ctx, pw, 1);
132+ }
133+ }
134+
135+ /*
136+ * Now make the output string. We know our limitations, so we
137+ * can use the string routines without bounds checking.
138+ */
139+ strcpy(passwd, APR1_ID);
140+ strncat(passwd, sp, sl);
141+ strcat(passwd, "$");
142+
143+ MD5_Final(final, &ctx);
144+
145+ /*
146+ * And now, just to make sure things don't run too fast..
147+ * On a 60 Mhz Pentium this takes 34 msec, so you would
148+ * need 30 seconds to build a 1000 entry dictionary...
149+ */
150+ for (i = 0; i < 1000; i++) {
151+ MD5_Init(&ctx1);
152+ if (i & 1) {
153+ MD5_Update(&ctx1, pw, strlen(pw));
154+ }
155+ else {
156+ MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE);
157+ }
158+ if (i % 3) {
159+ MD5_Update(&ctx1, sp, sl);
160+ }
161+
162+ if (i % 7) {
163+ MD5_Update(&ctx1, pw, strlen(pw));
164+ }
165+
166+ if (i & 1) {
167+ MD5_Update(&ctx1, final, APR_MD5_DIGESTSIZE);
168+ }
169+ else {
170+ MD5_Update(&ctx1, pw, strlen(pw));
171+ }
172+ MD5_Final(final,&ctx1);
173+ }
174+
175+ p = passwd + strlen(passwd);
176+
177+ l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p, l, 4); p += 4;
178+ l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p, l, 4); p += 4;
179+ l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p, l, 4); p += 4;
180+ l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p, l, 4); p += 4;
181+ l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p, l, 4); p += 4;
182+ l = final[11] ; to64(p, l, 2); p += 2;
183+ *p = '\0';
184+
185+ /*
186+ * Don't leave anything around in vm they could use.
187+ */
188+ memset(final, 0, sizeof(final));
189+
332e71e1
ER
190+ /* FIXME
191+ */
1bd1c0e4
ER
192+#define apr_cpystrn strncpy
193+ apr_cpystrn(result, passwd, nbytes - 1);
194+}
195+
196+
197 /**
198 *
199 *
332e71e1 200@@ -439,6 +622,14 @@
1bd1c0e4
ER
201 return 0;
202 }
9794508f 203 } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) {
1bd1c0e4
ER
204+ char sample[120];
205+ if (!strncmp(password->ptr, APR1_ID, strlen(APR1_ID))) {
206+ /*
207+ * The hash was created using $apr1$ custom algorithm.
208+ */
209+ apr_md5_encode(pw, password->ptr, sample, sizeof(sample));
210+ return (strcmp(sample, password->ptr) == 0) ? 0 : 1;
211+ } else {
9794508f 212 #ifdef HAVE_CRYPT
1bd1c0e4
ER
213 char salt[32];
214 char *crypted;
332e71e1 215@@ -493,6 +684,7 @@
1bd1c0e4 216 }
332e71e1
ER
217
218 #endif
219+ }
220 } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
221 if (0 == strcmp(password->ptr, pw)) {
222 return 0;
This page took 0.051816 seconds and 4 git commands to generate.