]> git.pld-linux.org Git - packages/lighttpd.git/blob - lighttpd-apr1.patch
- updated to 1.4.13
[packages/lighttpd.git] / lighttpd-apr1.patch
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
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 = '=';
21 @@ -405,6 +416,178 @@
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 +
190 +       /* FIXME
191 +        */
192 +#define apr_cpystrn strncpy
193 +    apr_cpystrn(result, passwd, nbytes - 1);
194 +}
195 +
196 +
197  /**
198   *
199   *
200 @@ -439,6 +622,14 @@
201                         return 0;
202                 }
203         } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) { 
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 {
212  #ifdef HAVE_CRYPT      
213                 char salt[32];
214                 char *crypted;
215 @@ -493,6 +684,7 @@
216                 }
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.083018 seconds and 3 git commands to generate.