Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_xauth.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* $NetBSD: isakmp_xauth.c,v 1.22.2.1 2013/02/05 06:23:42 tteras Exp $ */
1.1 misho 2:
3: /* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
4:
5: /*
6: * Copyright (C) 2004-2005 Emmanuel Dreyfus
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. Neither the name of the project nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #include "config.h"
35:
36: #include <sys/types.h>
37: #include <sys/param.h>
38: #include <sys/socket.h>
39: #include <sys/queue.h>
40:
41: #include <netinet/in.h>
42:
43: #include <assert.h>
44: #include <stdlib.h>
45: #include <stdio.h>
46: #include <string.h>
47: #include <errno.h>
48: #include <pwd.h>
49: #include <grp.h>
50: #if TIME_WITH_SYS_TIME
51: # include <sys/time.h>
52: # include <time.h>
53: #else
54: # if HAVE_SYS_TIME_H
55: # include <sys/time.h>
56: # else
57: # include <time.h>
58: # endif
59: #endif
60: #include <netdb.h>
61: #ifdef HAVE_UNISTD_H
62: #include <unistd.h>
63: #endif
64: #include <ctype.h>
65: #include <resolv.h>
66:
67: #ifdef HAVE_SHADOW_H
68: #include <shadow.h>
69: #endif
70:
71: #include "var.h"
72: #include "misc.h"
73: #include "vmbuf.h"
74: #include "plog.h"
75: #include "sockmisc.h"
76: #include "schedule.h"
77: #include "debug.h"
78:
79: #include "crypto_openssl.h"
80: #include "isakmp_var.h"
81: #include "isakmp.h"
82: #include "admin.h"
83: #include "privsep.h"
84: #include "evt.h"
85: #include "handler.h"
86: #include "throttle.h"
87: #include "remoteconf.h"
88: #include "isakmp_inf.h"
89: #include "isakmp_xauth.h"
90: #include "isakmp_unity.h"
91: #include "isakmp_cfg.h"
92: #include "strnames.h"
93: #include "ipsec_doi.h"
94: #include "remoteconf.h"
95: #include "localconf.h"
96:
97: #ifdef HAVE_LIBRADIUS
98: #include <radlib.h>
99: struct rad_handle *radius_auth_state = NULL;
100: struct rad_handle *radius_acct_state = NULL;
101: struct xauth_rad_config xauth_rad_config;
102: #endif
103:
104: #ifdef HAVE_LIBPAM
105: #include <security/pam_appl.h>
106:
107: static char *PAM_usr = NULL;
108: static char *PAM_pwd = NULL;
109: static int PAM_conv(int, const struct pam_message **,
110: struct pam_response **, void *);
111: static struct pam_conv PAM_chat = { &PAM_conv, NULL };
112: #endif
113:
114: #ifdef HAVE_LIBLDAP
115: #include "ldap.h"
116: #include <arpa/inet.h>
117: struct xauth_ldap_config xauth_ldap_config;
118: #endif
119:
120: void
121: xauth_sendreq(iph1)
122: struct ph1handle *iph1;
123: {
124: vchar_t *buffer;
125: struct isakmp_pl_attr *attr;
126: struct isakmp_data *typeattr;
127: struct isakmp_data *usrattr;
128: struct isakmp_data *pwdattr;
129: struct xauth_state *xst = &iph1->mode_cfg->xauth;
130: size_t tlen;
131:
132: /* Status checks */
133: if (iph1->status < PHASE1ST_ESTABLISHED) {
134: plog(LLV_ERROR, LOCATION, NULL,
135: "Xauth request while phase 1 is not completed\n");
136: return;
137: }
138:
139: if (xst->status != XAUTHST_NOTYET) {
140: plog(LLV_ERROR, LOCATION, NULL,
141: "Xauth request whith Xauth state %d\n", xst->status);
142: return;
143: }
144:
145: plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n");
146:
147: tlen = sizeof(*attr) +
148: + sizeof(*typeattr) +
149: + sizeof(*usrattr) +
150: + sizeof(*pwdattr);
151:
152: if ((buffer = vmalloc(tlen)) == NULL) {
153: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
154: return;
155: }
156:
157: attr = (struct isakmp_pl_attr *)buffer->v;
158: memset(attr, 0, tlen);
159:
160: attr->h.len = htons(tlen);
161: attr->type = ISAKMP_CFG_REQUEST;
162: attr->id = htons(eay_random());
163:
164: typeattr = (struct isakmp_data *)(attr + 1);
165: typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV);
166: typeattr->lorv = htons(XAUTH_TYPE_GENERIC);
167:
168: usrattr = (struct isakmp_data *)(typeattr + 1);
169: usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV);
170: usrattr->lorv = htons(0);
171:
172: pwdattr = (struct isakmp_data *)(usrattr + 1);
173: pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV);
174: pwdattr->lorv = htons(0);
175:
176: isakmp_cfg_send(iph1, buffer,
177: ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
178:
179: vfree(buffer);
180:
181: xst->status = XAUTHST_REQSENT;
182:
183: return;
184: }
185:
186: int
187: xauth_attr_reply(iph1, attr, id)
188: struct ph1handle *iph1;
189: struct isakmp_data *attr;
190: int id;
191: {
192: char **outlet = NULL;
193: size_t alen = 0;
194: int type;
195: struct xauth_state *xst = &iph1->mode_cfg->xauth;
196:
197: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
198: plog(LLV_ERROR, LOCATION, NULL,
199: "Xauth reply but peer did not declare "
200: "itself as Xauth capable\n");
201: return -1;
202: }
203:
204: if (xst->status != XAUTHST_REQSENT) {
205: plog(LLV_ERROR, LOCATION, NULL,
206: "Xauth reply while Xauth state is %d\n", xst->status);
207: return -1;
208: }
209:
210: type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
211: switch (type) {
212: case XAUTH_TYPE:
213: switch (ntohs(attr->lorv)) {
214: case XAUTH_TYPE_GENERIC:
215: xst->authtype = XAUTH_TYPE_GENERIC;
216: break;
217: default:
218: plog(LLV_WARNING, LOCATION, NULL,
219: "Unexpected authentication type %d\n",
220: ntohs(type));
221: return -1;
222: }
223: break;
224:
225: case XAUTH_USER_NAME:
226: outlet = &xst->authdata.generic.usr;
227: break;
228:
229: case XAUTH_USER_PASSWORD:
230: outlet = &xst->authdata.generic.pwd;
231: break;
232:
233: default:
234: plog(LLV_WARNING, LOCATION, NULL,
235: "ignored Xauth attribute %d\n", type);
236: break;
237: }
238:
239: if (outlet != NULL) {
240: alen = ntohs(attr->lorv);
241:
242: if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
243: plog(LLV_ERROR, LOCATION, NULL,
244: "Cannot allocate memory for Xauth Data\n");
245: return -1;
246: }
247:
248: memcpy(*outlet, attr + 1, alen);
249: (*outlet)[alen] = '\0';
250: outlet = NULL;
251: }
252:
253:
254: if ((xst->authdata.generic.usr != NULL) &&
255: (xst->authdata.generic.pwd != NULL)) {
256: int port;
257: int res;
258: char *usr = xst->authdata.generic.usr;
259: char *pwd = xst->authdata.generic.pwd;
260: time_t throttle_delay = 0;
261:
262: #if 0 /* Real debug, don't do that at home */
263: plog(LLV_DEBUG, LOCATION, NULL,
264: "Got username \"%s\", password \"%s\"\n", usr, pwd);
265: #endif
266: strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
267: iph1->mode_cfg->login[LOGINLEN] = '\0';
268:
269: res = -1;
270: if ((port = isakmp_cfg_getport(iph1)) == -1) {
271: plog(LLV_ERROR, LOCATION, NULL,
272: "Port pool depleted\n");
273: goto skip_auth;
274: }
275:
276: switch (isakmp_cfg_config.authsource) {
277: case ISAKMP_CFG_AUTH_SYSTEM:
278: res = privsep_xauth_login_system(usr, pwd);
279: break;
280: #ifdef HAVE_LIBRADIUS
281: case ISAKMP_CFG_AUTH_RADIUS:
282: res = xauth_login_radius(iph1, usr, pwd);
283: break;
284: #endif
285: #ifdef HAVE_LIBPAM
286: case ISAKMP_CFG_AUTH_PAM:
287: res = privsep_xauth_login_pam(iph1->mode_cfg->port,
288: iph1->remote, usr, pwd);
289: break;
290: #endif
291: #ifdef HAVE_LIBLDAP
292: case ISAKMP_CFG_AUTH_LDAP:
293: res = xauth_login_ldap(iph1, usr, pwd);
294: break;
295: #endif
296: default:
297: plog(LLV_ERROR, LOCATION, NULL,
298: "Unexpected authentication source\n");
299: res = -1;
300: break;
301: }
302:
303: /*
304: * Optional group authentication
305: */
306: if (!res && (isakmp_cfg_config.groupcount))
307: res = group_check(iph1,
308: isakmp_cfg_config.grouplist,
309: isakmp_cfg_config.groupcount);
310:
311: /*
312: * On failure, throttle the connexion for the remote host
313: * in order to make password attacks more difficult.
314: */
315: throttle_delay = throttle_host(iph1->remote, res);
316: if (throttle_delay > 0) {
317: char *str;
318:
319: str = saddrwop2str(iph1->remote);
320:
321: plog(LLV_ERROR, LOCATION, NULL,
322: "Throttling in action for %s: delay %lds\n",
323: str, (unsigned long)throttle_delay);
324: res = -1;
325: } else {
326: throttle_delay = 0;
327: }
328:
329: skip_auth:
330: if (throttle_delay != 0) {
331: struct xauth_reply_arg *xra;
332:
333: if ((xra = racoon_calloc(1, sizeof(*xra))) == NULL) {
334: plog(LLV_ERROR, LOCATION, NULL,
335: "malloc failed, bypass throttling\n");
336: return xauth_reply(iph1, port, id, res);
337: }
338:
339: /*
340: * We need to store the ph1, but it might have
341: * disapeared when xauth_reply is called, so
342: * store the index instead.
343: */
344: xra->index = iph1->index;
345: xra->port = port;
346: xra->id = id;
347: xra->res = res;
348: sched_schedule(&xra->sc, throttle_delay,
349: xauth_reply_stub);
350: } else {
351: return xauth_reply(iph1, port, id, res);
352: }
353: }
354:
355: return 0;
356: }
357:
358: void
359: xauth_reply_stub(sc)
360: struct sched *sc;
361: {
362: struct xauth_reply_arg *xra = container_of(sc, struct xauth_reply_arg, sc);
363: struct ph1handle *iph1;
364:
365: if ((iph1 = getph1byindex(&xra->index)) != NULL)
366: (void)xauth_reply(iph1, xra->port, xra->id, xra->res);
367: else
368: plog(LLV_ERROR, LOCATION, NULL,
369: "Delayed Xauth reply: phase 1 no longer exists.\n");
370:
371: racoon_free(xra);
372: }
373:
374: int
375: xauth_reply(iph1, port, id, res)
376: struct ph1handle *iph1;
377: int port;
378: int id;
379: {
380: struct xauth_state *xst = &iph1->mode_cfg->xauth;
381: char *usr = xst->authdata.generic.usr;
382:
383: if (res != 0) {
384: if (port != -1)
385: isakmp_cfg_putport(iph1, port);
386:
387: plog(LLV_INFO, LOCATION, NULL,
388: "login failed for user \"%s\"\n", usr);
389:
390: xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
391: xst->status = XAUTHST_NOTYET;
392:
393: /* Delete Phase 1 SA */
394: if (iph1->status >= PHASE1ST_ESTABLISHED)
395: isakmp_info_send_d1(iph1);
396: remph1(iph1);
397: delph1(iph1);
398:
399: return -1;
400: }
401:
402: xst->status = XAUTHST_OK;
403: plog(LLV_INFO, LOCATION, NULL,
404: "login succeeded for user \"%s\"\n", usr);
405:
406: xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
407:
408: return 0;
409: }
410:
411: void
412: xauth_sendstatus(iph1, status, id)
413: struct ph1handle *iph1;
414: int status;
415: int id;
416: {
417: vchar_t *buffer;
418: struct isakmp_pl_attr *attr;
419: struct isakmp_data *stattr;
420: size_t tlen;
421:
422: tlen = sizeof(*attr) +
423: + sizeof(*stattr);
424:
425: if ((buffer = vmalloc(tlen)) == NULL) {
426: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
427: return;
428: }
429:
430: attr = (struct isakmp_pl_attr *)buffer->v;
431: memset(attr, 0, tlen);
432:
433: attr->h.len = htons(tlen);
434: attr->type = ISAKMP_CFG_SET;
435: attr->id = htons(id);
436:
437: stattr = (struct isakmp_data *)(attr + 1);
438: stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV);
439: stattr->lorv = htons(status);
440:
441: isakmp_cfg_send(iph1, buffer,
442: ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
443:
444: vfree(buffer);
445:
446: return;
447: }
448:
449: #ifdef HAVE_LIBRADIUS
450: int
451: xauth_radius_init_conf(int free)
452: {
453: /* free radius config resources */
454: if (free) {
455: int i;
456: for (i = 0; i < xauth_rad_config.auth_server_count; i++) {
457: vfree(xauth_rad_config.auth_server_list[i].host);
458: vfree(xauth_rad_config.auth_server_list[i].secret);
459: }
460: for (i = 0; i < xauth_rad_config.acct_server_count; i++) {
461: vfree(xauth_rad_config.acct_server_list[i].host);
462: vfree(xauth_rad_config.acct_server_list[i].secret);
463: }
1.1.1.2 ! misho 464: if (radius_auth_state != NULL) {
1.1 misho 465: rad_close(radius_auth_state);
1.1.1.2 ! misho 466: radius_auth_state = NULL;
! 467: }
! 468: if (radius_acct_state != NULL) {
1.1 misho 469: rad_close(radius_acct_state);
1.1.1.2 ! misho 470: radius_acct_state = NULL;
! 471: }
1.1 misho 472: }
473:
474: /* initialize radius config */
475: memset(&xauth_rad_config, 0, sizeof(xauth_rad_config));
476: return 0;
477: }
478:
479: int
480: xauth_radius_init(void)
481: {
482: /* For first time use, initialize Radius */
483: if ((isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_RADIUS) &&
484: (radius_auth_state == NULL)) {
485: if ((radius_auth_state = rad_auth_open()) == NULL) {
486: plog(LLV_ERROR, LOCATION, NULL,
487: "Cannot init libradius\n");
488: return -1;
489: }
490:
491: int auth_count = xauth_rad_config.auth_server_count;
492: int auth_added = 0;
493: if (auth_count) {
494: int i;
495: for (i = 0; i < auth_count; i++) {
496: if(!rad_add_server(
497: radius_auth_state,
498: xauth_rad_config.auth_server_list[i].host->v,
499: xauth_rad_config.auth_server_list[i].port,
500: xauth_rad_config.auth_server_list[i].secret->v,
501: xauth_rad_config.timeout,
502: xauth_rad_config.retries ))
503: auth_added++;
504: else
505: plog(LLV_WARNING, LOCATION, NULL,
506: "could not add radius auth server %s\n",
507: xauth_rad_config.auth_server_list[i].host->v);
508: }
509: }
510:
511: if (!auth_added) {
512: if (rad_config(radius_auth_state, NULL) != 0) {
513: plog(LLV_ERROR, LOCATION, NULL,
514: "Cannot open libradius config file: %s\n",
515: rad_strerror(radius_auth_state));
516: rad_close(radius_auth_state);
517: radius_auth_state = NULL;
518: return -1;
519: }
520: }
521: }
522:
523: if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) &&
524: (radius_acct_state == NULL)) {
525: if ((radius_acct_state = rad_acct_open()) == NULL) {
526: plog(LLV_ERROR, LOCATION, NULL,
527: "Cannot init libradius\n");
528: return -1;
529: }
530:
531: int acct_count = xauth_rad_config.acct_server_count;
532: int acct_added = 0;
533: if (acct_count) {
534: int i;
535: for (i = 0; i < acct_count; i++) {
536: if(!rad_add_server(
537: radius_acct_state,
538: xauth_rad_config.acct_server_list[i].host->v,
539: xauth_rad_config.acct_server_list[i].port,
540: xauth_rad_config.acct_server_list[i].secret->v,
541: xauth_rad_config.timeout,
542: xauth_rad_config.retries ))
543: acct_added++;
544: else
545: plog(LLV_WARNING, LOCATION, NULL,
546: "could not add radius account server %s\n",
547: xauth_rad_config.acct_server_list[i].host->v);
548: }
549: }
550:
551: if (!acct_added) {
552: if (rad_config(radius_acct_state, NULL) != 0) {
553: plog(LLV_ERROR, LOCATION, NULL,
554: "Cannot open libradius config file: %s\n",
555: rad_strerror(radius_acct_state));
556: rad_close(radius_acct_state);
557: radius_acct_state = NULL;
558: return -1;
559: }
560: }
561: }
562:
563: return 0;
564: }
565:
566: int
567: xauth_login_radius(iph1, usr, pwd)
568: struct ph1handle *iph1;
569: char *usr;
570: char *pwd;
571: {
572: int res;
573: const void *data;
574: size_t len;
575: int type;
576:
577: if (rad_create_request(radius_auth_state, RAD_ACCESS_REQUEST) != 0) {
578: plog(LLV_ERROR, LOCATION, NULL,
579: "rad_create_request failed: %s\n",
580: rad_strerror(radius_auth_state));
581: return -1;
582: }
583:
584: if (rad_put_string(radius_auth_state, RAD_USER_NAME, usr) != 0) {
585: plog(LLV_ERROR, LOCATION, NULL,
586: "rad_put_string failed: %s\n",
587: rad_strerror(radius_auth_state));
588: return -1;
589: }
590:
591: if (rad_put_string(radius_auth_state, RAD_USER_PASSWORD, pwd) != 0) {
592: plog(LLV_ERROR, LOCATION, NULL,
593: "rad_put_string failed: %s\n",
594: rad_strerror(radius_auth_state));
595: return -1;
596: }
597:
598: if (isakmp_cfg_radius_common(radius_auth_state, iph1->mode_cfg->port) != 0)
599: return -1;
600:
601: switch (res = rad_send_request(radius_auth_state)) {
602: case RAD_ACCESS_ACCEPT:
603: while ((type = rad_get_attr(radius_auth_state, &data, &len)) != 0) {
604: switch (type) {
605: case RAD_FRAMED_IP_ADDRESS:
606: iph1->mode_cfg->addr4 = rad_cvt_addr(data);
607: iph1->mode_cfg->flags
608: |= ISAKMP_CFG_ADDR4_EXTERN;
609: break;
610:
611: case RAD_FRAMED_IP_NETMASK:
612: iph1->mode_cfg->mask4 = rad_cvt_addr(data);
613: iph1->mode_cfg->flags
614: |= ISAKMP_CFG_MASK4_EXTERN;
615: break;
616:
617: default:
618: plog(LLV_INFO, LOCATION, NULL,
619: "Unexpected attribute: %d\n", type);
620: break;
621: }
622: }
623:
624: return 0;
625: break;
626:
627: case RAD_ACCESS_REJECT:
628: return -1;
629: break;
630:
631: case -1:
632: plog(LLV_ERROR, LOCATION, NULL,
633: "rad_send_request failed: %s\n",
634: rad_strerror(radius_auth_state));
635: return -1;
636: break;
637: default:
638: plog(LLV_ERROR, LOCATION, NULL,
639: "rad_send_request returned %d\n", res);
640: return -1;
641: break;
642: }
643:
644: return -1;
645: }
646: #endif
647:
648: #ifdef HAVE_LIBPAM
649: static int
650: PAM_conv(msg_count, msg, rsp, dontcare)
651: int msg_count;
652: const struct pam_message **msg;
653: struct pam_response **rsp;
654: void *dontcare;
655: {
656: int i;
657: int replies = 0;
658: struct pam_response *reply = NULL;
659:
660: if ((reply = racoon_malloc(sizeof(*reply) * msg_count)) == NULL)
661: return PAM_CONV_ERR;
662: bzero(reply, sizeof(*reply) * msg_count);
663:
664: for (i = 0; i < msg_count; i++) {
665: switch (msg[i]->msg_style) {
666: case PAM_PROMPT_ECHO_ON:
667: /* Send the username, libpam frees resp */
668: reply[i].resp_retcode = PAM_SUCCESS;
669: if ((reply[i].resp = strdup(PAM_usr)) == NULL) {
670: plog(LLV_ERROR, LOCATION,
671: NULL, "strdup failed\n");
672: exit(1);
673: }
674: break;
675:
676: case PAM_PROMPT_ECHO_OFF:
677: /* Send the password, libpam frees resp */
678: reply[i].resp_retcode = PAM_SUCCESS;
679: if ((reply[i].resp = strdup(PAM_pwd)) == NULL) {
680: plog(LLV_ERROR, LOCATION,
681: NULL, "strdup failed\n");
682: exit(1);
683: }
684: break;
685:
686: case PAM_TEXT_INFO:
687: case PAM_ERROR_MSG:
688: reply[i].resp_retcode = PAM_SUCCESS;
689: reply[i].resp = NULL;
690: break;
691:
692: default:
693: if (reply != NULL)
694: racoon_free(reply);
695: return PAM_CONV_ERR;
696: break;
697: }
698: }
699:
700: if (reply != NULL)
701: *rsp = reply;
702:
703: return PAM_SUCCESS;
704: }
705:
706: int
707: xauth_login_pam(port, raddr, usr, pwd)
708: int port;
709: struct sockaddr *raddr;
710: char *usr;
711: char *pwd;
712: {
713: int error;
714: int res;
715: const void *data;
716: size_t len;
717: int type;
718: char *remote = NULL;
719: pam_handle_t *pam = NULL;
720:
721: if (isakmp_cfg_config.port_pool == NULL) {
722: plog(LLV_ERROR, LOCATION, NULL,
723: "isakmp_cfg_config.port_pool == NULL\n");
724: return -1;
725: }
726:
727: if ((error = pam_start("racoon", usr,
728: &PAM_chat, &isakmp_cfg_config.port_pool[port].pam)) != 0) {
729: if (isakmp_cfg_config.port_pool[port].pam == NULL) {
730: plog(LLV_ERROR, LOCATION, NULL, "pam_start failed\n");
731: return -1;
732: } else {
733: plog(LLV_ERROR, LOCATION, NULL,
734: "pam_start failed: %s\n",
735: pam_strerror(isakmp_cfg_config.port_pool[port].pam,
736: error));
737: goto out;
738: }
739: }
740: pam = isakmp_cfg_config.port_pool[port].pam;
741:
742: if ((remote = strdup(saddrwop2str(raddr))) == NULL) {
743: plog(LLV_ERROR, LOCATION, NULL,
744: "cannot allocate memory: %s\n", strerror(errno));
745: goto out;
746: }
747:
748: if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) {
749: plog(LLV_ERROR, LOCATION, NULL,
750: "pam_set_item failed: %s\n",
751: pam_strerror(pam, error));
752: goto out;
753: }
754:
755: if ((error = pam_set_item(pam, PAM_RUSER, usr)) != 0) {
756: plog(LLV_ERROR, LOCATION, NULL,
757: "pam_set_item failed: %s\n",
758: pam_strerror(pam, error));
759: goto out;
760: }
761:
762: PAM_usr = usr;
763: PAM_pwd = pwd;
764: error = pam_authenticate(pam, 0);
765: PAM_usr = NULL;
766: PAM_pwd = NULL;
767: if (error != 0) {
768: plog(LLV_ERROR, LOCATION, NULL,
769: "pam_authenticate failed: %s\n",
770: pam_strerror(pam, error));
771: goto out;
772: }
773:
774: if ((error = pam_acct_mgmt(pam, 0)) != 0) {
775: plog(LLV_ERROR, LOCATION, NULL,
776: "pam_acct_mgmt failed: %s\n",
777: pam_strerror(pam, error));
778: goto out;
779: }
780:
781: if ((error = pam_setcred(pam, 0)) != 0) {
782: plog(LLV_ERROR, LOCATION, NULL,
783: "pam_setcred failed: %s\n",
784: pam_strerror(pam, error));
785: goto out;
786: }
787:
788: if (remote != NULL)
789: free(remote);
790:
791: return 0;
792:
793: out:
794: pam_end(pam, error);
795: isakmp_cfg_config.port_pool[port].pam = NULL;
796: if (remote != NULL)
797: free(remote);
798: return -1;
799: }
800: #endif
801:
802: #ifdef HAVE_LIBLDAP
803: int
804: xauth_ldap_init_conf(void)
805: {
806: int tmplen;
807: int error = -1;
808:
809: xauth_ldap_config.pver = 3;
810: xauth_ldap_config.host = NULL;
811: xauth_ldap_config.port = LDAP_PORT;
812: xauth_ldap_config.base = NULL;
813: xauth_ldap_config.subtree = 0;
814: xauth_ldap_config.bind_dn = NULL;
815: xauth_ldap_config.bind_pw = NULL;
816: xauth_ldap_config.auth_type = LDAP_AUTH_SIMPLE;
817: xauth_ldap_config.attr_user = NULL;
818: xauth_ldap_config.attr_addr = NULL;
819: xauth_ldap_config.attr_mask = NULL;
820: xauth_ldap_config.attr_group = NULL;
821: xauth_ldap_config.attr_member = NULL;
822:
823: /* set default host */
824: tmplen = strlen(LDAP_DFLT_HOST);
825: xauth_ldap_config.host = vmalloc(tmplen);
826: if (xauth_ldap_config.host == NULL)
827: goto out;
828: memcpy(xauth_ldap_config.host->v, LDAP_DFLT_HOST, tmplen);
829:
830: /* set default user naming attribute */
831: tmplen = strlen(LDAP_DFLT_USER);
832: xauth_ldap_config.attr_user = vmalloc(tmplen);
833: if (xauth_ldap_config.attr_user == NULL)
834: goto out;
835: memcpy(xauth_ldap_config.attr_user->v, LDAP_DFLT_USER, tmplen);
836:
837: /* set default address attribute */
838: tmplen = strlen(LDAP_DFLT_ADDR);
839: xauth_ldap_config.attr_addr = vmalloc(tmplen);
840: if (xauth_ldap_config.attr_addr == NULL)
841: goto out;
842: memcpy(xauth_ldap_config.attr_addr->v, LDAP_DFLT_ADDR, tmplen);
843:
844: /* set default netmask attribute */
845: tmplen = strlen(LDAP_DFLT_MASK);
846: xauth_ldap_config.attr_mask = vmalloc(tmplen);
847: if (xauth_ldap_config.attr_mask == NULL)
848: goto out;
849: memcpy(xauth_ldap_config.attr_mask->v, LDAP_DFLT_MASK, tmplen);
850:
851: /* set default group naming attribute */
852: tmplen = strlen(LDAP_DFLT_GROUP);
853: xauth_ldap_config.attr_group = vmalloc(tmplen);
854: if (xauth_ldap_config.attr_group == NULL)
855: goto out;
856: memcpy(xauth_ldap_config.attr_group->v, LDAP_DFLT_GROUP, tmplen);
857:
858: /* set default member attribute */
859: tmplen = strlen(LDAP_DFLT_MEMBER);
860: xauth_ldap_config.attr_member = vmalloc(tmplen);
861: if (xauth_ldap_config.attr_member == NULL)
862: goto out;
863: memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen);
864:
865: error = 0;
866: out:
867: if (error != 0)
868: plog(LLV_ERROR, LOCATION, NULL, "cannot allocate memory\n");
869:
870: return error;
871: }
872:
873: int
874: xauth_login_ldap(iph1, usr, pwd)
875: struct ph1handle *iph1;
876: char *usr;
877: char *pwd;
878: {
879: int rtn = -1;
880: int res = -1;
881: LDAP *ld = NULL;
882: LDAPMessage *lr = NULL;
883: LDAPMessage *le = NULL;
884: struct berval cred;
885: struct berval **bv = NULL;
886: struct timeval timeout;
887: char *init = NULL;
888: char *filter = NULL;
889: char *atlist[3];
890: char *basedn = NULL;
891: char *userdn = NULL;
892: int tmplen = 0;
893: int ecount = 0;
894: int scope = LDAP_SCOPE_ONE;
895:
896: atlist[0] = NULL;
897: atlist[1] = NULL;
898: atlist[2] = NULL;
899:
900: /* build our initialization url */
901: tmplen = strlen("ldap://:") + 17;
902: tmplen += strlen(xauth_ldap_config.host->v);
903: init = racoon_malloc(tmplen);
904: if (init == NULL) {
905: plog(LLV_ERROR, LOCATION, NULL,
906: "unable to alloc ldap init url\n");
907: goto ldap_end;
908: }
909: sprintf(init,"ldap://%s:%d",
910: xauth_ldap_config.host->v,
911: xauth_ldap_config.port );
912:
913: /* initialize the ldap handle */
914: res = ldap_initialize(&ld, init);
915: if (res != LDAP_SUCCESS) {
916: plog(LLV_ERROR, LOCATION, NULL,
917: "ldap_initialize failed: %s\n",
918: ldap_err2string(res));
919: goto ldap_end;
920: }
921:
922: /* initialize the protocol version */
923: ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
924: &xauth_ldap_config.pver);
925:
926: /*
927: * attempt to bind to the ldap server.
928: * default to anonymous bind unless a
929: * user dn and password has been
930: * specified in our configuration
931: */
932: if ((xauth_ldap_config.bind_dn != NULL)&&
933: (xauth_ldap_config.bind_pw != NULL))
934: {
935: cred.bv_val = xauth_ldap_config.bind_pw->v;
936: cred.bv_len = strlen( cred.bv_val );
937: res = ldap_sasl_bind_s(ld,
938: xauth_ldap_config.bind_dn->v, NULL, &cred,
939: NULL, NULL, NULL);
940: }
941: else
942: {
943: res = ldap_sasl_bind_s(ld,
944: NULL, NULL, NULL,
945: NULL, NULL, NULL);
946: }
947:
948: if (res!=LDAP_SUCCESS) {
949: plog(LLV_ERROR, LOCATION, NULL,
950: "ldap_sasl_bind_s (search) failed: %s\n",
951: ldap_err2string(res));
952: goto ldap_end;
953: }
954:
955: /* build an ldap user search filter */
956: tmplen = strlen(xauth_ldap_config.attr_user->v);
957: tmplen += 1;
958: tmplen += strlen(usr);
959: tmplen += 1;
960: filter = racoon_malloc(tmplen);
961: if (filter == NULL) {
962: plog(LLV_ERROR, LOCATION, NULL,
963: "unable to alloc ldap search filter buffer\n");
964: goto ldap_end;
965: }
966: sprintf(filter, "%s=%s",
967: xauth_ldap_config.attr_user->v, usr);
968:
969: /* build our return attribute list */
970: tmplen = strlen(xauth_ldap_config.attr_addr->v) + 1;
971: atlist[0] = racoon_malloc(tmplen);
972: tmplen = strlen(xauth_ldap_config.attr_mask->v) + 1;
973: atlist[1] = racoon_malloc(tmplen);
974: if ((atlist[0] == NULL)||(atlist[1] == NULL)) {
975: plog(LLV_ERROR, LOCATION, NULL,
976: "unable to alloc ldap attrib list buffer\n");
977: goto ldap_end;
978: }
979: strcpy(atlist[0],xauth_ldap_config.attr_addr->v);
980: strcpy(atlist[1],xauth_ldap_config.attr_mask->v);
981:
982: /* attempt to locate the user dn */
983: if (xauth_ldap_config.base != NULL)
984: basedn = xauth_ldap_config.base->v;
985: if (xauth_ldap_config.subtree)
986: scope = LDAP_SCOPE_SUBTREE;
987: timeout.tv_sec = 15;
988: timeout.tv_usec = 0;
989: res = ldap_search_ext_s(ld, basedn, scope,
990: filter, atlist, 0, NULL, NULL,
991: &timeout, 2, &lr);
992: if (res != LDAP_SUCCESS) {
993: plog(LLV_ERROR, LOCATION, NULL,
994: "ldap_search_ext_s failed: %s\n",
995: ldap_err2string(res));
996: goto ldap_end;
997: }
998:
999: /* check the number of ldap entries returned */
1000: ecount = ldap_count_entries(ld, lr);
1001: if (ecount < 1) {
1002: plog(LLV_WARNING, LOCATION, NULL,
1003: "no ldap results for filter \'%s\'\n",
1004: filter);
1005: goto ldap_end;
1006: }
1007: if (ecount > 1) {
1008: plog(LLV_WARNING, LOCATION, NULL,
1009: "multiple (%i) ldap results for filter \'%s\'\n",
1010: ecount, filter);
1011: }
1012:
1013: /* obtain the dn from the first result */
1014: le = ldap_first_entry(ld, lr);
1015: if (le == NULL) {
1016: plog(LLV_ERROR, LOCATION, NULL,
1017: "ldap_first_entry failed: invalid entry returned\n");
1018: goto ldap_end;
1019: }
1020: userdn = ldap_get_dn(ld, le);
1021: if (userdn == NULL) {
1022: plog(LLV_ERROR, LOCATION, NULL,
1023: "ldap_get_dn failed: invalid string returned\n");
1024: goto ldap_end;
1025: }
1026:
1027: /* cache the user dn in the xauth state */
1028: iph1->mode_cfg->xauth.udn = racoon_malloc(strlen(userdn)+1);
1029: strcpy(iph1->mode_cfg->xauth.udn,userdn);
1030:
1031: /* retrieve modecfg address */
1032: bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_addr->v);
1033: if (bv != NULL) {
1034: char tmpaddr[16];
1035: /* sanity check for address value */
1036: if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
1037: plog(LLV_DEBUG, LOCATION, NULL,
1038: "ldap returned invalid modecfg address\n");
1039: ldap_value_free_len(bv);
1040: goto ldap_end;
1041: }
1042: memcpy(tmpaddr,bv[0]->bv_val,bv[0]->bv_len);
1043: tmpaddr[bv[0]->bv_len]=0;
1044: iph1->mode_cfg->addr4.s_addr = inet_addr(tmpaddr);
1045: iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_EXTERN;
1046: plog(LLV_INFO, LOCATION, NULL,
1047: "ldap returned modecfg address %s\n", tmpaddr);
1048: ldap_value_free_len(bv);
1049: }
1050:
1051: /* retrieve modecfg netmask */
1052: bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_mask->v);
1053: if (bv != NULL) {
1054: char tmpmask[16];
1055: /* sanity check for netmask value */
1056: if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
1057: plog(LLV_DEBUG, LOCATION, NULL,
1058: "ldap returned invalid modecfg netmask\n");
1059: ldap_value_free_len(bv);
1060: goto ldap_end;
1061: }
1062: memcpy(tmpmask,bv[0]->bv_val,bv[0]->bv_len);
1063: tmpmask[bv[0]->bv_len]=0;
1064: iph1->mode_cfg->mask4.s_addr = inet_addr(tmpmask);
1065: iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_EXTERN;
1066: plog(LLV_INFO, LOCATION, NULL,
1067: "ldap returned modecfg netmask %s\n", tmpmask);
1068: ldap_value_free_len(bv);
1069: }
1070:
1071: /*
1072: * finally, use the dn and the xauth
1073: * password to check the users given
1074: * credentials by attempting to bind
1075: * to the ldap server
1076: */
1077: plog(LLV_INFO, LOCATION, NULL,
1078: "attempting ldap bind for dn \'%s\'\n", userdn);
1079: cred.bv_val = pwd;
1080: cred.bv_len = strlen( cred.bv_val );
1081: res = ldap_sasl_bind_s(ld,
1082: userdn, NULL, &cred,
1083: NULL, NULL, NULL);
1084: if(res==LDAP_SUCCESS)
1085: rtn = 0;
1086:
1087: ldap_end:
1088:
1089: /* free ldap resources */
1090: if (userdn != NULL)
1091: ldap_memfree(userdn);
1092: if (atlist[0] != NULL)
1093: racoon_free(atlist[0]);
1094: if (atlist[1] != NULL)
1095: racoon_free(atlist[1]);
1096: if (filter != NULL)
1097: racoon_free(filter);
1098: if (lr != NULL)
1099: ldap_msgfree(lr);
1100: if (init != NULL)
1101: racoon_free(init);
1102:
1103: ldap_unbind_ext_s(ld, NULL, NULL);
1104:
1105: return rtn;
1106: }
1107:
1108: int
1109: xauth_group_ldap(udn, grp)
1110: char * udn;
1111: char * grp;
1112: {
1113: int rtn = -1;
1114: int res = -1;
1115: LDAP *ld = NULL;
1116: LDAPMessage *lr = NULL;
1117: LDAPMessage *le = NULL;
1118: struct berval cred;
1119: struct timeval timeout;
1120: char *init = NULL;
1121: char *filter = NULL;
1122: char *basedn = NULL;
1123: char *groupdn = NULL;
1124: int tmplen = 0;
1125: int ecount = 0;
1126: int scope = LDAP_SCOPE_ONE;
1127:
1128: /* build our initialization url */
1129: tmplen = strlen("ldap://:") + 17;
1130: tmplen += strlen(xauth_ldap_config.host->v);
1131: init = racoon_malloc(tmplen);
1132: if (init == NULL) {
1133: plog(LLV_ERROR, LOCATION, NULL,
1134: "unable to alloc ldap init url\n");
1135: goto ldap_group_end;
1136: }
1137: sprintf(init,"ldap://%s:%d",
1138: xauth_ldap_config.host->v,
1139: xauth_ldap_config.port );
1140:
1141: /* initialize the ldap handle */
1142: res = ldap_initialize(&ld, init);
1143: if (res != LDAP_SUCCESS) {
1144: plog(LLV_ERROR, LOCATION, NULL,
1145: "ldap_initialize failed: %s\n",
1146: ldap_err2string(res));
1147: goto ldap_group_end;
1148: }
1149:
1150: /* initialize the protocol version */
1151: ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
1152: &xauth_ldap_config.pver);
1153:
1154: /*
1155: * attempt to bind to the ldap server.
1156: * default to anonymous bind unless a
1157: * user dn and password has been
1158: * specified in our configuration
1159: */
1160: if ((xauth_ldap_config.bind_dn != NULL)&&
1161: (xauth_ldap_config.bind_pw != NULL))
1162: {
1163: cred.bv_val = xauth_ldap_config.bind_pw->v;
1164: cred.bv_len = strlen( cred.bv_val );
1165: res = ldap_sasl_bind_s(ld,
1166: xauth_ldap_config.bind_dn->v, NULL, &cred,
1167: NULL, NULL, NULL);
1168: }
1169: else
1170: {
1171: res = ldap_sasl_bind_s(ld,
1172: NULL, NULL, NULL,
1173: NULL, NULL, NULL);
1174: }
1175:
1176: if (res!=LDAP_SUCCESS) {
1177: plog(LLV_ERROR, LOCATION, NULL,
1178: "ldap_sasl_bind_s (search) failed: %s\n",
1179: ldap_err2string(res));
1180: goto ldap_group_end;
1181: }
1182:
1183: /* build an ldap group search filter */
1184: tmplen = strlen("(&(=)(=))") + 1;
1185: tmplen += strlen(xauth_ldap_config.attr_group->v);
1186: tmplen += strlen(grp);
1187: tmplen += strlen(xauth_ldap_config.attr_member->v);
1188: tmplen += strlen(udn);
1189: filter = racoon_malloc(tmplen);
1190: if (filter == NULL) {
1191: plog(LLV_ERROR, LOCATION, NULL,
1192: "unable to alloc ldap search filter buffer\n");
1193: goto ldap_group_end;
1194: }
1195: sprintf(filter, "(&(%s=%s)(%s=%s))",
1196: xauth_ldap_config.attr_group->v, grp,
1197: xauth_ldap_config.attr_member->v, udn);
1198:
1199: /* attempt to locate the group dn */
1200: if (xauth_ldap_config.base != NULL)
1201: basedn = xauth_ldap_config.base->v;
1202: if (xauth_ldap_config.subtree)
1203: scope = LDAP_SCOPE_SUBTREE;
1204: timeout.tv_sec = 15;
1205: timeout.tv_usec = 0;
1206: res = ldap_search_ext_s(ld, basedn, scope,
1207: filter, NULL, 0, NULL, NULL,
1208: &timeout, 2, &lr);
1209: if (res != LDAP_SUCCESS) {
1210: plog(LLV_ERROR, LOCATION, NULL,
1211: "ldap_search_ext_s failed: %s\n",
1212: ldap_err2string(res));
1213: goto ldap_group_end;
1214: }
1215:
1216: /* check the number of ldap entries returned */
1217: ecount = ldap_count_entries(ld, lr);
1218: if (ecount < 1) {
1219: plog(LLV_WARNING, LOCATION, NULL,
1220: "no ldap results for filter \'%s\'\n",
1221: filter);
1222: goto ldap_group_end;
1223: }
1224:
1225: /* success */
1226: rtn = 0;
1227:
1228: /* obtain the dn from the first result */
1229: le = ldap_first_entry(ld, lr);
1230: if (le == NULL) {
1231: plog(LLV_ERROR, LOCATION, NULL,
1232: "ldap_first_entry failed: invalid entry returned\n");
1233: goto ldap_group_end;
1234: }
1235: groupdn = ldap_get_dn(ld, le);
1236: if (groupdn == NULL) {
1237: plog(LLV_ERROR, LOCATION, NULL,
1238: "ldap_get_dn failed: invalid string returned\n");
1239: goto ldap_group_end;
1240: }
1241:
1242: plog(LLV_INFO, LOCATION, NULL,
1243: "ldap membership group returned \'%s\'\n", groupdn);
1244: ldap_group_end:
1245:
1246: /* free ldap resources */
1247: if (groupdn != NULL)
1248: ldap_memfree(groupdn);
1249: if (filter != NULL)
1250: racoon_free(filter);
1251: if (lr != NULL)
1252: ldap_msgfree(lr);
1253: if (init != NULL)
1254: racoon_free(init);
1255:
1256: ldap_unbind_ext_s(ld, NULL, NULL);
1257:
1258: return rtn;
1259: }
1260:
1261: #endif
1262:
1263: int
1264: xauth_login_system(usr, pwd)
1265: char *usr;
1266: char *pwd;
1267: {
1268: struct passwd *pw;
1269: char *cryptpwd;
1270: char *syscryptpwd;
1271: #ifdef HAVE_SHADOW_H
1272: struct spwd *spw;
1273:
1274: if ((spw = getspnam(usr)) == NULL)
1275: return -1;
1276:
1277: syscryptpwd = spw->sp_pwdp;
1278: #endif
1279:
1280: if ((pw = getpwnam(usr)) == NULL)
1281: return -1;
1282:
1283: #ifndef HAVE_SHADOW_H
1284: syscryptpwd = pw->pw_passwd;
1285: #endif
1286:
1287: /* No root login. Ever. */
1288: if (pw->pw_uid == 0)
1289: return -1;
1290:
1291: if ((cryptpwd = crypt(pwd, syscryptpwd)) == NULL)
1292: return -1;
1293:
1294: if (strcmp(cryptpwd, syscryptpwd) == 0)
1295: return 0;
1296:
1297: return -1;
1298: }
1299:
1300: int
1301: xauth_group_system(usr, grp)
1302: char * usr;
1303: char * grp;
1304: {
1305: struct group * gr;
1306: char * member;
1307: int index = 0;
1308:
1309: gr = getgrnam(grp);
1310: if (gr == NULL) {
1311: plog(LLV_ERROR, LOCATION, NULL,
1312: "the system group name \'%s\' is unknown\n",
1313: grp);
1314: return -1;
1315: }
1316:
1317: while ((member = gr->gr_mem[index++])!=NULL) {
1318: if (!strcmp(member,usr)) {
1319: plog(LLV_INFO, LOCATION, NULL,
1320: "membership validated\n");
1321: return 0;
1322: }
1323: }
1324:
1325: return -1;
1326: }
1327:
1328: int
1329: xauth_check(iph1)
1330: struct ph1handle *iph1;
1331: {
1332: struct xauth_state *xst = &iph1->mode_cfg->xauth;
1333:
1334: /*
1335: * Only the server side (edge device) really check for Xauth
1336: * status. It does it if the chose authmethod is using Xauth.
1337: * On the client side (roadwarrior), we don't check anything.
1338: */
1339: switch (iph1->approval->authmethod) {
1340: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1341: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1342: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1343: /* The following are not yet implemented */
1344: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1345: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1346: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1347: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1348: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1349: plog(LLV_ERROR, LOCATION, NULL,
1350: "Hybrid auth negotiated but peer did not "
1351: "announced as Xauth capable\n");
1352: return -1;
1353: }
1354:
1355: if (xst->status != XAUTHST_OK) {
1356: plog(LLV_ERROR, LOCATION, NULL,
1357: "Hybrid auth negotiated but peer did not "
1358: "succeed Xauth exchange\n");
1359: return -1;
1360: }
1361:
1362: return 0;
1363: break;
1364: default:
1365: return 0;
1366: break;
1367: }
1368:
1369: return 0;
1370: }
1371:
1372: int
1373: group_check(iph1, grp_list, grp_count)
1374: struct ph1handle *iph1;
1375: char **grp_list;
1376: int grp_count;
1377: {
1378: int res = -1;
1379: int grp_index = 0;
1380: char * usr = NULL;
1381:
1382: /* check for presence of modecfg data */
1383:
1384: if(iph1->mode_cfg == NULL) {
1385: plog(LLV_ERROR, LOCATION, NULL,
1386: "xauth group specified but modecfg not found\n");
1387: return res;
1388: }
1389:
1390: /* loop through our group list */
1391:
1392: for(; grp_index < grp_count; grp_index++) {
1393:
1394: /* check for presence of xauth data */
1395:
1396: usr = iph1->mode_cfg->xauth.authdata.generic.usr;
1397:
1398: if(usr == NULL) {
1399: plog(LLV_ERROR, LOCATION, NULL,
1400: "xauth group specified but xauth not found\n");
1401: return res;
1402: }
1403:
1404: /* call appropriate group validation funtion */
1405:
1406: switch (isakmp_cfg_config.groupsource) {
1407:
1408: case ISAKMP_CFG_GROUP_SYSTEM:
1409: res = xauth_group_system(
1410: usr,
1411: grp_list[grp_index]);
1412: break;
1413:
1414: #ifdef HAVE_LIBLDAP
1415: case ISAKMP_CFG_GROUP_LDAP:
1416: res = xauth_group_ldap(
1417: iph1->mode_cfg->xauth.udn,
1418: grp_list[grp_index]);
1419: break;
1420: #endif
1421:
1422: default:
1423: /* we should never get here */
1424: plog(LLV_ERROR, LOCATION, NULL,
1425: "Unknown group auth source\n");
1426: break;
1427: }
1428:
1429: if( !res ) {
1430: plog(LLV_INFO, LOCATION, NULL,
1431: "user \"%s\" is a member of group \"%s\"\n",
1432: usr,
1433: grp_list[grp_index]);
1434: break;
1435: } else {
1436: plog(LLV_INFO, LOCATION, NULL,
1437: "user \"%s\" is not a member of group \"%s\"\n",
1438: usr,
1439: grp_list[grp_index]);
1440: }
1441: }
1442:
1443: return res;
1444: }
1445:
1446: vchar_t *
1447: isakmp_xauth_req(iph1, attr)
1448: struct ph1handle *iph1;
1449: struct isakmp_data *attr;
1450: {
1451: int type;
1452: size_t dlen = 0;
1453: int ashort = 0;
1454: int value = 0;
1455: vchar_t *buffer = NULL;
1456: char *mraw = NULL, *mdata;
1457: char *data;
1458: vchar_t *usr = NULL;
1459: vchar_t *pwd = NULL;
1460: size_t skip = 0;
1461: int freepwd = 0;
1462:
1463: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1464: plog(LLV_ERROR, LOCATION, NULL,
1465: "Xauth mode config request but peer "
1466: "did not declare itself as Xauth capable\n");
1467: return NULL;
1468: }
1469:
1470: type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
1471:
1472: /* Sanity checks */
1473: switch(type) {
1474: case XAUTH_TYPE:
1475: if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
1476: plog(LLV_ERROR, LOCATION, NULL,
1477: "Unexpected long XAUTH_TYPE attribute\n");
1478: return NULL;
1479: }
1480: if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
1481: plog(LLV_ERROR, LOCATION, NULL,
1482: "Unsupported Xauth authentication %d\n",
1483: ntohs(attr->lorv));
1484: return NULL;
1485: }
1486: ashort = 1;
1487: dlen = 0;
1488: value = XAUTH_TYPE_GENERIC;
1489: break;
1490:
1491: case XAUTH_USER_NAME:
1492: if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
1493: plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
1494: "with no login supplied\n");
1495: return NULL;
1496: }
1497:
1498: dlen = iph1->rmconf->xauth->login->l - 1;
1499: iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
1500: break;
1501:
1502: case XAUTH_USER_PASSWORD:
1503: if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
1504: return NULL;
1505:
1506: skip = sizeof(struct ipsecdoi_id_b);
1507: usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
1508: if (usr == NULL) {
1509: plog(LLV_ERROR, LOCATION, NULL,
1510: "Cannot allocate memory\n");
1511: return NULL;
1512: }
1513: memset(usr->v, 0, skip);
1514: memcpy(usr->v + skip,
1515: iph1->rmconf->xauth->login->v,
1516: iph1->rmconf->xauth->login->l - 1);
1517:
1518: if (iph1->rmconf->xauth->pass) {
1519: /* A key given through racoonctl */
1520: pwd = iph1->rmconf->xauth->pass;
1521: } else {
1522: if ((pwd = getpskbyname(usr)) == NULL) {
1523: plog(LLV_ERROR, LOCATION, NULL,
1524: "No password was found for login %s\n",
1525: iph1->rmconf->xauth->login->v);
1526: vfree(usr);
1527: return NULL;
1528: }
1529: /* We have to free it before returning */
1530: freepwd = 1;
1531: }
1532: vfree(usr);
1533:
1534: iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
1535: dlen = pwd->l;
1536:
1537: break;
1538: case XAUTH_MESSAGE:
1539: if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
1540: dlen = ntohs(attr->lorv);
1541: if (dlen > 0) {
1542: mraw = (char*)(attr + 1);
1543: mdata = binsanitize(mraw, dlen);
1544: if (mdata == NULL) {
1545: plog(LLV_ERROR, LOCATION, iph1->remote,
1546: "Cannot allocate memory\n");
1547: return NULL;
1548: }
1549: plog(LLV_NOTIFY,LOCATION, iph1->remote,
1550: "XAUTH Message: '%s'.\n",
1551: mdata);
1552: racoon_free(mdata);
1553: }
1554: }
1555: return NULL;
1556: default:
1557: plog(LLV_WARNING, LOCATION, NULL,
1558: "Ignored attribute %s\n", s_isakmp_cfg_type(type));
1559: return NULL;
1560: break;
1561: }
1562:
1563: if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
1564: plog(LLV_ERROR, LOCATION, NULL,
1565: "Cannot allocate memory\n");
1566: goto out;
1567: }
1568:
1569: attr = (struct isakmp_data *)buffer->v;
1570: if (ashort) {
1571: attr->type = htons(type | ISAKMP_GEN_TV);
1572: attr->lorv = htons(value);
1573: goto out;
1574: }
1575:
1576: attr->type = htons(type | ISAKMP_GEN_TLV);
1577: attr->lorv = htons(dlen);
1578: data = (char *)(attr + 1);
1579:
1580: switch(type) {
1581: case XAUTH_USER_NAME:
1582: /*
1583: * iph1->rmconf->xauth->login->v is valid,
1584: * we just checked it in the previous switch case
1585: */
1586: memcpy(data, iph1->rmconf->xauth->login->v, dlen);
1587: break;
1588: case XAUTH_USER_PASSWORD:
1589: memcpy(data, pwd->v, dlen);
1590: break;
1591: default:
1592: break;
1593: }
1594:
1595: out:
1596: if (freepwd)
1597: vfree(pwd);
1598:
1599: return buffer;
1600: }
1601:
1602: vchar_t *
1603: isakmp_xauth_set(iph1, attr)
1604: struct ph1handle *iph1;
1605: struct isakmp_data *attr;
1606: {
1607: int type;
1608: vchar_t *buffer = NULL;
1609: char *data;
1610: struct xauth_state *xst;
1611: size_t dlen = 0;
1612: char* mraw = NULL, *mdata;
1613:
1614: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1615: plog(LLV_ERROR, LOCATION, NULL,
1616: "Xauth mode config set but peer "
1617: "did not declare itself as Xauth capable\n");
1618: return NULL;
1619: }
1620:
1621: type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
1622:
1623: switch(type) {
1624: case XAUTH_STATUS:
1625: /*
1626: * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS
1627: * when running as a client (initiator).
1628: */
1629: xst = &iph1->mode_cfg->xauth;
1630: switch (iph1->approval->authmethod) {
1631: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1632: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
1633: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1634: /* Not implemented ... */
1635: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1636: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1637: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1638: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1639: break;
1640: default:
1641: plog(LLV_ERROR, LOCATION, NULL,
1642: "Unexpected XAUTH_STATUS_OK\n");
1643: return NULL;
1644: break;
1645: }
1646:
1647: /* If we got a failure, delete iph1 */
1648: if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
1649: plog(LLV_ERROR, LOCATION, NULL,
1650: "Xauth authentication failed\n");
1651:
1652: evt_phase1(iph1, EVT_PHASE1_XAUTH_FAILED, NULL);
1653:
1654: iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
1655: } else {
1656: evt_phase1(iph1, EVT_PHASE1_XAUTH_SUCCESS, NULL);
1657: }
1658:
1659:
1660: /* We acknowledge it */
1661: break;
1662: case XAUTH_MESSAGE:
1663: if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
1664: dlen = ntohs(attr->lorv);
1665: if (dlen > 0) {
1666: mraw = (char*)(attr + 1);
1667: mdata = binsanitize(mraw, dlen);
1668: if (mdata == NULL) {
1669: plog(LLV_ERROR, LOCATION, iph1->remote,
1670: "Cannot allocate memory\n");
1671: return NULL;
1672: }
1673: plog(LLV_NOTIFY,LOCATION, iph1->remote,
1674: "XAUTH Message: '%s'.\n",
1675: mdata);
1676: racoon_free(mdata);
1677: }
1678: }
1679:
1680: default:
1681: plog(LLV_WARNING, LOCATION, NULL,
1682: "Ignored attribute %s\n", s_isakmp_cfg_type(type));
1683: return NULL;
1684: break;
1685: }
1686:
1687: if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1688: plog(LLV_ERROR, LOCATION, NULL,
1689: "Cannot allocate memory\n");
1690: return NULL;
1691: }
1692:
1693: attr = (struct isakmp_data *)buffer->v;
1694: attr->type = htons(type | ISAKMP_GEN_TV);
1695: attr->lorv = htons(0);
1696:
1697: return buffer;
1698: }
1699:
1700:
1701: void
1702: xauth_rmstate(xst)
1703: struct xauth_state *xst;
1704: {
1705: switch (xst->authtype) {
1706: case XAUTH_TYPE_GENERIC:
1707: if (xst->authdata.generic.usr)
1708: racoon_free(xst->authdata.generic.usr);
1709:
1710: if (xst->authdata.generic.pwd)
1711: racoon_free(xst->authdata.generic.pwd);
1712:
1713: break;
1714:
1715: case XAUTH_TYPE_CHAP:
1716: case XAUTH_TYPE_OTP:
1717: case XAUTH_TYPE_SKEY:
1718: plog(LLV_WARNING, LOCATION, NULL,
1719: "Unsupported authtype %d\n", xst->authtype);
1720: break;
1721:
1722: default:
1723: plog(LLV_WARNING, LOCATION, NULL,
1724: "Unexpected authtype %d\n", xst->authtype);
1725: break;
1726: }
1727:
1728: #ifdef HAVE_LIBLDAP
1729: if (xst->udn != NULL)
1730: racoon_free(xst->udn);
1731: #endif
1732: return;
1733: }
1734:
1735: int
1736: xauth_rmconf_used(xauth_rmconf)
1737: struct xauth_rmconf **xauth_rmconf;
1738: {
1739: if (*xauth_rmconf == NULL) {
1740: *xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf));
1741: if (*xauth_rmconf == NULL) {
1742: plog(LLV_ERROR, LOCATION, NULL,
1743: "xauth_rmconf_used: malloc failed\n");
1744: return -1;
1745: }
1746:
1747: (*xauth_rmconf)->login = NULL;
1748: (*xauth_rmconf)->pass = NULL;
1749: (*xauth_rmconf)->state = 0;
1750: }
1751:
1752: return 0;
1753: }
1754:
1755: void
1756: xauth_rmconf_delete(xauth_rmconf)
1757: struct xauth_rmconf **xauth_rmconf;
1758: {
1759: if (*xauth_rmconf != NULL) {
1760: if ((*xauth_rmconf)->login != NULL)
1761: vfree((*xauth_rmconf)->login);
1762: if ((*xauth_rmconf)->pass != NULL)
1763: vfree((*xauth_rmconf)->pass);
1764:
1765: racoon_free(*xauth_rmconf);
1766: *xauth_rmconf = NULL;
1767: }
1768:
1769: return;
1770: }
1771:
1772: struct xauth_rmconf *
1773: xauth_rmconf_dup(xauth_rmconf)
1774: struct xauth_rmconf *xauth_rmconf;
1775: {
1776: struct xauth_rmconf *new;
1777:
1778: if (xauth_rmconf != NULL) {
1779: new = racoon_malloc(sizeof(*new));
1780: if (new == NULL) {
1781: plog(LLV_ERROR, LOCATION, NULL,
1782: "xauth_rmconf_dup: malloc failed\n");
1783: return NULL;
1784: }
1785:
1786: memcpy(new, xauth_rmconf, sizeof(*new));
1787:
1788: if (xauth_rmconf->login != NULL) {
1789: new->login = vdup(xauth_rmconf->login);
1790: if (new->login == NULL) {
1791: plog(LLV_ERROR, LOCATION, NULL,
1792: "xauth_rmconf_dup: malloc failed (login)\n");
1793: return NULL;
1794: }
1795: }
1796: if (xauth_rmconf->pass != NULL) {
1797: new->pass = vdup(xauth_rmconf->pass);
1798: if (new->pass == NULL) {
1799: plog(LLV_ERROR, LOCATION, NULL,
1800: "xauth_rmconf_dup: malloc failed (password)\n");
1801: return NULL;
1802: }
1803: }
1804:
1805: return new;
1806: }
1807:
1808: return NULL;
1809: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>