]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/isakmp_xauth.c
ipsec-34.0.2.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_xauth.c
1 /* $Id: isakmp_xauth.c,v 1.17.2.5 2005/05/20 07:31:09 manubsd Exp $ */
2
3 /*
4 * Copyright (C) 2004-2005 Emmanuel Dreyfus
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include "config.h"
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37 #include <sys/queue.h>
38
39 #include <netinet/in.h>
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <errno.h>
45 #include <pwd.h>
46 #ifdef HAVE_SHADOW_H
47 #include <shadow.h>
48 #endif
49 #if TIME_WITH_SYS_TIME
50 # include <sys/time.h>
51 # include <time.h>
52 #else
53 # if HAVE_SYS_TIME_H
54 # include <sys/time.h>
55 # else
56 # include <time.h>
57 # endif
58 #endif
59 #include <netdb.h>
60 #ifdef HAVE_UNISTD_H
61 #include <unistd.h>
62 #endif
63 #include <ctype.h>
64
65 #include "var.h"
66 #include "misc.h"
67 #include "vmbuf.h"
68 #include "plog.h"
69 #include "sockmisc.h"
70 #include "schedule.h"
71 #include "debug.h"
72
73 #include "crypto_openssl.h"
74 #include "isakmp_var.h"
75 #include "isakmp.h"
76 #include "admin.h"
77 #include "privsep.h"
78 #include "evt.h"
79 #include "handler.h"
80 #include "throttle.h"
81 #include "remoteconf.h"
82 #include "isakmp_inf.h"
83 #include "isakmp_xauth.h"
84 #include "isakmp_unity.h"
85 #include "isakmp_cfg.h"
86 #include "strnames.h"
87 #include "ipsec_doi.h"
88 #include "remoteconf.h"
89 #include "localconf.h"
90
91 #ifdef HAVE_LIBRADIUS
92 #include <radlib.h>
93
94 struct rad_handle *radius_auth_state = NULL;
95 struct rad_handle *radius_acct_state = NULL;
96 #endif
97
98 #ifdef HAVE_LIBPAM
99 #ifdef __APPLE__
100 #include <pam/pam_appl.h>
101 #else
102 #include <security/pam_appl.h>
103 #endif
104
105 static char *PAM_usr = NULL;
106 static char *PAM_pwd = NULL;
107 static int PAM_conv(int, const struct pam_message **,
108 struct pam_response **, void *);
109 static struct pam_conv PAM_chat = { &PAM_conv, NULL };
110 #endif
111
112
113 void
114 xauth_sendreq(iph1)
115 struct ph1handle *iph1;
116 {
117 vchar_t *buffer;
118 struct isakmp_pl_attr *attr;
119 struct isakmp_data *typeattr;
120 struct isakmp_data *usrattr;
121 struct isakmp_data *pwdattr;
122 struct xauth_state *xst = &iph1->mode_cfg->xauth;
123 size_t tlen;
124
125 /* Status checks */
126 if (iph1->status != PHASE1ST_ESTABLISHED) {
127 plog(LLV_ERROR, LOCATION, NULL,
128 "Xauth request while phase 1 is not completed\n");
129 return;
130 }
131
132 if (xst->status != XAUTHST_NOTYET) {
133 plog(LLV_ERROR, LOCATION, NULL,
134 "Xauth request whith Xauth state %d\n", xst->status);
135 return;
136 }
137
138 plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n");
139
140 tlen = sizeof(*attr) +
141 + sizeof(*typeattr) +
142 + sizeof(*usrattr) +
143 + sizeof(*pwdattr);
144
145 if ((buffer = vmalloc(tlen)) == NULL) {
146 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
147 return;
148 }
149
150 attr = (struct isakmp_pl_attr *)buffer->v;
151 memset(attr, 0, tlen);
152
153 attr->h.len = htons(tlen);
154 attr->type = ISAKMP_CFG_REQUEST;
155 attr->id = htons(eay_random());
156
157 typeattr = (struct isakmp_data *)(attr + 1);
158 typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV);
159 typeattr->lorv = htons(XAUTH_TYPE_GENERIC);
160
161 usrattr = (struct isakmp_data *)(typeattr + 1);
162 usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV);
163 usrattr->lorv = htons(0);
164
165 pwdattr = (struct isakmp_data *)(usrattr + 1);
166 pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV);
167 pwdattr->lorv = htons(0);
168
169 isakmp_cfg_send(iph1, buffer,
170 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
171
172 vfree(buffer);
173
174 xst->status = XAUTHST_REQSENT;
175
176 return;
177 }
178
179 void
180 xauth_attr_reply(iph1, attr, id)
181 struct ph1handle *iph1;
182 struct isakmp_data *attr;
183 int id;
184 {
185 char **outlet = NULL;
186 size_t alen = 0;
187 int type;
188 struct xauth_state *xst = &iph1->mode_cfg->xauth;
189
190 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
191 plog(LLV_ERROR, LOCATION, NULL,
192 "Xauth reply but peer did not declare "
193 "itself as Xauth capable\n");
194 return;
195 }
196
197 if (xst->status != XAUTHST_REQSENT) {
198 plog(LLV_ERROR, LOCATION, NULL,
199 "Xauth reply while Xauth state is %d\n", xst->status);
200 return;
201 }
202
203 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
204 switch (type) {
205 case XAUTH_TYPE:
206 switch (ntohs(attr->lorv)) {
207 case XAUTH_TYPE_GENERIC:
208 xst->authtype = XAUTH_TYPE_GENERIC;
209 break;
210 default:
211 plog(LLV_WARNING, LOCATION, NULL,
212 "Unexpected authentication type %d\n",
213 ntohs(type));
214 return;
215 }
216 break;
217
218 case XAUTH_USER_NAME:
219 outlet = &xst->authdata.generic.usr;
220 break;
221
222 case XAUTH_USER_PASSWORD:
223 outlet = &xst->authdata.generic.pwd;
224 break;
225
226 default:
227 plog(LLV_WARNING, LOCATION, NULL,
228 "ignored Xauth attribute %d\n", type);
229 break;
230 }
231
232 if (outlet != NULL) {
233 alen = ntohs(attr->lorv);
234
235 if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
236 plog(LLV_ERROR, LOCATION, NULL,
237 "Cannot allocate memory for Xauth Data\n");
238 return;
239 }
240
241 memcpy(*outlet, attr + 1, alen);
242 (*outlet)[alen] = '\0';
243 outlet = NULL;
244 }
245
246
247 if ((xst->authdata.generic.usr != NULL) &&
248 (xst->authdata.generic.pwd != NULL)) {
249 int port;
250 int res;
251 char *usr = xst->authdata.generic.usr;
252 char *pwd = xst->authdata.generic.pwd;
253 time_t throttle_delay = 0;
254
255 #if 0 /* Real debug, don't do that at home */
256 plog(LLV_DEBUG, LOCATION, NULL,
257 "Got username \"%s\", password \"%s\"\n", usr, pwd);
258 #endif
259 strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
260 iph1->mode_cfg->login[LOGINLEN] = '\0';
261
262 res = -1;
263 if ((port = isakmp_cfg_getport(iph1)) == -1) {
264 plog(LLV_ERROR, LOCATION, NULL,
265 "Port pool depleted\n");
266 goto skip_auth;
267 }
268
269 switch (isakmp_cfg_config.authsource) {
270 case ISAKMP_CFG_AUTH_SYSTEM:
271 res = privsep_xauth_login_system(usr, pwd);
272 break;
273 #ifdef HAVE_LIBRADIUS
274 case ISAKMP_CFG_AUTH_RADIUS:
275 res = xauth_login_radius(iph1, usr, pwd);
276 break;
277 #endif
278 #ifdef HAVE_LIBPAM
279 case ISAKMP_CFG_AUTH_PAM:
280 res = privsep_xauth_login_pam(iph1->mode_cfg->port,
281 iph1->remote, usr, pwd);
282 break;
283 #endif
284 default:
285 plog(LLV_ERROR, LOCATION, NULL,
286 "Unexpected authentication source\n");
287 res = -1;
288 break;
289 }
290
291 /*
292 * On failure, throttle the connexion for the remote host
293 * in order to make password attacks more difficult.
294 */
295 throttle_delay = throttle_host(iph1->remote, res) - time(NULL);
296 if (throttle_delay > 0) {
297 char *str;
298
299 str = saddrwop2str(iph1->remote);
300
301 plog(LLV_ERROR, LOCATION, NULL,
302 "Throttling in action for %s: delay %lds\n",
303 str, (unsigned long)throttle_delay);
304 res = -1;
305 } else {
306 throttle_delay = 0;
307 }
308
309 skip_auth:
310 if (throttle_delay != 0) {
311 struct xauth_reply_arg *xra;
312
313 if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
314 plog(LLV_ERROR, LOCATION, NULL,
315 "malloc failed, bypass throttling\n");
316 xauth_reply(iph1, port, id, res);
317 return;
318 }
319
320 /*
321 * We need to store the ph1, but it might have
322 * disapeared when xauth_reply is called, so
323 * store the index instead.
324 */
325 xra->index = iph1->index;
326 xra->port = port;
327 xra->id = id;
328 xra->res = res;
329 sched_new(throttle_delay, xauth_reply_stub, xra);
330 } else {
331 xauth_reply(iph1, port, id, res);
332 }
333 }
334
335 return;
336 }
337
338 void
339 xauth_reply_stub(args)
340 void *args;
341 {
342 struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
343 struct ph1handle *iph1;
344
345 if ((iph1 = getph1byindex(&xra->index)) != NULL)
346 xauth_reply(iph1, xra->port, xra->id, xra->res);
347 else
348 plog(LLV_ERROR, LOCATION, NULL,
349 "Delayed Xauth reply: phase 1 no longer exists.\n");
350
351 racoon_free(xra);
352 return;
353 }
354
355 void
356 xauth_reply(iph1, port, id, res)
357 struct ph1handle *iph1;
358 int port;
359 int id;
360 {
361 struct xauth_state *xst = &iph1->mode_cfg->xauth;
362 char *usr = xst->authdata.generic.usr;
363
364 if (res != 0) {
365 if (port != -1)
366 isakmp_cfg_putport(iph1, port);
367
368 plog(LLV_INFO, LOCATION, NULL,
369 "login failed for user \"%s\"\n", usr);
370
371 xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
372 xst->status = XAUTHST_NOTYET;
373
374 /* Delete Phase 1 SA */
375 if (iph1->status == PHASE1ST_ESTABLISHED)
376 isakmp_info_send_d1(iph1);
377 remph1(iph1);
378 delph1(iph1);
379
380 return;
381 }
382
383 xst->status = XAUTHST_OK;
384 plog(LLV_INFO, LOCATION, NULL,
385 "login succeeded for user \"%s\"\n", usr);
386
387 xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
388
389 return;
390 }
391
392 void
393 xauth_sendstatus(iph1, status, id)
394 struct ph1handle *iph1;
395 int status;
396 int id;
397 {
398 vchar_t *buffer;
399 struct isakmp_pl_attr *attr;
400 struct isakmp_data *stattr;
401 size_t tlen;
402
403 tlen = sizeof(*attr) +
404 + sizeof(*stattr);
405
406 if ((buffer = vmalloc(tlen)) == NULL) {
407 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
408 return;
409 }
410
411 attr = (struct isakmp_pl_attr *)buffer->v;
412 memset(attr, 0, tlen);
413
414 attr->h.len = htons(tlen);
415 attr->type = ISAKMP_CFG_SET;
416 attr->id = htons(id);
417
418 stattr = (struct isakmp_data *)(attr + 1);
419 stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV);
420 stattr->lorv = htons(status);
421
422 isakmp_cfg_send(iph1, buffer,
423 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
424
425 vfree(buffer);
426
427 return;
428 }
429
430 #ifdef HAVE_LIBRADIUS
431 int
432 xauth_radius_init(void)
433 {
434 /* For first time use, initialize Radius */
435 if ((isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_RADIUS) &&
436 (radius_auth_state == NULL)) {
437 if ((radius_auth_state = rad_auth_open()) == NULL) {
438 plog(LLV_ERROR, LOCATION, NULL,
439 "Cannot init libradius\n");
440 return -1;
441 }
442
443 if (rad_config(radius_auth_state, NULL) != 0) {
444 plog(LLV_ERROR, LOCATION, NULL,
445 "Cannot open librarius config file: %s\n",
446 rad_strerror(radius_auth_state));
447 rad_close(radius_auth_state);
448 radius_auth_state = NULL;
449 return -1;
450 }
451 }
452
453 if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) &&
454 (radius_acct_state == NULL)) {
455 if ((radius_acct_state = rad_auth_open()) == NULL) {
456 plog(LLV_ERROR, LOCATION, NULL,
457 "Cannot init libradius\n");
458 return -1;
459 }
460
461 if (rad_config(radius_acct_state, NULL) != 0) {
462 plog(LLV_ERROR, LOCATION, NULL,
463 "Cannot open librarius config file: %s\n",
464 rad_strerror(radius_acct_state));
465 rad_close(radius_acct_state);
466 radius_acct_state = NULL;
467 return -1;
468 }
469 }
470
471 return 0;
472 }
473
474 int
475 xauth_login_radius(iph1, usr, pwd)
476 struct ph1handle *iph1;
477 char *usr;
478 char *pwd;
479 {
480 int res;
481 const void *data;
482 size_t len;
483 int type;
484
485 if (rad_create_request(radius_auth_state, RAD_ACCESS_REQUEST) != 0) {
486 plog(LLV_ERROR, LOCATION, NULL,
487 "rad_create_request failed: %s\n",
488 rad_strerror(radius_auth_state));
489 return -1;
490 }
491
492 if (rad_put_string(radius_auth_state, RAD_USER_NAME, usr) != 0) {
493 plog(LLV_ERROR, LOCATION, NULL,
494 "rad_put_string failed: %s\n",
495 rad_strerror(radius_auth_state));
496 return -1;
497 }
498
499 if (rad_put_string(radius_auth_state, RAD_USER_PASSWORD, pwd) != 0) {
500 plog(LLV_ERROR, LOCATION, NULL,
501 "rad_put_string failed: %s\n",
502 rad_strerror(radius_auth_state));
503 return -1;
504 }
505
506 if (isakmp_cfg_radius_common(radius_auth_state, iph1->mode_cfg->port) != 0)
507 return -1;
508
509 switch (res = rad_send_request(radius_auth_state)) {
510 case RAD_ACCESS_ACCEPT:
511 while ((type = rad_get_attr(radius_auth_state, &data, &len)) != 0) {
512 switch (type) {
513 case RAD_FRAMED_IP_ADDRESS:
514 iph1->mode_cfg->addr4 = rad_cvt_addr(data);
515 iph1->mode_cfg->flags
516 |= ISAKMP_CFG_ADDR4_RADIUS;
517 break;
518
519 case RAD_FRAMED_IP_NETMASK:
520 iph1->mode_cfg->mask4 = rad_cvt_addr(data);
521 iph1->mode_cfg->flags
522 |= ISAKMP_CFG_MASK4_RADIUS;
523 break;
524
525 default:
526 plog(LLV_INFO, LOCATION, NULL,
527 "Unexpected attribute: %d\n", type);
528 break;
529 }
530 }
531
532 return 0;
533 break;
534
535 case RAD_ACCESS_REJECT:
536 return -1;
537 break;
538
539 case -1:
540 plog(LLV_ERROR, LOCATION, NULL,
541 "rad_send_request failed: %s\n",
542 rad_strerror(radius_auth_state));
543 return -1;
544 break;
545 default:
546 plog(LLV_ERROR, LOCATION, NULL,
547 "rad_send_request returned %d\n", res);
548 return -1;
549 break;
550 }
551
552 return -1;
553 }
554 #endif
555
556 #ifdef HAVE_LIBPAM
557 static int
558 PAM_conv(msg_count, msg, rsp, dontcare)
559 int msg_count;
560 const struct pam_message **msg;
561 struct pam_response **rsp;
562 void *dontcare;
563 {
564 int i;
565 int replies = 0;
566 struct pam_response *reply = NULL;
567
568 if ((reply = racoon_malloc(sizeof(*reply) * msg_count)) == NULL)
569 return PAM_CONV_ERR;
570 bzero(reply, sizeof(*reply) * msg_count);
571
572 for (i = 0; i < msg_count; i++) {
573 switch (msg[i]->msg_style) {
574 case PAM_PROMPT_ECHO_ON:
575 /* Send the username, libpam frees resp */
576 reply[i].resp_retcode = PAM_SUCCESS;
577 reply[i].resp = strdup(PAM_usr);
578 break;
579
580 case PAM_PROMPT_ECHO_OFF:
581 /* Send the password, libpam frees resp */
582 reply[i].resp_retcode = PAM_SUCCESS;
583 reply[i].resp = strdup(PAM_pwd);
584 break;
585
586 case PAM_TEXT_INFO:
587 case PAM_ERROR_MSG:
588 reply[i].resp_retcode = PAM_SUCCESS;
589 reply[i].resp = NULL;
590 break;
591
592 default:
593 if (reply != NULL)
594 racoon_free(reply);
595 return PAM_CONV_ERR;
596 break;
597 }
598 }
599
600 if (reply != NULL)
601 *rsp = reply;
602
603 return PAM_SUCCESS;
604 }
605
606 int
607 xauth_login_pam(port, raddr, usr, pwd)
608 int port;
609 struct sockaddr *raddr;
610 char *usr;
611 char *pwd;
612 {
613 int error;
614 int res;
615 const void *data;
616 size_t len;
617 int type;
618 char *remote;
619 pam_handle_t *pam = NULL;
620
621 if (isakmp_cfg_config.port_pool == NULL) {
622 plog(LLV_ERROR, LOCATION, NULL,
623 "isakmp_cfg_config.port_pool == NULL\n");
624 return -1;
625 }
626
627 if ((error = pam_start("racoon", usr,
628 &PAM_chat, &isakmp_cfg_config.port_pool[port].pam)) != 0) {
629 if (isakmp_cfg_config.port_pool[port].pam == NULL) {
630 plog(LLV_ERROR, LOCATION, NULL, "pam_start failed\n");
631 return -1;
632 } else {
633 plog(LLV_ERROR, LOCATION, NULL,
634 "pam_start failed: %s\n",
635 pam_strerror(isakmp_cfg_config.port_pool[port].pam,
636 error));
637 goto out;
638 }
639 }
640 pam = isakmp_cfg_config.port_pool[port].pam;
641
642 if ((remote = strdup(saddrwop2str(raddr))) == NULL) {
643 plog(LLV_ERROR, LOCATION, NULL,
644 "cannot allocate memory: %s\n", strerror(errno));
645 goto out;
646 }
647
648 if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) {
649 plog(LLV_ERROR, LOCATION, NULL,
650 "pam_set_item failed: %s\n",
651 pam_strerror(pam, error));
652 goto out;
653 }
654
655 PAM_usr = usr;
656 PAM_pwd = pwd;
657 error = pam_authenticate(pam, 0);
658 PAM_usr = NULL;
659 PAM_pwd = NULL;
660 if (error != 0) {
661 plog(LLV_ERROR, LOCATION, NULL,
662 "pam_authenticate failed: %s\n",
663 pam_strerror(pam, error));
664 goto out;
665 }
666
667 if ((error = pam_acct_mgmt(pam, 0)) != 0) {
668 plog(LLV_ERROR, LOCATION, NULL,
669 "pam_acct_mgmt failed: %s\n",
670 pam_strerror(pam, error));
671 goto out;
672 }
673
674 if ((error = pam_setcred(pam, 0)) != 0) {
675 plog(LLV_ERROR, LOCATION, NULL,
676 "pam_setcred failed: %s\n",
677 pam_strerror(pam, error));
678 goto out;
679 }
680
681 return 0;
682
683 out:
684 pam_end(pam, error);
685 isakmp_cfg_config.port_pool[port].pam = NULL;
686 return -1;
687 }
688 #endif
689
690 int
691 xauth_login_system(usr, pwd)
692 char *usr;
693 char *pwd;
694 {
695 struct passwd *pw;
696 char *cryptpwd;
697 char *syscryptpwd;
698 #ifdef HAVE_SHADOW_H
699 struct spwd *spw;
700
701 if ((spw = getspnam(usr)) == NULL)
702 return -1;
703
704 syscryptpwd = spw->sp_pwdp;
705 #endif
706
707 if ((pw = getpwnam(usr)) == NULL)
708 return -1;
709
710 #ifndef HAVE_SHADOW_H
711 syscryptpwd = pw->pw_passwd;
712 #endif
713
714 /* No root login. Ever. */
715 if (pw->pw_uid == 0)
716 return -1;
717
718 if ((cryptpwd = crypt(pwd, syscryptpwd)) == NULL)
719 return -1;
720
721 if (strcmp(cryptpwd, syscryptpwd) == 0)
722 return 0;
723
724 return -1;
725 }
726
727 int
728 xauth_check(iph1)
729 struct ph1handle *iph1;
730 {
731 struct xauth_state *xst = &iph1->mode_cfg->xauth;
732
733 /* If we don't use Xauth, then we pass */
734 switch (iph1->approval->authmethod) {
735 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
736 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
737 /* The following are not yet implemented */
738 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
739 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
740 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
741 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
742 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
743 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
744 plog(LLV_ERROR, LOCATION, NULL,
745 "Hybrid auth negotiated but peer did not "
746 "announced as Xauth capable\n");
747 return -1;
748 }
749
750 if (xst->status != XAUTHST_OK) {
751 plog(LLV_ERROR, LOCATION, NULL,
752 "Hybrid auth negotiated but peer did not "
753 "succeed Xauth exchange\n");
754 return -1;
755 }
756
757 return 0;
758 break;
759 default:
760 return 0;
761 break;
762 }
763
764 return 0;
765 }
766
767 vchar_t *
768 isakmp_xauth_req(iph1, attr)
769 struct ph1handle *iph1;
770 struct isakmp_data *attr;
771 {
772 int type;
773 size_t dlen = 0;
774 int ashort = 0;
775 int value = 0;
776 vchar_t *buffer = NULL;
777 char *data;
778 vchar_t *usr = NULL;
779 vchar_t *pwd = NULL;
780 size_t skip = 0;
781 int freepwd = 0;
782
783 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
784 plog(LLV_ERROR, LOCATION, NULL,
785 "Xauth mode config request but peer "
786 "did not declare itself as Xauth capable\n");
787 return NULL;
788 }
789
790 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
791
792 /* Sanity checks */
793 switch(type) {
794 case XAUTH_TYPE:
795 if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
796 plog(LLV_ERROR, LOCATION, NULL,
797 "Unexpected long XAUTH_TYPE attribute\n");
798 return NULL;
799 }
800 if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
801 plog(LLV_ERROR, LOCATION, NULL,
802 "Unsupported Xauth authentication %d\n",
803 ntohs(attr->lorv));
804 return NULL;
805 }
806 ashort = 1;
807 dlen = 0;
808 value = XAUTH_TYPE_GENERIC;
809 break;
810
811 case XAUTH_USER_NAME:
812 if (iph1->rmconf->idvtype != IDTYPE_LOGIN) {
813 plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
814 "while identifier is not a login\n");
815 return NULL;
816 }
817
818 if (iph1->rmconf->idv == NULL) {
819 plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
820 "with no login supplied\n");
821 return NULL;
822 }
823
824 dlen = iph1->rmconf->idv->l;
825 break;
826
827 case XAUTH_USER_PASSWORD:
828 if (iph1->rmconf->idvtype != IDTYPE_LOGIN)
829 return NULL;
830
831 if (iph1->rmconf->idv == NULL)
832 return NULL;
833
834 skip = sizeof(struct ipsecdoi_id_b);
835 if ((usr = vmalloc(iph1->rmconf->idv->l + skip)) == NULL) {
836 plog(LLV_ERROR, LOCATION, NULL,
837 "Cannot allocate memory\n");
838 return NULL;
839 }
840
841 memset(usr->v, 0, skip);
842 memcpy(usr->v + skip,
843 iph1->rmconf->idv->v,
844 iph1->rmconf->idv->l);
845
846 if (iph1->rmconf->key) {
847 /* A key given through racoonctl */
848 pwd = iph1->rmconf->key;
849 } else {
850 if ((pwd = getpskbyname(usr)) == NULL) {
851 plog(LLV_ERROR, LOCATION, NULL,
852 "No password was found for login %s\n",
853 iph1->rmconf->idv->v);
854 vfree(usr);
855 return NULL;
856 }
857 /* We have to free it before returning */
858 freepwd = 1;
859 }
860 vfree(usr);
861
862 dlen = pwd->l;
863
864 break;
865
866 default:
867 plog(LLV_WARNING, LOCATION, NULL,
868 "Ignored attribute %d\n", type);
869 return NULL;
870 break;
871 }
872
873 if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
874 plog(LLV_ERROR, LOCATION, NULL,
875 "Cannot allocate memory\n");
876 goto out;
877 }
878
879 attr = (struct isakmp_data *)buffer->v;
880 if (ashort) {
881 attr->type = htons(type | ISAKMP_GEN_TV);
882 attr->lorv = htons(value);
883 goto out;
884 }
885
886 attr->type = htons(type | ISAKMP_GEN_TLV);
887 attr->lorv = htons(dlen);
888 data = (char *)(attr + 1);
889
890 switch(type) {
891 case XAUTH_USER_NAME:
892 memcpy(data, iph1->rmconf->idv->v, dlen);
893 break;
894 case XAUTH_USER_PASSWORD:
895 memcpy(data, pwd->v, dlen);
896 break;
897 default:
898 break;
899 }
900
901 out:
902 if (freepwd)
903 vfree(pwd);
904
905 return buffer;
906 }
907
908 vchar_t *
909 isakmp_xauth_set(iph1, attr)
910 struct ph1handle *iph1;
911 struct isakmp_data *attr;
912 {
913 int type;
914 vchar_t *buffer = NULL;
915 char *data;
916
917 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
918 plog(LLV_ERROR, LOCATION, NULL,
919 "Xauth mode config set but peer "
920 "did not declare itself as Xauth capable\n");
921 return NULL;
922 }
923
924 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
925
926 switch(type) {
927 case XAUTH_STATUS:
928 /* If we got a failure, delete iph1 */
929 if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
930 plog(LLV_ERROR, LOCATION, NULL,
931 "Xauth authentication failed\n");
932
933 EVT_PUSH(iph1->local, iph1->remote,
934 EVTT_XAUTH_FAILED, NULL);
935
936 iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
937 } else {
938 EVT_PUSH(iph1->local,
939 iph1->remote, EVTT_XAUTH_SUCCESS, NULL);
940 }
941
942
943 /* We acknowledge it */
944 break;
945 default:
946 plog(LLV_WARNING, LOCATION, NULL,
947 "Ignored attribute %d\n", type);
948 return NULL;
949 break;
950 }
951
952 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
953 plog(LLV_ERROR, LOCATION, NULL,
954 "Cannot allocate memory\n");
955 return NULL;
956 }
957
958 attr = (struct isakmp_data *)buffer->v;
959 attr->type = htons(type | ISAKMP_GEN_TV);
960 attr->lorv = htons(0);
961
962 return buffer;
963 }
964
965
966 void
967 xauth_rmstate(xst)
968 struct xauth_state *xst;
969 {
970 switch (xst->authtype) {
971 case XAUTH_TYPE_GENERIC:
972 if (xst->authdata.generic.usr)
973 racoon_free(xst->authdata.generic.usr);
974
975 if (xst->authdata.generic.pwd)
976 racoon_free(xst->authdata.generic.pwd);
977
978 break;
979
980 case XAUTH_TYPE_CHAP:
981 case XAUTH_TYPE_OTP:
982 case XAUTH_TYPE_SKEY:
983 plog(LLV_WARNING, LOCATION, NULL,
984 "Unsupported authtype %d\n", xst->authtype);
985 break;
986
987 default:
988 plog(LLV_WARNING, LOCATION, NULL,
989 "Unexpected authtype %d\n", xst->authtype);
990 break;
991 }
992
993 return;
994 }
995