1 /* $Id: isakmp_xauth.c,v 1.14 2004/11/30 00:46:09 manubsd Exp $ */
4 * Copyright (C) 2004 Emmanuel Dreyfus
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37 #include <sys/queue.h>
39 #include <netinet/in.h>
46 #if TIME_WITH_SYS_TIME
47 # include <sys/time.h>
51 # include <sys/time.h>
70 #include "crypto_openssl.h"
71 #include "isakmp_var.h"
76 #include "remoteconf.h"
77 #include "isakmp_inf.h"
78 #include "isakmp_xauth.h"
79 #include "isakmp_unity.h"
80 #include "isakmp_cfg.h"
82 #include "ipsec_doi.h"
83 #include "remoteconf.h"
84 #include "localconf.h"
92 struct ph1handle *iph1;
95 struct isakmp_pl_attr *attr;
96 struct isakmp_data *typeattr;
97 struct isakmp_data *usrattr;
98 struct isakmp_data *pwdattr;
99 struct xauth_state *xst = &iph1->mode_cfg->xauth;
103 if (iph1->status != PHASE1ST_ESTABLISHED) {
104 plog(LLV_ERROR, LOCATION, NULL,
105 "Xauth request while phase 1 is not completed\n");
109 if (xst->status != XAUTHST_NOTYET) {
110 plog(LLV_ERROR, LOCATION, NULL,
111 "Xauth request whith Xauth state %d\n", xst->status);
115 plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n");
117 tlen = sizeof(*attr) +
118 + sizeof(*typeattr) +
122 if ((buffer = vmalloc(tlen)) == NULL) {
123 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
127 attr = (struct isakmp_pl_attr *)buffer->v;
128 memset(attr, 0, tlen);
130 attr->h.len = htons(tlen);
131 attr->type = ISAKMP_CFG_REQUEST;
132 attr->id = htons(eay_random());
134 typeattr = (struct isakmp_data *)(attr + 1);
135 typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV);
136 typeattr->lorv = htons(XAUTH_TYPE_GENERIC);
138 usrattr = (struct isakmp_data *)(typeattr + 1);
139 usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV);
140 usrattr->lorv = htons(0);
142 pwdattr = (struct isakmp_data *)(usrattr + 1);
143 pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV);
144 pwdattr->lorv = htons(0);
146 isakmp_cfg_send(iph1, buffer,
147 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
151 xst->status = XAUTHST_REQSENT;
157 xauth_attr_reply(iph1, attr, id)
158 struct ph1handle *iph1;
159 struct isakmp_data *attr;
162 char **outlet = NULL;
165 struct xauth_state *xst = &iph1->mode_cfg->xauth;
167 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
168 plog(LLV_ERROR, LOCATION, NULL,
169 "Xauth reply but peer did not declare "
170 "itself as Xauth capable\n");
174 if (xst->status != XAUTHST_REQSENT) {
175 plog(LLV_ERROR, LOCATION, NULL,
176 "Xauth reply while Xauth state is %d\n", xst->status);
180 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
183 switch (ntohs(attr->lorv)) {
184 case XAUTH_TYPE_GENERIC:
185 xst->authtype = XAUTH_TYPE_GENERIC;
188 plog(LLV_WARNING, LOCATION, NULL,
189 "Unexpected authentication type %d\n",
195 case XAUTH_USER_NAME:
196 outlet = &xst->authdata.generic.usr;
199 case XAUTH_USER_PASSWORD:
200 outlet = &xst->authdata.generic.pwd;
204 plog(LLV_WARNING, LOCATION, NULL,
205 "ignored Xauth attribute %d\n", type);
209 if (outlet != NULL) {
210 alen = ntohs(attr->lorv);
212 if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
213 plog(LLV_ERROR, LOCATION, NULL,
214 "Cannot allocate memory for Xauth Data\n");
218 memcpy(*outlet, attr + 1, alen);
219 (*outlet)[alen] = '\0';
224 if ((xst->authdata.generic.usr != NULL) &&
225 (xst->authdata.generic.pwd != NULL)) {
228 char *usr = xst->authdata.generic.usr;
229 char *pwd = xst->authdata.generic.pwd;
230 time_t throttle_delay = 0;
232 #if 0 /* Real debug, don't do that at home */
233 plog(LLV_DEBUG, LOCATION, NULL,
234 "Got username \"%s\", password \"%s\"\n", usr, pwd);
236 strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
237 iph1->mode_cfg->login[LOGINLEN] = '\0';
240 if ((port = isakmp_cfg_getport(iph1)) == -1) {
241 plog(LLV_ERROR, LOCATION, NULL,
242 "Port pool depleted\n");
246 switch (isakmp_cfg_config.authsource) {
247 case ISAKMP_CFG_AUTH_SYSTEM:
248 res = xauth_login_system(iph1, usr, pwd);
250 #ifdef HAVE_LIBRADIUS
251 case ISAKMP_CFG_AUTH_RADIUS:
252 res = xauth_login_radius(iph1, usr, pwd);
256 plog(LLV_ERROR, LOCATION, NULL,
257 "Unexpected authentication source\n");
263 * On failure, throttle the connexion for the remote host
264 * in order to make password attacks more difficult.
266 throttle_delay = throttle_host(iph1->remote, res) - time(NULL);
267 if (throttle_delay > 0) {
270 str = saddrwop2str(iph1->remote);
272 plog(LLV_ERROR, LOCATION, NULL,
273 "Throttling in action for %s: delay %lds\n",
274 str, (unsigned long)throttle_delay);
281 if (throttle_delay != 0) {
282 struct xauth_reply_arg *xra;
284 if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
285 plog(LLV_ERROR, LOCATION, NULL,
286 "malloc failed, bypass throttling\n");
287 xauth_reply(iph1, port, id, res);
292 * We need to store the ph1, but it might have
293 * disapeared when xauth_reply is called, so
294 * store the index instead.
296 xra->index = iph1->index;
300 sched_new(throttle_delay, xauth_reply_stub, xra);
302 xauth_reply(iph1, port, id, res);
310 xauth_reply_stub(args)
313 struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
314 struct ph1handle *iph1;
316 if ((iph1 = getph1byindex(&xra->index)) != NULL)
317 xauth_reply(iph1, xra->port, xra->id, xra->res);
319 plog(LLV_ERROR, LOCATION, NULL,
320 "Delayed Xauth reply: phase 1 no longer exists.\n");
327 xauth_reply(iph1, port, id, res)
328 struct ph1handle *iph1;
332 struct xauth_state *xst = &iph1->mode_cfg->xauth;
333 char *usr = xst->authdata.generic.usr;
337 isakmp_cfg_putport(iph1, port);
339 plog(LLV_INFO, LOCATION, NULL,
340 "login failed for user \"%s\"\n", usr);
342 xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
343 xst->status = XAUTHST_NOTYET;
345 /* Delete Phase 1 SA */
346 if (iph1->status == PHASE1ST_ESTABLISHED)
347 isakmp_info_send_d1(iph1);
354 xst->status = XAUTHST_OK;
355 plog(LLV_INFO, LOCATION, NULL,
356 "login succeeded for user \"%s\"\n", usr);
358 xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
364 xauth_sendstatus(iph1, status, id)
365 struct ph1handle *iph1;
370 struct isakmp_pl_attr *attr;
371 struct isakmp_data *stattr;
374 tlen = sizeof(*attr) +
377 if ((buffer = vmalloc(tlen)) == NULL) {
378 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
382 attr = (struct isakmp_pl_attr *)buffer->v;
383 memset(attr, 0, tlen);
385 attr->h.len = htons(tlen);
386 attr->type = ISAKMP_CFG_SET;
387 attr->id = htons(id);
389 stattr = (struct isakmp_data *)(attr + 1);
390 stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV);
391 stattr->lorv = htons(status);
393 isakmp_cfg_send(iph1, buffer,
394 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
401 #ifdef HAVE_LIBRADIUS
403 xauth_login_radius(iph1, usr, pwd)
404 struct ph1handle *iph1;
408 static struct rad_handle *radius_state = NULL;
414 /* For first time use, initialize Radius */
415 if (radius_state == NULL) {
416 if ((radius_state = rad_auth_open()) == NULL) {
417 plog(LLV_ERROR, LOCATION, NULL,
418 "Cannot init librradius\n");
422 if (rad_config(radius_state, NULL) != 0) {
423 plog(LLV_ERROR, LOCATION, NULL,
424 "Cannot open librarius config file: %s\n",
425 rad_strerror(radius_state));
426 rad_close(radius_state);
432 if (rad_create_request(radius_state, RAD_ACCESS_REQUEST) != 0) {
433 plog(LLV_ERROR, LOCATION, NULL,
434 "rad_create_request failed: %s\n",
435 rad_strerror(radius_state));
439 if (rad_put_string(radius_state, RAD_USER_NAME, usr) != 0) {
440 plog(LLV_ERROR, LOCATION, NULL,
441 "rad_put_string failed: %s\n",
442 rad_strerror(radius_state));
446 if (rad_put_string(radius_state, RAD_USER_PASSWORD, pwd) != 0) {
447 plog(LLV_ERROR, LOCATION, NULL,
448 "rad_put_string failed: %s\n",
449 rad_strerror(radius_state));
453 if (isakmp_cfg_radius_common(radius_state, iph1->mode_cfg->port) != 0)
456 switch (res = rad_send_request(radius_state)) {
457 case RAD_ACCESS_ACCEPT:
458 while ((type = rad_get_attr(radius_state, &data, &len)) != 0) {
460 case RAD_FRAMED_IP_ADDRESS:
461 iph1->mode_cfg->addr4 = rad_cvt_addr(data);
462 iph1->mode_cfg->flags
463 |= ISAKMP_CFG_ADDR4_RADIUS;
466 case RAD_FRAMED_IP_NETMASK:
467 iph1->mode_cfg->mask4 = rad_cvt_addr(data);
468 iph1->mode_cfg->flags
469 |= ISAKMP_CFG_MASK4_RADIUS;
473 plog(LLV_INFO, LOCATION, NULL,
474 "Unexpected attribute: %d\n", type);
482 case RAD_ACCESS_REJECT:
487 plog(LLV_ERROR, LOCATION, NULL,
488 "rad_send_request failed: %s\n",
489 rad_strerror(radius_state));
493 plog(LLV_ERROR, LOCATION, NULL,
494 "rad_send_request returned %d\n", res);
504 xauth_login_system(iph1, usr, pwd)
505 struct ph1handle *iph1;
512 if ((pw = getpwnam(usr)) == NULL)
515 /* No root login. Ever. */
519 if ((cryptpwd = crypt(pwd, pw->pw_passwd)) == NULL)
522 if (strcmp(cryptpwd, pw->pw_passwd) == 0)
530 struct ph1handle *iph1;
532 struct xauth_state *xst = &iph1->mode_cfg->xauth;
534 /* If we don't use Xauth, then we pass */
535 switch (iph1->approval->authmethod) {
536 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
537 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
538 /* The following are not yet implemented */
539 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
540 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
541 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
542 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
543 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
544 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
545 plog(LLV_ERROR, LOCATION, NULL,
546 "Hybrid auth negotiated but peer did not "
547 "announced as Xauth capable\n");
551 if (xst->status != XAUTHST_OK) {
552 plog(LLV_ERROR, LOCATION, NULL,
553 "Hybrid auth negotiated but peer did not "
554 "succeed Xauth exchange\n");
569 isakmp_xauth_req(iph1, attr)
570 struct ph1handle *iph1;
571 struct isakmp_data *attr;
577 vchar_t *buffer = NULL;
584 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
585 plog(LLV_ERROR, LOCATION, NULL,
586 "Xauth mode config request but peer "
587 "did not declare itself as Xauth capable\n");
591 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
596 if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
597 plog(LLV_ERROR, LOCATION, NULL,
598 "Unexpected long XAUTH_TYPE attribute\n");
601 if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
602 plog(LLV_ERROR, LOCATION, NULL,
603 "Unsupported Xauth authentication %d\n",
609 value = XAUTH_TYPE_GENERIC;
612 case XAUTH_USER_NAME:
613 if (iph1->rmconf->idvtype != IDTYPE_LOGIN) {
614 plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
615 "while identifier is not a login\n");
619 if (iph1->rmconf->idv == NULL) {
620 plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
621 "with no login supplied\n");
625 dlen = iph1->rmconf->idv->l;
628 case XAUTH_USER_PASSWORD:
629 if (iph1->rmconf->idvtype != IDTYPE_LOGIN)
632 if (iph1->rmconf->idv == NULL)
635 skip = sizeof(struct ipsecdoi_id_b);
636 if ((usr = vmalloc(iph1->rmconf->idv->l + skip)) == NULL) {
637 plog(LLV_ERROR, LOCATION, NULL,
638 "Cannot allocate memory\n");
642 memset(usr->v, 0, skip);
643 memcpy(usr->v + skip,
644 iph1->rmconf->idv->v,
645 iph1->rmconf->idv->l);
647 if (iph1->rmconf->key) {
648 /* A key given through racoonctl */
649 pwd = iph1->rmconf->key;
651 if ((pwd = getpskbyname(usr)) == NULL) {
652 plog(LLV_ERROR, LOCATION, NULL,
653 "No password was found for login %s\n",
654 iph1->rmconf->idv->v);
658 /* We have to free it before returning */
668 plog(LLV_WARNING, LOCATION, NULL,
669 "Ignored attribute %d\n", type);
674 if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
675 plog(LLV_ERROR, LOCATION, NULL,
676 "Cannot allocate memory\n");
680 attr = (struct isakmp_data *)buffer->v;
682 attr->type = htons(type | ISAKMP_GEN_TV);
683 attr->lorv = htons(value);
687 attr->type = htons(type | ISAKMP_GEN_TLV);
688 attr->lorv = htons(dlen);
689 data = (char *)(attr + 1);
692 case XAUTH_USER_NAME:
693 memcpy(data, iph1->rmconf->idv->v, dlen);
695 case XAUTH_USER_PASSWORD:
696 memcpy(data, pwd->v, dlen);
710 isakmp_xauth_set(iph1, attr)
711 struct ph1handle *iph1;
712 struct isakmp_data *attr;
715 vchar_t *buffer = NULL;
718 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
719 plog(LLV_ERROR, LOCATION, NULL,
720 "Xauth mode config set but peer "
721 "did not declare itself as Xauth capable\n");
725 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
729 /* If we got a failure, delete iph1 */
730 if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
731 plog(LLV_ERROR, LOCATION, NULL,
732 "Xauth authentication failed\n");
734 EVT_PUSH(iph1->local, iph1->remote,
735 EVTT_XAUTH_FAILED, NULL);
737 iph1->mode_cfg->flags &= ISAKMP_CFG_DELETE_PH1;
739 EVT_PUSH(iph1->local,
740 iph1->remote, EVTT_XAUTH_SUCCESS, NULL);
744 /* We acknowledge it */
747 plog(LLV_WARNING, LOCATION, NULL,
748 "Ignored attribute %d\n", type);
753 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
754 plog(LLV_ERROR, LOCATION, NULL,
755 "Cannot allocate memory\n");
759 attr = (struct isakmp_data *)buffer->v;
760 attr->type = htons(type | ISAKMP_GEN_TV);
761 attr->lorv = htons(0);
769 struct xauth_state *xst;
771 switch (xst->authtype) {
772 case XAUTH_TYPE_GENERIC:
773 if (xst->authdata.generic.usr)
774 racoon_free(xst->authdata.generic.usr);
776 if (xst->authdata.generic.pwd)
777 racoon_free(xst->authdata.generic.pwd);
781 case XAUTH_TYPE_CHAP:
783 case XAUTH_TYPE_SKEY:
784 plog(LLV_WARNING, LOCATION, NULL,
785 "Unsupported authtype %d\n", xst->authtype);
789 plog(LLV_WARNING, LOCATION, NULL,
790 "Unexpected authtype %d\n", xst->authtype);