]>
Commit | Line | Data |
---|---|---|
9621ccaa | 1 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/Makefile.in openssh-4.0p1-lpk/Makefile.in |
2 | --- openssh-4.0p1/Makefile.in 2005-02-26 00:12:38.000000000 +0100 | |
3 | +++ openssh-4.0p1-lpk/Makefile.in 2005-03-12 00:38:11.000000000 +0100 | |
4 | @@ -86,7 +86,7 @@ | |
5 | auth-krb5.o \ | |
6 | auth2-gss.o gss-serv.o gss-serv-krb5.o \ | |
7 | loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ | |
8 | - audit.o audit-bsm.o | |
9 | + audit.o audit-bsm.o ldapauth.o | |
10 | ||
11 | MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out | |
12 | MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 | |
13 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/auth-rsa.c openssh-4.0p1-lpk/auth-rsa.c | |
14 | --- openssh-4.0p1/auth-rsa.c 2004-12-11 03:39:50.000000000 +0100 | |
15 | +++ openssh-4.0p1-lpk/auth-rsa.c 2005-03-12 00:34:31.000000000 +0100 | |
16 | @@ -160,10 +160,96 @@ | |
17 | u_long linenum = 0; | |
18 | struct stat st; | |
19 | Key *key; | |
20 | +#ifdef WITH_LDAP_PUBKEY | |
21 | + ldap_key_t * k; | |
22 | + int i = 0; | |
23 | +#endif | |
24 | ||
25 | /* Temporarily use the user's uid. */ | |
26 | temporarily_use_uid(pw); | |
27 | ||
28 | +#ifdef WITH_LDAP_PUBKEY | |
29 | + /* here is the job */ | |
30 | + key = key_new(KEY_RSA1); | |
31 | + | |
32 | + if (options.lpk.on) { | |
33 | + debug("[LDAP] trying LDAP first uid=%s", pw->pw_name); | |
34 | + if ( ldap_ismember(&options.lpk, pw->pw_name) > 0) { | |
35 | + if ( (k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) { | |
36 | + for (i = 0 ; i < k->num ; i++) { | |
37 | + char *cp, *options; | |
38 | + | |
39 | + for (cp = k->keys[i]; *cp == ' ' || *cp == '\t'; cp++) | |
40 | + ; | |
41 | + if (!*cp || *cp == '\n' || *cp == '#') | |
42 | + continue; | |
43 | + | |
44 | + /* | |
45 | + * Check if there are options for this key, and if so, | |
46 | + * save their starting address and skip the option part | |
47 | + * for now. If there are no options, set the starting | |
48 | + * address to NULL. | |
49 | + */ | |
50 | + if (*cp < '0' || *cp > '9') { | |
51 | + int quoted = 0; | |
52 | + options = cp; | |
53 | + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { | |
54 | + if (*cp == '\\' && cp[1] == '"') | |
55 | + cp++; /* Skip both */ | |
56 | + else if (*cp == '"') | |
57 | + quoted = !quoted; | |
58 | + } | |
59 | + } else | |
60 | + options = NULL; | |
61 | + | |
62 | + /* Parse the key from the line. */ | |
63 | + if (hostfile_read_key(&cp, &bits, key) == 0) { | |
64 | + debug("[LDAP] line %d: non ssh1 key syntax", i); | |
65 | + continue; | |
66 | + } | |
67 | + /* cp now points to the comment part. */ | |
68 | + | |
69 | + /* Check if the we have found the desired key (identified by its modulus). */ | |
70 | + if (BN_cmp(key->rsa->n, client_n) != 0) | |
71 | + continue; | |
72 | + | |
73 | + /* check the real bits */ | |
74 | + if (bits != BN_num_bits(key->rsa->n)) | |
75 | + logit("[LDAP] Warning: ldap, line %lu: keysize mismatch: " | |
76 | + "actual %d vs. announced %d.", (unsigned long)i, BN_num_bits(key->rsa->n), bits); | |
77 | + | |
78 | + /* We have found the desired key. */ | |
79 | + /* | |
80 | + * If our options do not allow this key to be used, | |
81 | + * do not send challenge. | |
82 | + */ | |
83 | + if (!auth_parse_options(pw, options, "[LDAP]", (unsigned long) i)) | |
84 | + continue; | |
85 | + | |
86 | + /* break out, this key is allowed */ | |
87 | + allowed = 1; | |
88 | + | |
89 | + /* add the return stuff etc... */ | |
90 | + /* Restore the privileged uid. */ | |
91 | + restore_uid(); | |
92 | + | |
93 | + /* return key if allowed */ | |
94 | + if (allowed && rkey != NULL) | |
95 | + *rkey = key; | |
96 | + else | |
97 | + key_free(key); | |
98 | + | |
99 | + ldap_keys_free(k); | |
100 | + return (allowed); | |
101 | + } | |
102 | + } else { | |
103 | + logit("[LDAP] no keys found for '%s'!", pw->pw_name); | |
104 | + } | |
105 | + } else { | |
106 | + logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup); | |
107 | + } | |
108 | + } | |
109 | +#endif | |
110 | /* The authorized keys. */ | |
111 | file = authorized_keys_file(pw); | |
112 | debug("trying public RSA key file %s", file); | |
113 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/auth2-pubkey.c openssh-4.0p1-lpk/auth2-pubkey.c | |
114 | --- openssh-4.0p1/auth2-pubkey.c 2004-12-11 03:39:50.000000000 +0100 | |
115 | +++ openssh-4.0p1-lpk/auth2-pubkey.c 2005-03-12 00:34:31.000000000 +0100 | |
116 | @@ -43,6 +43,10 @@ | |
117 | #include "monitor_wrap.h" | |
118 | #include "misc.h" | |
119 | ||
120 | +#ifdef WITH_LDAP_PUBKEY | |
121 | +#include "ldapauth.h" | |
122 | +#endif | |
123 | + | |
124 | /* import */ | |
125 | extern ServerOptions options; | |
126 | extern u_char *session_id2; | |
127 | @@ -176,10 +180,77 @@ | |
128 | struct stat st; | |
129 | Key *found; | |
130 | char *fp; | |
131 | +#ifdef WITH_LDAP_PUBKEY | |
132 | + ldap_key_t * k; | |
133 | + int i = 0; | |
134 | +#endif | |
135 | ||
136 | /* Temporarily use the user's uid. */ | |
137 | temporarily_use_uid(pw); | |
138 | ||
139 | +#ifdef WITH_LDAP_PUBKEY | |
140 | + found_key = 0; | |
141 | + /* allocate a new key type */ | |
142 | + found = key_new(key->type); | |
143 | + | |
144 | + /* first check if the options is enabled, then try.. */ | |
145 | + if (options.lpk.on) { | |
146 | + debug("[LDAP] trying LDAP first uid=%s",pw->pw_name); | |
147 | + if (ldap_ismember(&options.lpk, pw->pw_name) > 0) { | |
148 | + if ((k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) { | |
149 | + char *cp, *options = NULL; | |
150 | + /* Skip leading whitespace, empty and comment lines. */ | |
151 | + for (i = 0 ; i < k->num ; i++) { | |
152 | + for (cp = (char *)k->keys[i]; *cp == ' ' || *cp == '\t'; cp++) | |
153 | + ; | |
154 | + if (!*cp || *cp == '\n' || *cp == '#') | |
155 | + continue; | |
156 | + | |
157 | + if (key_read(found, &cp) != 1) { | |
158 | + /* no key? check if there are options for this key */ | |
159 | + int quoted = 0; | |
160 | + debug2("[LDAP] user_key_allowed: check options: '%s'", cp); | |
161 | + options = cp; | |
162 | + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { | |
163 | + if (*cp == '\\' && cp[1] == '"') | |
164 | + cp++; /* Skip both */ | |
165 | + else if (*cp == '"') | |
166 | + quoted = !quoted; | |
167 | + } | |
168 | + /* Skip remaining whitespace. */ | |
169 | + for (; *cp == ' ' || *cp == '\t'; cp++) | |
170 | + ; | |
171 | + if (key_read(found, &cp) != 1) { | |
172 | + debug2("[LDAP] user_key_allowed: advance: '%s'", cp); | |
173 | + /* still no key? advance to next line*/ | |
174 | + continue; | |
175 | + } | |
176 | + } | |
177 | + | |
178 | + if (key_equal(found, key) && | |
179 | + auth_parse_options(pw, options, file, linenum) == 1) { | |
180 | + found_key = 1; | |
181 | + debug("[LDAP] matching key found"); | |
182 | + fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); | |
183 | + verbose("[LDAP] Found matching %s key: %s", key_type(found), fp); | |
184 | + | |
185 | + /* restoring memory */ | |
186 | + ldap_keys_free(k); | |
187 | + xfree(fp); | |
188 | + restore_uid(); | |
189 | + key_free(found); | |
190 | + return found_key; | |
191 | + break; | |
192 | + } | |
193 | + }/* end of LDAP for() */ | |
194 | + } else { | |
195 | + logit("[LDAP] no keys found for '%s'!", pw->pw_name); | |
196 | + } | |
197 | + } else { | |
198 | + logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup); | |
199 | + } | |
200 | + } | |
201 | +#endif | |
202 | debug("trying public key file %s", file); | |
203 | ||
204 | /* Fail quietly if file does not exist */ | |
205 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/ldapauth.c openssh-4.0p1-lpk/ldapauth.c | |
206 | --- openssh-4.0p1/ldapauth.c 1970-01-01 01:00:00.000000000 +0100 | |
207 | +++ openssh-4.0p1-lpk/ldapauth.c 2005-03-15 23:29:48.000000000 +0100 | |
208 | @@ -0,0 +1,308 @@ | |
209 | +/* | |
210 | + * | |
211 | + * Copyright (c) 2005, Eric AUGE <eau@phear.org> | |
212 | + * All rights reserved. | |
213 | + * | |
214 | + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | |
215 | + * | |
216 | + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | |
217 | + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | |
218 | + * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. | |
219 | + * | |
220 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, | |
221 | + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
222 | + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | |
223 | + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
224 | + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
225 | + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
226 | + * | |
227 | + * | |
228 | + */ | |
229 | + | |
230 | +#include <stdio.h> | |
231 | +#include <stdlib.h> | |
232 | +#include <unistd.h> | |
233 | +#include <string.h> | |
234 | + | |
235 | + | |
236 | +#include "ldapauth.h" | |
237 | + | |
238 | +static char *attrs[] = { | |
239 | + PUBKEYATTR, | |
240 | + NULL | |
241 | +}; | |
242 | + | |
243 | +/* just filter building stuff */ | |
244 | +#define REQUEST_GROUP_SIZE(grp, uid) (size_t) (strlen(grp)+strlen(uid)+46) | |
245 | +#define REQUEST_GROUP(buffer,pwname,grp) \ | |
246 | + buffer = (char *) calloc(REQUEST_GROUP_SIZE(grp, pwname), sizeof(char)); \ | |
247 | + if (!buffer) { \ | |
248 | + perror("calloc()"); \ | |
249 | + return FAILURE; \ | |
250 | + } \ | |
251 | + snprintf(buffer,REQUEST_GROUP_SIZE(grp,pwname),"(&(objectclass=posixGroup)(cn=%s)(memberUid=%s))",grp,pwname) | |
252 | + | |
253 | +#define REQUEST_USER_SIZE(uid) (size_t) (strlen(uid)+64) | |
254 | +#define REQUEST_USER(buffer, pwname) \ | |
255 | + buffer = (char *) calloc(REQUEST_USER_SIZE(pwname), sizeof(char)); \ | |
256 | + if (!buffer) { \ | |
257 | + perror("calloc()"); \ | |
258 | + return NULL; \ | |
259 | + } \ | |
260 | + snprintf(buffer,REQUEST_USER_SIZE(pwname),"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s))",pwname) | |
261 | + | |
262 | +/* some portable and working tokenizer, lame though */ | |
263 | +static int tokenize(char ** o, size_t size, char * input) { | |
264 | + unsigned int i = 0, num; | |
265 | + char * charset = " \t"; | |
266 | + char * ptr = input; | |
267 | + | |
268 | + /* leading white spaces are ignored */ | |
269 | + num = strspn(ptr, charset); | |
270 | + ptr += num; | |
271 | + | |
272 | + while ((num = strcspn(ptr, charset))) { | |
273 | + if (i < size-1) { | |
274 | + o[i++] = ptr; | |
275 | + ptr += num; | |
276 | + if (*ptr) | |
277 | + *ptr++ = '\0'; | |
278 | + } | |
279 | + } | |
280 | + o[i] = NULL; | |
281 | + return SUCCESS; | |
282 | +} | |
283 | + | |
284 | +/* init && bind XXX TLS missing */ | |
285 | +int ldap_connect(ldap_opt_t * ldap) { | |
286 | + int version = LDAP_VERSION3; | |
287 | + | |
288 | + if (!ldap->servers) | |
289 | + return FAILURE; | |
290 | + | |
291 | + ldap->ld = ldap_init(ldap->servers, LDAP_PORT); | |
292 | + if (!ldap->ld) { | |
293 | + ldap_perror(ldap->ld, "ldap_init()"); | |
294 | + return FAILURE; | |
295 | + } | |
296 | + | |
297 | + if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) { | |
298 | + ldap_perror(ldap->ld, "ldap_set_option()"); | |
299 | + return FAILURE; | |
300 | + } | |
301 | + | |
302 | + /* TLS support */ | |
303 | + if (ldap_start_tls_s(ldap->ld, NULL, NULL ) != LDAP_SUCCESS) { | |
304 | + /* failed then reinit the initial connect */ | |
305 | + ldap_perror(ldap->ld, "ldap_connect: (TLS) ldap_start_tls()"); | |
306 | + | |
307 | + ldap->ld = ldap_init(ldap->servers, LDAP_PORT); | |
308 | + if (!ldap->ld) { | |
309 | + ldap_perror(ldap->ld, "ldap_init()"); | |
310 | + return FAILURE; | |
311 | + } | |
312 | + | |
313 | + if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) { | |
314 | + ldap_perror(ldap->ld, "ldap_set_option()"); | |
315 | + return FAILURE; | |
316 | + } | |
317 | + } | |
318 | + | |
319 | + | |
320 | + if ( ldap_simple_bind_s(ldap->ld, ldap->binddn, ldap->bindpw) != LDAP_SUCCESS) { | |
321 | + ldap_perror(ldap->ld, "ldap_simple_bind_s()"); | |
322 | + return FAILURE; | |
323 | + } | |
324 | + | |
325 | + return SUCCESS; | |
326 | +} | |
327 | + | |
328 | +/* must free allocated ressource */ | |
329 | +static char * ldap_build_host(char *host, int port) { | |
330 | + unsigned int size = strlen(host)+11; | |
331 | + char * h = (char *) calloc (size, sizeof(char)); | |
332 | + int rc; | |
333 | + if (!h) | |
334 | + return NULL; | |
335 | + | |
336 | + rc = snprintf(h, size, "%s:%d ", host, port); | |
337 | + if (rc == -1) | |
338 | + return NULL; | |
339 | + return h; | |
340 | +} | |
341 | + | |
342 | +/* a bit dirty but leak free */ | |
343 | +char * ldap_parse_servers(char * servers) { | |
344 | + char * s = NULL; | |
345 | + char * tmp = NULL, *urls[32]; | |
346 | + unsigned int num = 0 , i = 0 , asize = 0; | |
347 | + LDAPURLDesc *urld[32]; | |
348 | + | |
349 | + if (!servers) | |
350 | + return NULL; | |
351 | + | |
352 | + /* local copy of the arg */ | |
353 | + s = strdup(servers); | |
354 | + if (!s) | |
355 | + return NULL; | |
356 | + | |
357 | + /* first separate into URL tokens */ | |
358 | + if ( tokenize(urls, sizeof(urls)/sizeof(*urls), s) < 0) | |
359 | + return NULL; | |
360 | + | |
361 | + i = 0; | |
362 | + while (urls[i]) { | |
363 | + if ( ldap_is_ldap_url(urls[i]) ) { | |
364 | + if (ldap_url_parse(urls[i], &urld[i]) != 0) | |
365 | + return NULL; | |
366 | + } | |
367 | + i++; | |
368 | + } | |
369 | + | |
370 | + /* now free(s) */ | |
371 | + free (s); | |
372 | + | |
373 | + /* how much memory do we need */ | |
374 | + num = i; | |
375 | + for (i = 0 ; i < num ; i++) | |
376 | + asize += strlen(urld[i]->lud_host)+11; | |
377 | + | |
378 | + /* alloc */ | |
379 | + s = (char *) calloc( asize+1 , sizeof(char)); | |
380 | + if (!s) { | |
381 | + for (i = 0 ; i < num ; i++) | |
382 | + ldap_free_urldesc(urld[i]); | |
383 | + return NULL; | |
384 | + } | |
385 | + | |
386 | + /* then build the final host string */ | |
387 | + for (i = 0 ; i < num ; i++) { | |
388 | + /* built host part */ | |
389 | + tmp = ldap_build_host(urld[i]->lud_host, urld[i]->lud_port); | |
390 | + strncat(s, tmp, strlen(tmp)); | |
391 | + ldap_free_urldesc(urld[i]); | |
392 | + free(tmp); | |
393 | + } | |
394 | + | |
395 | + return s; | |
396 | +} | |
397 | + | |
398 | +void ldap_options_print(ldap_opt_t * ldap) { | |
399 | + printf("ldap options:\n"); | |
400 | + printf("servers: %s\n", ldap->servers); | |
401 | + printf("user basedn: %s\n", ldap->u_basedn); | |
402 | + printf("group basedn: %s\n", ldap->g_basedn); | |
403 | + printf("binddn: %s\n", ldap->binddn); | |
404 | + printf("bindpw: %s\n", ldap->bindpw); | |
405 | + printf("group: %s\n", ldap->sgroup); | |
406 | +} | |
407 | + | |
408 | +void ldap_options_free(ldap_opt_t * l) { | |
409 | + if (!l) | |
410 | + return; | |
411 | + if (l->servers) | |
412 | + free(l->servers); | |
413 | + if (l->u_basedn) | |
414 | + free(l->u_basedn); | |
415 | + if (l->g_basedn) | |
416 | + free(l->g_basedn); | |
417 | + if (l->binddn) | |
418 | + free(l->binddn); | |
419 | + if (l->bindpw) | |
420 | + free(l->bindpw); | |
421 | + if (l->sgroup) | |
422 | + free(l->sgroup); | |
423 | + free(l); | |
424 | +} | |
425 | + | |
426 | +/* free keys */ | |
427 | +void ldap_keys_free(ldap_key_t * k) { | |
428 | + ldap_value_free(k->keys); | |
429 | + free(k); | |
430 | + return; | |
431 | +} | |
432 | + | |
433 | +ldap_key_t * ldap_getuserkey(ldap_opt_t *l, char * user) { | |
434 | + ldap_key_t * k = (ldap_key_t *) calloc (1, sizeof(ldap_key_t)); | |
435 | + LDAPMessage *res, *e; | |
436 | + char * filter; | |
437 | + int i; | |
438 | + | |
439 | + if (!k) | |
440 | + return NULL; | |
441 | + | |
442 | + /* build filter for LDAP request */ | |
443 | + REQUEST_USER(filter, user); | |
444 | + | |
445 | + if ( ldap_search_s( l->ld, | |
446 | + l->u_basedn, | |
447 | + LDAP_SCOPE_SUBTREE, | |
448 | + filter, | |
449 | + attrs, 0, &res ) != LDAP_SUCCESS) { | |
450 | + ldap_perror(l->ld, "ldap_search_s()"); | |
451 | + | |
452 | + free(filter); | |
453 | + free(k); | |
454 | + | |
455 | + return NULL; | |
456 | + } | |
457 | + | |
458 | + /* free */ | |
459 | + free(filter); | |
460 | + | |
461 | + /* check if any results */ | |
462 | + i = ldap_count_entries(l->ld,res); | |
463 | + if (i <= 0) { | |
464 | + ldap_msgfree(res); | |
465 | + free(k); | |
466 | + return NULL; | |
467 | + } | |
468 | + | |
469 | + if (i > 1) | |
470 | + printf("[LDAP] duplicate entries, using the FIRST entry returned\n"); | |
471 | + | |
472 | + e = ldap_first_entry(l->ld, res); | |
473 | + k->keys = ldap_get_values(l->ld, e, PUBKEYATTR); | |
474 | + k->num = ldap_count_values(k->keys); | |
475 | + | |
476 | + ldap_msgfree(res); | |
477 | + return k; | |
478 | +} | |
479 | + | |
480 | + | |
481 | +/* -1 if trouble | |
482 | + 0 if user is NOT member of current server group | |
483 | + 1 if user IS MEMBER of current server group | |
484 | + */ | |
485 | +int ldap_ismember(ldap_opt_t * l, char * user) { | |
486 | + LDAPMessage *res; | |
487 | + char * filter; | |
488 | + | |
489 | + if ((!l->sgroup) || !(l->g_basedn)) | |
490 | + return 1; | |
491 | + | |
492 | + /* build filter for LDAP request */ | |
493 | + REQUEST_GROUP(filter, user, l->sgroup); | |
494 | + | |
495 | + if (ldap_search_s ( l->ld, | |
496 | + l->g_basedn, | |
497 | + LDAP_SCOPE_SUBTREE, | |
498 | + filter, | |
499 | + NULL, 0, &res) != LDAP_SUCCESS) { | |
500 | + ldap_perror(l->ld, "ldap_search_s()"); | |
501 | + | |
502 | + free(filter); | |
503 | + return FAILURE; | |
504 | + } | |
505 | + | |
506 | + free(filter); | |
507 | + | |
508 | + /* check if any results */ | |
509 | + if (ldap_count_entries(l->ld, res) > 0) { | |
510 | + ldap_msgfree(res); | |
511 | + return 1; | |
512 | + } | |
513 | + | |
514 | + ldap_msgfree(res); | |
515 | + return 0; | |
516 | +} | |
517 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/ldapauth.h openssh-4.0p1-lpk/ldapauth.h | |
518 | --- openssh-4.0p1/ldapauth.h 1970-01-01 01:00:00.000000000 +0100 | |
519 | +++ openssh-4.0p1-lpk/ldapauth.h 2005-03-12 00:34:31.000000000 +0100 | |
520 | @@ -0,0 +1,79 @@ | |
521 | +/* | |
522 | + * | |
523 | + * Copyright (c) 2005, Eric AUGE <eau@phear.org> | |
524 | + * All rights reserved. | |
525 | + * | |
526 | + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | |
527 | + * | |
528 | + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | |
529 | + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | |
530 | + * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. | |
531 | + * | |
532 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, | |
533 | + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
534 | + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | |
535 | + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
536 | + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
537 | + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
538 | + * | |
539 | + * | |
540 | + */ | |
541 | + | |
542 | +#ifndef LDAPAUTH_H | |
543 | +#define LDAPAUTH_H | |
544 | + | |
545 | +#include <string.h> | |
546 | +#include <ldap.h> | |
547 | +#include <lber.h> | |
548 | + | |
549 | +/* tokens in use for config */ | |
550 | +#define _DEFAULT_LPK_TOKEN "UseLPK" | |
551 | +#define _DEFAULT_SRV_TOKEN "LpkServers" | |
552 | +#define _DEFAULT_USR_TOKEN "LpkUserDN" | |
553 | +#define _DEFAULT_GRP_TOKEN "LpkGroupDN" | |
554 | +#define _DEFAULT_BDN_TOKEN "LpkBindDN" | |
555 | +#define _DEFAULT_BPW_TOKEN "LpkBindPw" | |
556 | +#define _DEFAULT_MYG_TOKEN "LpkServerGroup" | |
557 | + | |
558 | +/* default options */ | |
559 | +#define _DEFAULT_LPK_ON 1 | |
560 | +#define _DEFAULT_LPK_SERVERS NULL | |
561 | +#define _DEFAULT_LPK_UDN NULL | |
562 | +#define _DEFAULT_LPK_GDN NULL | |
563 | +#define _DEFAULT_LPK_BINDDN NULL | |
564 | +#define _DEFAULT_LPK_BINDPW NULL | |
565 | +#define _DEFAULT_LPK_SGROUP NULL | |
566 | + | |
567 | +/* defines */ | |
568 | +#define FAILURE -1 | |
569 | +#define SUCCESS 0 | |
570 | +#define PUBKEYATTR "sshPublicKey" | |
571 | + | |
572 | +/* structures */ | |
573 | +typedef struct ldap_options { | |
574 | + int on; /* Use it or NOT */ | |
575 | + LDAP * ld; /* LDAP file desc */ | |
576 | + char * servers; /* parsed servers for ldaplib failover handling */ | |
577 | + char * u_basedn; /* user basedn */ | |
578 | + char * g_basedn; /* group basedn */ | |
579 | + char * binddn; /* binddn */ | |
580 | + char * bindpw; /* bind password */ | |
581 | + char * sgroup; /* server group */ | |
582 | +} ldap_opt_t; | |
583 | + | |
584 | +typedef struct ldap_keys { | |
585 | + char ** keys; /* the public keys retrieved */ | |
586 | + unsigned int num; /* number of keys */ | |
587 | +} ldap_key_t; | |
588 | + | |
589 | + | |
590 | +/* function headers */ | |
591 | +int ldap_connect(ldap_opt_t *); | |
592 | +char * ldap_parse_servers(char *); | |
593 | +void ldap_options_print(ldap_opt_t *); | |
594 | +void ldap_options_free(ldap_opt_t *); | |
595 | +void ldap_keys_free(ldap_key_t *); | |
596 | +ldap_key_t * ldap_getuserkey(ldap_opt_t *, char *); | |
597 | +int ldap_ismember(ldap_opt_t *, char *); | |
598 | + | |
599 | +#endif | |
600 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/servconf.c openssh-4.0p1-lpk/servconf.c | |
601 | --- openssh-4.0p1/servconf.c 2005-03-01 11:24:33.000000000 +0100 | |
602 | +++ openssh-4.0p1-lpk/servconf.c 2005-03-12 00:34:31.000000000 +0100 | |
603 | @@ -23,6 +23,10 @@ | |
604 | #include "kex.h" | |
605 | #include "mac.h" | |
606 | ||
607 | +#ifdef WITH_LDAP_PUBKEY | |
608 | +#include "ldapauth.h" | |
609 | +#endif | |
610 | + | |
611 | static void add_listen_addr(ServerOptions *, char *, u_short); | |
612 | static void add_one_listen_addr(ServerOptions *, char *, u_short); | |
613 | ||
614 | @@ -101,7 +105,17 @@ | |
615 | options->authorized_keys_file = NULL; | |
616 | options->authorized_keys_file2 = NULL; | |
617 | options->num_accept_env = 0; | |
618 | - | |
619 | +#ifdef WITH_LDAP_PUBKEY | |
620 | + /* XXX dirty */ | |
621 | + options->lpk.ld = NULL; | |
622 | + options->lpk.on = -1; | |
623 | + options->lpk.servers = NULL; | |
624 | + options->lpk.u_basedn = NULL; | |
625 | + options->lpk.g_basedn = NULL; | |
626 | + options->lpk.binddn = NULL; | |
627 | + options->lpk.bindpw = NULL; | |
628 | + options->lpk.sgroup = NULL; | |
629 | +#endif | |
630 | /* Needs to be accessable in many places */ | |
631 | use_privsep = -1; | |
632 | } | |
633 | @@ -229,7 +243,22 @@ | |
634 | } | |
635 | if (options->authorized_keys_file == NULL) | |
636 | options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; | |
637 | - | |
638 | +#ifdef WITH_LDAP_PUBKEY | |
639 | + if (options->lpk.on == -1) | |
640 | + options->lpk.on = _DEFAULT_LPK_ON; | |
641 | + if (options->lpk.servers == NULL) | |
642 | + options->lpk.servers = _DEFAULT_LPK_SERVERS; | |
643 | + if (options->lpk.u_basedn == NULL) | |
644 | + options->lpk.u_basedn = _DEFAULT_LPK_UDN; | |
645 | + if (options->lpk.g_basedn == NULL) | |
646 | + options->lpk.g_basedn = _DEFAULT_LPK_GDN; | |
647 | + if (options->lpk.binddn == NULL) | |
648 | + options->lpk.binddn = _DEFAULT_LPK_BINDDN; | |
649 | + if (options->lpk.bindpw == NULL) | |
650 | + options->lpk.bindpw = _DEFAULT_LPK_BINDPW; | |
651 | + if (options->lpk.sgroup == NULL) | |
652 | + options->lpk.sgroup = _DEFAULT_LPK_SGROUP; | |
653 | +#endif | |
654 | /* Turn privilege separation on by default */ | |
655 | if (use_privsep == -1) | |
656 | use_privsep = 1; | |
657 | @@ -273,6 +302,9 @@ | |
658 | sGssAuthentication, sGssCleanupCreds, sAcceptEnv, | |
659 | sUsePrivilegeSeparation, | |
660 | sDeprecated, sUnsupported | |
661 | +#ifdef WITH_LDAP_PUBKEY | |
662 | + ,sLdapPublickey, sLdapServers, sLdapUserDN, sLdapGroupDN, sBindDN, sBindPw, sMyGroup | |
663 | +#endif | |
664 | } ServerOpCodes; | |
665 | ||
666 | /* Textual representation of the tokens. */ | |
667 | @@ -371,6 +403,15 @@ | |
668 | { "clientalivecountmax", sClientAliveCountMax }, | |
669 | { "authorizedkeysfile", sAuthorizedKeysFile }, | |
670 | { "authorizedkeysfile2", sAuthorizedKeysFile2 }, | |
671 | +#ifdef WITH_LDAP_PUBKEY | |
672 | + { _DEFAULT_LPK_TOKEN, sLdapPublickey }, | |
673 | + { _DEFAULT_SRV_TOKEN, sLdapServers }, | |
674 | + { _DEFAULT_USR_TOKEN, sLdapUserDN }, | |
675 | + { _DEFAULT_GRP_TOKEN, sLdapGroupDN }, | |
676 | + { _DEFAULT_BDN_TOKEN, sBindDN }, | |
677 | + { _DEFAULT_BPW_TOKEN, sBindPw }, | |
678 | + { _DEFAULT_MYG_TOKEN, sMyGroup }, | |
679 | +#endif | |
680 | { "useprivilegeseparation", sUsePrivilegeSeparation}, | |
681 | { "acceptenv", sAcceptEnv }, | |
682 | { NULL, sBadOption } | |
683 | @@ -949,6 +990,77 @@ | |
684 | while (arg) | |
685 | arg = strdelim(&cp); | |
686 | break; | |
687 | +#ifdef WITH_LDAP_PUBKEY | |
688 | + case sLdapPublickey: | |
689 | + intptr = &options->lpk.on; | |
690 | + goto parse_flag; | |
691 | + case sLdapServers: | |
692 | + /* arg = strdelim(&cp); */ | |
693 | + p = line; | |
694 | + while(*p++); | |
695 | + arg = p; | |
696 | + if (!arg || *arg == '\0') | |
697 | + fatal("%s line %d: missing ldap server",filename,linenum); | |
698 | + arg[strlen(arg)] = '\0'; | |
699 | + if ((options->lpk.servers = ldap_parse_servers(arg)) == NULL) | |
700 | + fatal("%s line %d: error in ldap servers", filename, linenum); | |
701 | + memset(arg,0,strlen(arg)); | |
702 | + break; | |
703 | + case sLdapUserDN: | |
704 | + /* arg = strdelim(&cp); */ | |
705 | + p = line; | |
706 | + while(*p++); | |
707 | + arg = p; | |
708 | + if (!arg || *arg == '\0') | |
709 | + fatal("%s line %d: missing ldap server",filename,linenum); | |
710 | + arg[strlen(arg)] = '\0'; | |
711 | + options->lpk.u_basedn = xstrdup(arg); | |
712 | + memset(arg,0,strlen(arg)); | |
713 | + break; | |
714 | + case sLdapGroupDN: | |
715 | + /* arg = strdelim(&cp); */ | |
716 | + p = line; | |
717 | + while(*p++); | |
718 | + arg = p; | |
719 | + if (!arg || *arg == '\0') | |
720 | + fatal("%s line %d: missing ldap server",filename,linenum); | |
721 | + arg[strlen(arg)] = '\0'; | |
722 | + options->lpk.g_basedn = xstrdup(arg); | |
723 | + memset(arg,0,strlen(arg)); | |
724 | + break; | |
725 | + case sBindDN: | |
726 | + /* arg = strdelim(&cp); */ | |
727 | + p = line; | |
728 | + while(*p++); | |
729 | + arg = p; | |
730 | + if (!arg || *arg == '\0') | |
731 | + fatal("%s line %d: missing binddn",filename,linenum); | |
732 | + arg[strlen(arg)] = '\0'; | |
733 | + options->lpk.binddn = xstrdup(arg); | |
734 | + memset(arg,0,strlen(arg)); | |
735 | + break; | |
736 | + case sBindPw: | |
737 | + /* arg = strdelim(&cp); */ | |
738 | + p = line; | |
739 | + while(*p++); | |
740 | + arg = p; | |
741 | + if (!arg || *arg == '\0') | |
742 | + fatal("%s line %d: missing bindpw",filename,linenum); | |
743 | + arg[strlen(arg)] = '\0'; | |
744 | + options->lpk.bindpw = xstrdup(arg); | |
745 | + memset(arg,0,strlen(arg)); | |
746 | + break; | |
747 | + case sMyGroup: | |
748 | + p = line; | |
749 | + while (*p++); | |
750 | + arg = p; | |
751 | + if (!arg || *arg == '\0') | |
752 | + fatal("%s line %d: missing groupname",filename, linenum); | |
753 | + arg[strlen(arg)] = '\0'; | |
754 | + options->lpk.sgroup = xstrdup(arg); | |
755 | + memset(arg,0,strlen(arg)); | |
756 | + break; | |
757 | +#endif | |
758 | ||
759 | default: | |
760 | fatal("%s line %d: Missing handler for opcode %s (%d)", | |
761 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/servconf.h openssh-4.0p1-lpk/servconf.h | |
762 | --- openssh-4.0p1/servconf.h 2005-01-20 00:57:56.000000000 +0100 | |
763 | +++ openssh-4.0p1-lpk/servconf.h 2005-03-12 00:34:31.000000000 +0100 | |
764 | @@ -18,6 +18,10 @@ | |
765 | ||
766 | #include "buffer.h" | |
767 | ||
768 | +#ifdef WITH_LDAP_PUBKEY | |
769 | +#include "ldapauth.h" | |
770 | +#endif | |
771 | + | |
772 | #define MAX_PORTS 256 /* Max # ports. */ | |
773 | ||
774 | #define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ | |
775 | @@ -134,6 +138,9 @@ | |
776 | char *authorized_keys_file; /* File containing public keys */ | |
777 | char *authorized_keys_file2; | |
778 | int use_pam; /* Enable auth via PAM */ | |
779 | +#ifdef WITH_LDAP_PUBKEY | |
780 | + ldap_opt_t lpk; | |
781 | +#endif | |
782 | } ServerOptions; | |
783 | ||
784 | void initialize_server_options(ServerOptions *); | |
785 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/sshd.c openssh-4.0p1-lpk/sshd.c | |
786 | --- openssh-4.0p1/sshd.c 2005-03-06 12:38:52.000000000 +0100 | |
787 | +++ openssh-4.0p1-lpk/sshd.c 2005-03-12 00:37:33.000000000 +0100 | |
788 | @@ -93,6 +93,10 @@ | |
789 | int deny_severity = LOG_WARNING; | |
790 | #endif /* LIBWRAP */ | |
791 | ||
792 | +#ifdef WITH_LDAP_PUBKEY | |
793 | +#include "ldapauth.h" | |
794 | +#endif | |
795 | + | |
796 | #ifndef O_NOCTTY | |
797 | #define O_NOCTTY 0 | |
798 | #endif | |
799 | @@ -1076,6 +1080,13 @@ | |
800 | exit(1); | |
801 | } | |
802 | ||
803 | +#ifdef WITH_LDAP_PUBKEY | |
804 | + ldap_options_print(&options.lpk); | |
805 | + /* XXX initialize/check ldap connection and set *LD */ | |
806 | + if (options.lpk.on && ldap_connect(&options.lpk) < 0) { | |
807 | + error("[LDAP] Could not initialize ldap connections"); | |
808 | + } | |
809 | +#endif | |
810 | debug("sshd version %.100s", SSH_RELEASE); | |
811 | ||
812 | /* load private host keys */ | |
813 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/sshd_config openssh-4.0p1-lpk/sshd_config | |
814 | --- openssh-4.0p1/sshd_config 2005-01-20 00:57:56.000000000 +0100 | |
815 | +++ openssh-4.0p1-lpk/sshd_config 2005-03-12 00:34:31.000000000 +0100 | |
816 | @@ -38,8 +38,8 @@ | |
817 | #StrictModes yes | |
818 | #MaxAuthTries 6 | |
819 | ||
820 | -#RSAAuthentication yes | |
821 | -#PubkeyAuthentication yes | |
822 | +RSAAuthentication yes | |
823 | +PubkeyAuthentication yes | |
824 | #AuthorizedKeysFile .ssh/authorized_keys | |
825 | ||
826 | # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts | |
827 | @@ -53,11 +53,11 @@ | |
828 | #IgnoreRhosts yes | |
829 | ||
830 | # To disable tunneled clear text passwords, change to no here! | |
831 | -#PasswordAuthentication yes | |
832 | -#PermitEmptyPasswords no | |
833 | +PasswordAuthentication yes | |
834 | +PermitEmptyPasswords no | |
835 | ||
836 | # Change to no to disable s/key passwords | |
837 | -#ChallengeResponseAuthentication yes | |
838 | +ChallengeResponseAuthentication no | |
839 | ||
840 | # Kerberos options | |
841 | #KerberosAuthentication no | |
842 | @@ -88,9 +88,9 @@ | |
843 | #PrintLastLog yes | |
844 | #TCPKeepAlive yes | |
845 | #UseLogin no | |
846 | -#UsePrivilegeSeparation yes | |
847 | +UsePrivilegeSeparation no | |
848 | #PermitUserEnvironment no | |
849 | -#Compression yes | |
850 | +Compression no | |
851 | #ClientAliveInterval 0 | |
852 | #ClientAliveCountMax 3 | |
853 | #UseDNS yes | |
854 | @@ -99,6 +99,16 @@ | |
855 | ||
856 | # no default banner path | |
857 | #Banner /some/path | |
858 | + | |
859 | +# here is the new patched ldap related tokens | |
860 | +# entries in your LDAP must have posixAccount & ldapPublicKey objectclass | |
861 | +UseLPK yes | |
862 | +LpkServers ldap://127.0.0.4 ldap://127.0.0.3 ldap://127.0.0.1/ | |
863 | +LpkUserDN ou=users,dc=phear,dc=org | |
864 | +LpkGroupDN ou=groups,dc=phear,dc=org | |
865 | +#LpkBindDN cn=Manager,dc=phear,dc=org | |
866 | +#LpkBindPw secret | |
867 | +LpkServerGroup mail | |
868 | ||
869 | # override default of no subsystems | |
870 | Subsystem sftp /usr/libexec/sftp-server | |
871 | diff -Nru -x 'config.*' -x Makefile -x 'buildpkg.*' -x opensshd.init -x 'ssh_prng_*' openssh-4.0p1/sshd_config.5 openssh-4.0p1-lpk/sshd_config.5 | |
872 | --- openssh-4.0p1/sshd_config.5 2005-03-01 11:24:34.000000000 +0100 | |
873 | +++ openssh-4.0p1-lpk/sshd_config.5 2005-03-12 00:34:31.000000000 +0100 | |
874 | @@ -760,6 +760,32 @@ | |
875 | program. | |
876 | The default is | |
877 | .Pa /usr/X11R6/bin/xauth . | |
878 | +.It Cm UseLPK | |
879 | +Enable LDAP public key resolution. The argument must be | |
880 | +.Dq yes | |
881 | +or | |
882 | +.Dq no . | |
883 | +.It Cm LpkServers | |
884 | +Specifies LDAP one or more [:space:] separated server's url the following form may be used: | |
885 | +.Pp | |
886 | +.Bl -item -offset indent -compact | |
887 | +.It | |
888 | +.Cm LpkServers | |
889 | +.Sm off | |
890 | +.Ar LpkServers ldaps://127.0.0.1 ldap://127.0.0.2 ldap://127.0.0.3 | |
891 | +.Sm on | |
892 | +.It Cm LpkUserDN/LpkGroupDN | |
893 | +.Sm off | |
894 | +.Ar LpkUserDN ou=groups,dc=phear,dc=org | |
895 | +.Sm on | |
896 | +.El | |
897 | +.Pp | |
898 | +.It Cm LpkBindDN | |
899 | +Specifies a LDAP bind DN to use when doing ldap lookups. | |
900 | +.It Cm LpkBindPw | |
901 | +Specifies a LDAP bind Password associated to the previous token. | |
902 | +.It Cm LpkServerGroup | |
903 | +Specifies the group is the host is part of. | |
904 | .El | |
905 | .Ss Time Formats | |
906 | .Nm sshd |