Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_xauth.c, revision 1.1
1.1 ! misho 1: /* $NetBSD: isakmp_xauth.c,v 1.22 2011/03/14 15:50:36 vanhu Exp $ */
! 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: }
! 464: if (radius_auth_state != NULL)
! 465: rad_close(radius_auth_state);
! 466: if (radius_acct_state != NULL)
! 467: rad_close(radius_acct_state);
! 468: }
! 469:
! 470: /* initialize radius config */
! 471: memset(&xauth_rad_config, 0, sizeof(xauth_rad_config));
! 472: return 0;
! 473: }
! 474:
! 475: int
! 476: xauth_radius_init(void)
! 477: {
! 478: /* For first time use, initialize Radius */
! 479: if ((isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_RADIUS) &&
! 480: (radius_auth_state == NULL)) {
! 481: if ((radius_auth_state = rad_auth_open()) == NULL) {
! 482: plog(LLV_ERROR, LOCATION, NULL,
! 483: "Cannot init libradius\n");
! 484: return -1;
! 485: }
! 486:
! 487: int auth_count = xauth_rad_config.auth_server_count;
! 488: int auth_added = 0;
! 489: if (auth_count) {
! 490: int i;
! 491: for (i = 0; i < auth_count; i++) {
! 492: if(!rad_add_server(
! 493: radius_auth_state,
! 494: xauth_rad_config.auth_server_list[i].host->v,
! 495: xauth_rad_config.auth_server_list[i].port,
! 496: xauth_rad_config.auth_server_list[i].secret->v,
! 497: xauth_rad_config.timeout,
! 498: xauth_rad_config.retries ))
! 499: auth_added++;
! 500: else
! 501: plog(LLV_WARNING, LOCATION, NULL,
! 502: "could not add radius auth server %s\n",
! 503: xauth_rad_config.auth_server_list[i].host->v);
! 504: }
! 505: }
! 506:
! 507: if (!auth_added) {
! 508: if (rad_config(radius_auth_state, NULL) != 0) {
! 509: plog(LLV_ERROR, LOCATION, NULL,
! 510: "Cannot open libradius config file: %s\n",
! 511: rad_strerror(radius_auth_state));
! 512: rad_close(radius_auth_state);
! 513: radius_auth_state = NULL;
! 514: return -1;
! 515: }
! 516: }
! 517: }
! 518:
! 519: if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) &&
! 520: (radius_acct_state == NULL)) {
! 521: if ((radius_acct_state = rad_acct_open()) == NULL) {
! 522: plog(LLV_ERROR, LOCATION, NULL,
! 523: "Cannot init libradius\n");
! 524: return -1;
! 525: }
! 526:
! 527: int acct_count = xauth_rad_config.acct_server_count;
! 528: int acct_added = 0;
! 529: if (acct_count) {
! 530: int i;
! 531: for (i = 0; i < acct_count; i++) {
! 532: if(!rad_add_server(
! 533: radius_acct_state,
! 534: xauth_rad_config.acct_server_list[i].host->v,
! 535: xauth_rad_config.acct_server_list[i].port,
! 536: xauth_rad_config.acct_server_list[i].secret->v,
! 537: xauth_rad_config.timeout,
! 538: xauth_rad_config.retries ))
! 539: acct_added++;
! 540: else
! 541: plog(LLV_WARNING, LOCATION, NULL,
! 542: "could not add radius account server %s\n",
! 543: xauth_rad_config.acct_server_list[i].host->v);
! 544: }
! 545: }
! 546:
! 547: if (!acct_added) {
! 548: if (rad_config(radius_acct_state, NULL) != 0) {
! 549: plog(LLV_ERROR, LOCATION, NULL,
! 550: "Cannot open libradius config file: %s\n",
! 551: rad_strerror(radius_acct_state));
! 552: rad_close(radius_acct_state);
! 553: radius_acct_state = NULL;
! 554: return -1;
! 555: }
! 556: }
! 557: }
! 558:
! 559: return 0;
! 560: }
! 561:
! 562: int
! 563: xauth_login_radius(iph1, usr, pwd)
! 564: struct ph1handle *iph1;
! 565: char *usr;
! 566: char *pwd;
! 567: {
! 568: int res;
! 569: const void *data;
! 570: size_t len;
! 571: int type;
! 572:
! 573: if (rad_create_request(radius_auth_state, RAD_ACCESS_REQUEST) != 0) {
! 574: plog(LLV_ERROR, LOCATION, NULL,
! 575: "rad_create_request failed: %s\n",
! 576: rad_strerror(radius_auth_state));
! 577: return -1;
! 578: }
! 579:
! 580: if (rad_put_string(radius_auth_state, RAD_USER_NAME, usr) != 0) {
! 581: plog(LLV_ERROR, LOCATION, NULL,
! 582: "rad_put_string failed: %s\n",
! 583: rad_strerror(radius_auth_state));
! 584: return -1;
! 585: }
! 586:
! 587: if (rad_put_string(radius_auth_state, RAD_USER_PASSWORD, pwd) != 0) {
! 588: plog(LLV_ERROR, LOCATION, NULL,
! 589: "rad_put_string failed: %s\n",
! 590: rad_strerror(radius_auth_state));
! 591: return -1;
! 592: }
! 593:
! 594: if (isakmp_cfg_radius_common(radius_auth_state, iph1->mode_cfg->port) != 0)
! 595: return -1;
! 596:
! 597: switch (res = rad_send_request(radius_auth_state)) {
! 598: case RAD_ACCESS_ACCEPT:
! 599: while ((type = rad_get_attr(radius_auth_state, &data, &len)) != 0) {
! 600: switch (type) {
! 601: case RAD_FRAMED_IP_ADDRESS:
! 602: iph1->mode_cfg->addr4 = rad_cvt_addr(data);
! 603: iph1->mode_cfg->flags
! 604: |= ISAKMP_CFG_ADDR4_EXTERN;
! 605: break;
! 606:
! 607: case RAD_FRAMED_IP_NETMASK:
! 608: iph1->mode_cfg->mask4 = rad_cvt_addr(data);
! 609: iph1->mode_cfg->flags
! 610: |= ISAKMP_CFG_MASK4_EXTERN;
! 611: break;
! 612:
! 613: default:
! 614: plog(LLV_INFO, LOCATION, NULL,
! 615: "Unexpected attribute: %d\n", type);
! 616: break;
! 617: }
! 618: }
! 619:
! 620: return 0;
! 621: break;
! 622:
! 623: case RAD_ACCESS_REJECT:
! 624: return -1;
! 625: break;
! 626:
! 627: case -1:
! 628: plog(LLV_ERROR, LOCATION, NULL,
! 629: "rad_send_request failed: %s\n",
! 630: rad_strerror(radius_auth_state));
! 631: return -1;
! 632: break;
! 633: default:
! 634: plog(LLV_ERROR, LOCATION, NULL,
! 635: "rad_send_request returned %d\n", res);
! 636: return -1;
! 637: break;
! 638: }
! 639:
! 640: return -1;
! 641: }
! 642: #endif
! 643:
! 644: #ifdef HAVE_LIBPAM
! 645: static int
! 646: PAM_conv(msg_count, msg, rsp, dontcare)
! 647: int msg_count;
! 648: const struct pam_message **msg;
! 649: struct pam_response **rsp;
! 650: void *dontcare;
! 651: {
! 652: int i;
! 653: int replies = 0;
! 654: struct pam_response *reply = NULL;
! 655:
! 656: if ((reply = racoon_malloc(sizeof(*reply) * msg_count)) == NULL)
! 657: return PAM_CONV_ERR;
! 658: bzero(reply, sizeof(*reply) * msg_count);
! 659:
! 660: for (i = 0; i < msg_count; i++) {
! 661: switch (msg[i]->msg_style) {
! 662: case PAM_PROMPT_ECHO_ON:
! 663: /* Send the username, libpam frees resp */
! 664: reply[i].resp_retcode = PAM_SUCCESS;
! 665: if ((reply[i].resp = strdup(PAM_usr)) == NULL) {
! 666: plog(LLV_ERROR, LOCATION,
! 667: NULL, "strdup failed\n");
! 668: exit(1);
! 669: }
! 670: break;
! 671:
! 672: case PAM_PROMPT_ECHO_OFF:
! 673: /* Send the password, libpam frees resp */
! 674: reply[i].resp_retcode = PAM_SUCCESS;
! 675: if ((reply[i].resp = strdup(PAM_pwd)) == NULL) {
! 676: plog(LLV_ERROR, LOCATION,
! 677: NULL, "strdup failed\n");
! 678: exit(1);
! 679: }
! 680: break;
! 681:
! 682: case PAM_TEXT_INFO:
! 683: case PAM_ERROR_MSG:
! 684: reply[i].resp_retcode = PAM_SUCCESS;
! 685: reply[i].resp = NULL;
! 686: break;
! 687:
! 688: default:
! 689: if (reply != NULL)
! 690: racoon_free(reply);
! 691: return PAM_CONV_ERR;
! 692: break;
! 693: }
! 694: }
! 695:
! 696: if (reply != NULL)
! 697: *rsp = reply;
! 698:
! 699: return PAM_SUCCESS;
! 700: }
! 701:
! 702: int
! 703: xauth_login_pam(port, raddr, usr, pwd)
! 704: int port;
! 705: struct sockaddr *raddr;
! 706: char *usr;
! 707: char *pwd;
! 708: {
! 709: int error;
! 710: int res;
! 711: const void *data;
! 712: size_t len;
! 713: int type;
! 714: char *remote = NULL;
! 715: pam_handle_t *pam = NULL;
! 716:
! 717: if (isakmp_cfg_config.port_pool == NULL) {
! 718: plog(LLV_ERROR, LOCATION, NULL,
! 719: "isakmp_cfg_config.port_pool == NULL\n");
! 720: return -1;
! 721: }
! 722:
! 723: if ((error = pam_start("racoon", usr,
! 724: &PAM_chat, &isakmp_cfg_config.port_pool[port].pam)) != 0) {
! 725: if (isakmp_cfg_config.port_pool[port].pam == NULL) {
! 726: plog(LLV_ERROR, LOCATION, NULL, "pam_start failed\n");
! 727: return -1;
! 728: } else {
! 729: plog(LLV_ERROR, LOCATION, NULL,
! 730: "pam_start failed: %s\n",
! 731: pam_strerror(isakmp_cfg_config.port_pool[port].pam,
! 732: error));
! 733: goto out;
! 734: }
! 735: }
! 736: pam = isakmp_cfg_config.port_pool[port].pam;
! 737:
! 738: if ((remote = strdup(saddrwop2str(raddr))) == NULL) {
! 739: plog(LLV_ERROR, LOCATION, NULL,
! 740: "cannot allocate memory: %s\n", strerror(errno));
! 741: goto out;
! 742: }
! 743:
! 744: if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) {
! 745: plog(LLV_ERROR, LOCATION, NULL,
! 746: "pam_set_item failed: %s\n",
! 747: pam_strerror(pam, error));
! 748: goto out;
! 749: }
! 750:
! 751: if ((error = pam_set_item(pam, PAM_RUSER, usr)) != 0) {
! 752: plog(LLV_ERROR, LOCATION, NULL,
! 753: "pam_set_item failed: %s\n",
! 754: pam_strerror(pam, error));
! 755: goto out;
! 756: }
! 757:
! 758: PAM_usr = usr;
! 759: PAM_pwd = pwd;
! 760: error = pam_authenticate(pam, 0);
! 761: PAM_usr = NULL;
! 762: PAM_pwd = NULL;
! 763: if (error != 0) {
! 764: plog(LLV_ERROR, LOCATION, NULL,
! 765: "pam_authenticate failed: %s\n",
! 766: pam_strerror(pam, error));
! 767: goto out;
! 768: }
! 769:
! 770: if ((error = pam_acct_mgmt(pam, 0)) != 0) {
! 771: plog(LLV_ERROR, LOCATION, NULL,
! 772: "pam_acct_mgmt failed: %s\n",
! 773: pam_strerror(pam, error));
! 774: goto out;
! 775: }
! 776:
! 777: if ((error = pam_setcred(pam, 0)) != 0) {
! 778: plog(LLV_ERROR, LOCATION, NULL,
! 779: "pam_setcred failed: %s\n",
! 780: pam_strerror(pam, error));
! 781: goto out;
! 782: }
! 783:
! 784: if (remote != NULL)
! 785: free(remote);
! 786:
! 787: return 0;
! 788:
! 789: out:
! 790: pam_end(pam, error);
! 791: isakmp_cfg_config.port_pool[port].pam = NULL;
! 792: if (remote != NULL)
! 793: free(remote);
! 794: return -1;
! 795: }
! 796: #endif
! 797:
! 798: #ifdef HAVE_LIBLDAP
! 799: int
! 800: xauth_ldap_init_conf(void)
! 801: {
! 802: int tmplen;
! 803: int error = -1;
! 804:
! 805: xauth_ldap_config.pver = 3;
! 806: xauth_ldap_config.host = NULL;
! 807: xauth_ldap_config.port = LDAP_PORT;
! 808: xauth_ldap_config.base = NULL;
! 809: xauth_ldap_config.subtree = 0;
! 810: xauth_ldap_config.bind_dn = NULL;
! 811: xauth_ldap_config.bind_pw = NULL;
! 812: xauth_ldap_config.auth_type = LDAP_AUTH_SIMPLE;
! 813: xauth_ldap_config.attr_user = NULL;
! 814: xauth_ldap_config.attr_addr = NULL;
! 815: xauth_ldap_config.attr_mask = NULL;
! 816: xauth_ldap_config.attr_group = NULL;
! 817: xauth_ldap_config.attr_member = NULL;
! 818:
! 819: /* set default host */
! 820: tmplen = strlen(LDAP_DFLT_HOST);
! 821: xauth_ldap_config.host = vmalloc(tmplen);
! 822: if (xauth_ldap_config.host == NULL)
! 823: goto out;
! 824: memcpy(xauth_ldap_config.host->v, LDAP_DFLT_HOST, tmplen);
! 825:
! 826: /* set default user naming attribute */
! 827: tmplen = strlen(LDAP_DFLT_USER);
! 828: xauth_ldap_config.attr_user = vmalloc(tmplen);
! 829: if (xauth_ldap_config.attr_user == NULL)
! 830: goto out;
! 831: memcpy(xauth_ldap_config.attr_user->v, LDAP_DFLT_USER, tmplen);
! 832:
! 833: /* set default address attribute */
! 834: tmplen = strlen(LDAP_DFLT_ADDR);
! 835: xauth_ldap_config.attr_addr = vmalloc(tmplen);
! 836: if (xauth_ldap_config.attr_addr == NULL)
! 837: goto out;
! 838: memcpy(xauth_ldap_config.attr_addr->v, LDAP_DFLT_ADDR, tmplen);
! 839:
! 840: /* set default netmask attribute */
! 841: tmplen = strlen(LDAP_DFLT_MASK);
! 842: xauth_ldap_config.attr_mask = vmalloc(tmplen);
! 843: if (xauth_ldap_config.attr_mask == NULL)
! 844: goto out;
! 845: memcpy(xauth_ldap_config.attr_mask->v, LDAP_DFLT_MASK, tmplen);
! 846:
! 847: /* set default group naming attribute */
! 848: tmplen = strlen(LDAP_DFLT_GROUP);
! 849: xauth_ldap_config.attr_group = vmalloc(tmplen);
! 850: if (xauth_ldap_config.attr_group == NULL)
! 851: goto out;
! 852: memcpy(xauth_ldap_config.attr_group->v, LDAP_DFLT_GROUP, tmplen);
! 853:
! 854: /* set default member attribute */
! 855: tmplen = strlen(LDAP_DFLT_MEMBER);
! 856: xauth_ldap_config.attr_member = vmalloc(tmplen);
! 857: if (xauth_ldap_config.attr_member == NULL)
! 858: goto out;
! 859: memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen);
! 860:
! 861: error = 0;
! 862: out:
! 863: if (error != 0)
! 864: plog(LLV_ERROR, LOCATION, NULL, "cannot allocate memory\n");
! 865:
! 866: return error;
! 867: }
! 868:
! 869: int
! 870: xauth_login_ldap(iph1, usr, pwd)
! 871: struct ph1handle *iph1;
! 872: char *usr;
! 873: char *pwd;
! 874: {
! 875: int rtn = -1;
! 876: int res = -1;
! 877: LDAP *ld = NULL;
! 878: LDAPMessage *lr = NULL;
! 879: LDAPMessage *le = NULL;
! 880: struct berval cred;
! 881: struct berval **bv = NULL;
! 882: struct timeval timeout;
! 883: char *init = NULL;
! 884: char *filter = NULL;
! 885: char *atlist[3];
! 886: char *basedn = NULL;
! 887: char *userdn = NULL;
! 888: int tmplen = 0;
! 889: int ecount = 0;
! 890: int scope = LDAP_SCOPE_ONE;
! 891:
! 892: atlist[0] = NULL;
! 893: atlist[1] = NULL;
! 894: atlist[2] = NULL;
! 895:
! 896: /* build our initialization url */
! 897: tmplen = strlen("ldap://:") + 17;
! 898: tmplen += strlen(xauth_ldap_config.host->v);
! 899: init = racoon_malloc(tmplen);
! 900: if (init == NULL) {
! 901: plog(LLV_ERROR, LOCATION, NULL,
! 902: "unable to alloc ldap init url\n");
! 903: goto ldap_end;
! 904: }
! 905: sprintf(init,"ldap://%s:%d",
! 906: xauth_ldap_config.host->v,
! 907: xauth_ldap_config.port );
! 908:
! 909: /* initialize the ldap handle */
! 910: res = ldap_initialize(&ld, init);
! 911: if (res != LDAP_SUCCESS) {
! 912: plog(LLV_ERROR, LOCATION, NULL,
! 913: "ldap_initialize failed: %s\n",
! 914: ldap_err2string(res));
! 915: goto ldap_end;
! 916: }
! 917:
! 918: /* initialize the protocol version */
! 919: ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
! 920: &xauth_ldap_config.pver);
! 921:
! 922: /*
! 923: * attempt to bind to the ldap server.
! 924: * default to anonymous bind unless a
! 925: * user dn and password has been
! 926: * specified in our configuration
! 927: */
! 928: if ((xauth_ldap_config.bind_dn != NULL)&&
! 929: (xauth_ldap_config.bind_pw != NULL))
! 930: {
! 931: cred.bv_val = xauth_ldap_config.bind_pw->v;
! 932: cred.bv_len = strlen( cred.bv_val );
! 933: res = ldap_sasl_bind_s(ld,
! 934: xauth_ldap_config.bind_dn->v, NULL, &cred,
! 935: NULL, NULL, NULL);
! 936: }
! 937: else
! 938: {
! 939: res = ldap_sasl_bind_s(ld,
! 940: NULL, NULL, NULL,
! 941: NULL, NULL, NULL);
! 942: }
! 943:
! 944: if (res!=LDAP_SUCCESS) {
! 945: plog(LLV_ERROR, LOCATION, NULL,
! 946: "ldap_sasl_bind_s (search) failed: %s\n",
! 947: ldap_err2string(res));
! 948: goto ldap_end;
! 949: }
! 950:
! 951: /* build an ldap user search filter */
! 952: tmplen = strlen(xauth_ldap_config.attr_user->v);
! 953: tmplen += 1;
! 954: tmplen += strlen(usr);
! 955: tmplen += 1;
! 956: filter = racoon_malloc(tmplen);
! 957: if (filter == NULL) {
! 958: plog(LLV_ERROR, LOCATION, NULL,
! 959: "unable to alloc ldap search filter buffer\n");
! 960: goto ldap_end;
! 961: }
! 962: sprintf(filter, "%s=%s",
! 963: xauth_ldap_config.attr_user->v, usr);
! 964:
! 965: /* build our return attribute list */
! 966: tmplen = strlen(xauth_ldap_config.attr_addr->v) + 1;
! 967: atlist[0] = racoon_malloc(tmplen);
! 968: tmplen = strlen(xauth_ldap_config.attr_mask->v) + 1;
! 969: atlist[1] = racoon_malloc(tmplen);
! 970: if ((atlist[0] == NULL)||(atlist[1] == NULL)) {
! 971: plog(LLV_ERROR, LOCATION, NULL,
! 972: "unable to alloc ldap attrib list buffer\n");
! 973: goto ldap_end;
! 974: }
! 975: strcpy(atlist[0],xauth_ldap_config.attr_addr->v);
! 976: strcpy(atlist[1],xauth_ldap_config.attr_mask->v);
! 977:
! 978: /* attempt to locate the user dn */
! 979: if (xauth_ldap_config.base != NULL)
! 980: basedn = xauth_ldap_config.base->v;
! 981: if (xauth_ldap_config.subtree)
! 982: scope = LDAP_SCOPE_SUBTREE;
! 983: timeout.tv_sec = 15;
! 984: timeout.tv_usec = 0;
! 985: res = ldap_search_ext_s(ld, basedn, scope,
! 986: filter, atlist, 0, NULL, NULL,
! 987: &timeout, 2, &lr);
! 988: if (res != LDAP_SUCCESS) {
! 989: plog(LLV_ERROR, LOCATION, NULL,
! 990: "ldap_search_ext_s failed: %s\n",
! 991: ldap_err2string(res));
! 992: goto ldap_end;
! 993: }
! 994:
! 995: /* check the number of ldap entries returned */
! 996: ecount = ldap_count_entries(ld, lr);
! 997: if (ecount < 1) {
! 998: plog(LLV_WARNING, LOCATION, NULL,
! 999: "no ldap results for filter \'%s\'\n",
! 1000: filter);
! 1001: goto ldap_end;
! 1002: }
! 1003: if (ecount > 1) {
! 1004: plog(LLV_WARNING, LOCATION, NULL,
! 1005: "multiple (%i) ldap results for filter \'%s\'\n",
! 1006: ecount, filter);
! 1007: }
! 1008:
! 1009: /* obtain the dn from the first result */
! 1010: le = ldap_first_entry(ld, lr);
! 1011: if (le == NULL) {
! 1012: plog(LLV_ERROR, LOCATION, NULL,
! 1013: "ldap_first_entry failed: invalid entry returned\n");
! 1014: goto ldap_end;
! 1015: }
! 1016: userdn = ldap_get_dn(ld, le);
! 1017: if (userdn == NULL) {
! 1018: plog(LLV_ERROR, LOCATION, NULL,
! 1019: "ldap_get_dn failed: invalid string returned\n");
! 1020: goto ldap_end;
! 1021: }
! 1022:
! 1023: /* cache the user dn in the xauth state */
! 1024: iph1->mode_cfg->xauth.udn = racoon_malloc(strlen(userdn)+1);
! 1025: strcpy(iph1->mode_cfg->xauth.udn,userdn);
! 1026:
! 1027: /* retrieve modecfg address */
! 1028: bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_addr->v);
! 1029: if (bv != NULL) {
! 1030: char tmpaddr[16];
! 1031: /* sanity check for address value */
! 1032: if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
! 1033: plog(LLV_DEBUG, LOCATION, NULL,
! 1034: "ldap returned invalid modecfg address\n");
! 1035: ldap_value_free_len(bv);
! 1036: goto ldap_end;
! 1037: }
! 1038: memcpy(tmpaddr,bv[0]->bv_val,bv[0]->bv_len);
! 1039: tmpaddr[bv[0]->bv_len]=0;
! 1040: iph1->mode_cfg->addr4.s_addr = inet_addr(tmpaddr);
! 1041: iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_EXTERN;
! 1042: plog(LLV_INFO, LOCATION, NULL,
! 1043: "ldap returned modecfg address %s\n", tmpaddr);
! 1044: ldap_value_free_len(bv);
! 1045: }
! 1046:
! 1047: /* retrieve modecfg netmask */
! 1048: bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_mask->v);
! 1049: if (bv != NULL) {
! 1050: char tmpmask[16];
! 1051: /* sanity check for netmask value */
! 1052: if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
! 1053: plog(LLV_DEBUG, LOCATION, NULL,
! 1054: "ldap returned invalid modecfg netmask\n");
! 1055: ldap_value_free_len(bv);
! 1056: goto ldap_end;
! 1057: }
! 1058: memcpy(tmpmask,bv[0]->bv_val,bv[0]->bv_len);
! 1059: tmpmask[bv[0]->bv_len]=0;
! 1060: iph1->mode_cfg->mask4.s_addr = inet_addr(tmpmask);
! 1061: iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_EXTERN;
! 1062: plog(LLV_INFO, LOCATION, NULL,
! 1063: "ldap returned modecfg netmask %s\n", tmpmask);
! 1064: ldap_value_free_len(bv);
! 1065: }
! 1066:
! 1067: /*
! 1068: * finally, use the dn and the xauth
! 1069: * password to check the users given
! 1070: * credentials by attempting to bind
! 1071: * to the ldap server
! 1072: */
! 1073: plog(LLV_INFO, LOCATION, NULL,
! 1074: "attempting ldap bind for dn \'%s\'\n", userdn);
! 1075: cred.bv_val = pwd;
! 1076: cred.bv_len = strlen( cred.bv_val );
! 1077: res = ldap_sasl_bind_s(ld,
! 1078: userdn, NULL, &cred,
! 1079: NULL, NULL, NULL);
! 1080: if(res==LDAP_SUCCESS)
! 1081: rtn = 0;
! 1082:
! 1083: ldap_end:
! 1084:
! 1085: /* free ldap resources */
! 1086: if (userdn != NULL)
! 1087: ldap_memfree(userdn);
! 1088: if (atlist[0] != NULL)
! 1089: racoon_free(atlist[0]);
! 1090: if (atlist[1] != NULL)
! 1091: racoon_free(atlist[1]);
! 1092: if (filter != NULL)
! 1093: racoon_free(filter);
! 1094: if (lr != NULL)
! 1095: ldap_msgfree(lr);
! 1096: if (init != NULL)
! 1097: racoon_free(init);
! 1098:
! 1099: ldap_unbind_ext_s(ld, NULL, NULL);
! 1100:
! 1101: return rtn;
! 1102: }
! 1103:
! 1104: int
! 1105: xauth_group_ldap(udn, grp)
! 1106: char * udn;
! 1107: char * grp;
! 1108: {
! 1109: int rtn = -1;
! 1110: int res = -1;
! 1111: LDAP *ld = NULL;
! 1112: LDAPMessage *lr = NULL;
! 1113: LDAPMessage *le = NULL;
! 1114: struct berval cred;
! 1115: struct timeval timeout;
! 1116: char *init = NULL;
! 1117: char *filter = NULL;
! 1118: char *basedn = NULL;
! 1119: char *groupdn = NULL;
! 1120: int tmplen = 0;
! 1121: int ecount = 0;
! 1122: int scope = LDAP_SCOPE_ONE;
! 1123:
! 1124: /* build our initialization url */
! 1125: tmplen = strlen("ldap://:") + 17;
! 1126: tmplen += strlen(xauth_ldap_config.host->v);
! 1127: init = racoon_malloc(tmplen);
! 1128: if (init == NULL) {
! 1129: plog(LLV_ERROR, LOCATION, NULL,
! 1130: "unable to alloc ldap init url\n");
! 1131: goto ldap_group_end;
! 1132: }
! 1133: sprintf(init,"ldap://%s:%d",
! 1134: xauth_ldap_config.host->v,
! 1135: xauth_ldap_config.port );
! 1136:
! 1137: /* initialize the ldap handle */
! 1138: res = ldap_initialize(&ld, init);
! 1139: if (res != LDAP_SUCCESS) {
! 1140: plog(LLV_ERROR, LOCATION, NULL,
! 1141: "ldap_initialize failed: %s\n",
! 1142: ldap_err2string(res));
! 1143: goto ldap_group_end;
! 1144: }
! 1145:
! 1146: /* initialize the protocol version */
! 1147: ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
! 1148: &xauth_ldap_config.pver);
! 1149:
! 1150: /*
! 1151: * attempt to bind to the ldap server.
! 1152: * default to anonymous bind unless a
! 1153: * user dn and password has been
! 1154: * specified in our configuration
! 1155: */
! 1156: if ((xauth_ldap_config.bind_dn != NULL)&&
! 1157: (xauth_ldap_config.bind_pw != NULL))
! 1158: {
! 1159: cred.bv_val = xauth_ldap_config.bind_pw->v;
! 1160: cred.bv_len = strlen( cred.bv_val );
! 1161: res = ldap_sasl_bind_s(ld,
! 1162: xauth_ldap_config.bind_dn->v, NULL, &cred,
! 1163: NULL, NULL, NULL);
! 1164: }
! 1165: else
! 1166: {
! 1167: res = ldap_sasl_bind_s(ld,
! 1168: NULL, NULL, NULL,
! 1169: NULL, NULL, NULL);
! 1170: }
! 1171:
! 1172: if (res!=LDAP_SUCCESS) {
! 1173: plog(LLV_ERROR, LOCATION, NULL,
! 1174: "ldap_sasl_bind_s (search) failed: %s\n",
! 1175: ldap_err2string(res));
! 1176: goto ldap_group_end;
! 1177: }
! 1178:
! 1179: /* build an ldap group search filter */
! 1180: tmplen = strlen("(&(=)(=))") + 1;
! 1181: tmplen += strlen(xauth_ldap_config.attr_group->v);
! 1182: tmplen += strlen(grp);
! 1183: tmplen += strlen(xauth_ldap_config.attr_member->v);
! 1184: tmplen += strlen(udn);
! 1185: filter = racoon_malloc(tmplen);
! 1186: if (filter == NULL) {
! 1187: plog(LLV_ERROR, LOCATION, NULL,
! 1188: "unable to alloc ldap search filter buffer\n");
! 1189: goto ldap_group_end;
! 1190: }
! 1191: sprintf(filter, "(&(%s=%s)(%s=%s))",
! 1192: xauth_ldap_config.attr_group->v, grp,
! 1193: xauth_ldap_config.attr_member->v, udn);
! 1194:
! 1195: /* attempt to locate the group dn */
! 1196: if (xauth_ldap_config.base != NULL)
! 1197: basedn = xauth_ldap_config.base->v;
! 1198: if (xauth_ldap_config.subtree)
! 1199: scope = LDAP_SCOPE_SUBTREE;
! 1200: timeout.tv_sec = 15;
! 1201: timeout.tv_usec = 0;
! 1202: res = ldap_search_ext_s(ld, basedn, scope,
! 1203: filter, NULL, 0, NULL, NULL,
! 1204: &timeout, 2, &lr);
! 1205: if (res != LDAP_SUCCESS) {
! 1206: plog(LLV_ERROR, LOCATION, NULL,
! 1207: "ldap_search_ext_s failed: %s\n",
! 1208: ldap_err2string(res));
! 1209: goto ldap_group_end;
! 1210: }
! 1211:
! 1212: /* check the number of ldap entries returned */
! 1213: ecount = ldap_count_entries(ld, lr);
! 1214: if (ecount < 1) {
! 1215: plog(LLV_WARNING, LOCATION, NULL,
! 1216: "no ldap results for filter \'%s\'\n",
! 1217: filter);
! 1218: goto ldap_group_end;
! 1219: }
! 1220:
! 1221: /* success */
! 1222: rtn = 0;
! 1223:
! 1224: /* obtain the dn from the first result */
! 1225: le = ldap_first_entry(ld, lr);
! 1226: if (le == NULL) {
! 1227: plog(LLV_ERROR, LOCATION, NULL,
! 1228: "ldap_first_entry failed: invalid entry returned\n");
! 1229: goto ldap_group_end;
! 1230: }
! 1231: groupdn = ldap_get_dn(ld, le);
! 1232: if (groupdn == NULL) {
! 1233: plog(LLV_ERROR, LOCATION, NULL,
! 1234: "ldap_get_dn failed: invalid string returned\n");
! 1235: goto ldap_group_end;
! 1236: }
! 1237:
! 1238: plog(LLV_INFO, LOCATION, NULL,
! 1239: "ldap membership group returned \'%s\'\n", groupdn);
! 1240: ldap_group_end:
! 1241:
! 1242: /* free ldap resources */
! 1243: if (groupdn != NULL)
! 1244: ldap_memfree(groupdn);
! 1245: if (filter != NULL)
! 1246: racoon_free(filter);
! 1247: if (lr != NULL)
! 1248: ldap_msgfree(lr);
! 1249: if (init != NULL)
! 1250: racoon_free(init);
! 1251:
! 1252: ldap_unbind_ext_s(ld, NULL, NULL);
! 1253:
! 1254: return rtn;
! 1255: }
! 1256:
! 1257: #endif
! 1258:
! 1259: int
! 1260: xauth_login_system(usr, pwd)
! 1261: char *usr;
! 1262: char *pwd;
! 1263: {
! 1264: struct passwd *pw;
! 1265: char *cryptpwd;
! 1266: char *syscryptpwd;
! 1267: #ifdef HAVE_SHADOW_H
! 1268: struct spwd *spw;
! 1269:
! 1270: if ((spw = getspnam(usr)) == NULL)
! 1271: return -1;
! 1272:
! 1273: syscryptpwd = spw->sp_pwdp;
! 1274: #endif
! 1275:
! 1276: if ((pw = getpwnam(usr)) == NULL)
! 1277: return -1;
! 1278:
! 1279: #ifndef HAVE_SHADOW_H
! 1280: syscryptpwd = pw->pw_passwd;
! 1281: #endif
! 1282:
! 1283: /* No root login. Ever. */
! 1284: if (pw->pw_uid == 0)
! 1285: return -1;
! 1286:
! 1287: if ((cryptpwd = crypt(pwd, syscryptpwd)) == NULL)
! 1288: return -1;
! 1289:
! 1290: if (strcmp(cryptpwd, syscryptpwd) == 0)
! 1291: return 0;
! 1292:
! 1293: return -1;
! 1294: }
! 1295:
! 1296: int
! 1297: xauth_group_system(usr, grp)
! 1298: char * usr;
! 1299: char * grp;
! 1300: {
! 1301: struct group * gr;
! 1302: char * member;
! 1303: int index = 0;
! 1304:
! 1305: gr = getgrnam(grp);
! 1306: if (gr == NULL) {
! 1307: plog(LLV_ERROR, LOCATION, NULL,
! 1308: "the system group name \'%s\' is unknown\n",
! 1309: grp);
! 1310: return -1;
! 1311: }
! 1312:
! 1313: while ((member = gr->gr_mem[index++])!=NULL) {
! 1314: if (!strcmp(member,usr)) {
! 1315: plog(LLV_INFO, LOCATION, NULL,
! 1316: "membership validated\n");
! 1317: return 0;
! 1318: }
! 1319: }
! 1320:
! 1321: return -1;
! 1322: }
! 1323:
! 1324: int
! 1325: xauth_check(iph1)
! 1326: struct ph1handle *iph1;
! 1327: {
! 1328: struct xauth_state *xst = &iph1->mode_cfg->xauth;
! 1329:
! 1330: /*
! 1331: * Only the server side (edge device) really check for Xauth
! 1332: * status. It does it if the chose authmethod is using Xauth.
! 1333: * On the client side (roadwarrior), we don't check anything.
! 1334: */
! 1335: switch (iph1->approval->authmethod) {
! 1336: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
! 1337: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
! 1338: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
! 1339: /* The following are not yet implemented */
! 1340: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
! 1341: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
! 1342: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
! 1343: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
! 1344: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
! 1345: plog(LLV_ERROR, LOCATION, NULL,
! 1346: "Hybrid auth negotiated but peer did not "
! 1347: "announced as Xauth capable\n");
! 1348: return -1;
! 1349: }
! 1350:
! 1351: if (xst->status != XAUTHST_OK) {
! 1352: plog(LLV_ERROR, LOCATION, NULL,
! 1353: "Hybrid auth negotiated but peer did not "
! 1354: "succeed Xauth exchange\n");
! 1355: return -1;
! 1356: }
! 1357:
! 1358: return 0;
! 1359: break;
! 1360: default:
! 1361: return 0;
! 1362: break;
! 1363: }
! 1364:
! 1365: return 0;
! 1366: }
! 1367:
! 1368: int
! 1369: group_check(iph1, grp_list, grp_count)
! 1370: struct ph1handle *iph1;
! 1371: char **grp_list;
! 1372: int grp_count;
! 1373: {
! 1374: int res = -1;
! 1375: int grp_index = 0;
! 1376: char * usr = NULL;
! 1377:
! 1378: /* check for presence of modecfg data */
! 1379:
! 1380: if(iph1->mode_cfg == NULL) {
! 1381: plog(LLV_ERROR, LOCATION, NULL,
! 1382: "xauth group specified but modecfg not found\n");
! 1383: return res;
! 1384: }
! 1385:
! 1386: /* loop through our group list */
! 1387:
! 1388: for(; grp_index < grp_count; grp_index++) {
! 1389:
! 1390: /* check for presence of xauth data */
! 1391:
! 1392: usr = iph1->mode_cfg->xauth.authdata.generic.usr;
! 1393:
! 1394: if(usr == NULL) {
! 1395: plog(LLV_ERROR, LOCATION, NULL,
! 1396: "xauth group specified but xauth not found\n");
! 1397: return res;
! 1398: }
! 1399:
! 1400: /* call appropriate group validation funtion */
! 1401:
! 1402: switch (isakmp_cfg_config.groupsource) {
! 1403:
! 1404: case ISAKMP_CFG_GROUP_SYSTEM:
! 1405: res = xauth_group_system(
! 1406: usr,
! 1407: grp_list[grp_index]);
! 1408: break;
! 1409:
! 1410: #ifdef HAVE_LIBLDAP
! 1411: case ISAKMP_CFG_GROUP_LDAP:
! 1412: res = xauth_group_ldap(
! 1413: iph1->mode_cfg->xauth.udn,
! 1414: grp_list[grp_index]);
! 1415: break;
! 1416: #endif
! 1417:
! 1418: default:
! 1419: /* we should never get here */
! 1420: plog(LLV_ERROR, LOCATION, NULL,
! 1421: "Unknown group auth source\n");
! 1422: break;
! 1423: }
! 1424:
! 1425: if( !res ) {
! 1426: plog(LLV_INFO, LOCATION, NULL,
! 1427: "user \"%s\" is a member of group \"%s\"\n",
! 1428: usr,
! 1429: grp_list[grp_index]);
! 1430: break;
! 1431: } else {
! 1432: plog(LLV_INFO, LOCATION, NULL,
! 1433: "user \"%s\" is not a member of group \"%s\"\n",
! 1434: usr,
! 1435: grp_list[grp_index]);
! 1436: }
! 1437: }
! 1438:
! 1439: return res;
! 1440: }
! 1441:
! 1442: vchar_t *
! 1443: isakmp_xauth_req(iph1, attr)
! 1444: struct ph1handle *iph1;
! 1445: struct isakmp_data *attr;
! 1446: {
! 1447: int type;
! 1448: size_t dlen = 0;
! 1449: int ashort = 0;
! 1450: int value = 0;
! 1451: vchar_t *buffer = NULL;
! 1452: char *mraw = NULL, *mdata;
! 1453: char *data;
! 1454: vchar_t *usr = NULL;
! 1455: vchar_t *pwd = NULL;
! 1456: size_t skip = 0;
! 1457: int freepwd = 0;
! 1458:
! 1459: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
! 1460: plog(LLV_ERROR, LOCATION, NULL,
! 1461: "Xauth mode config request but peer "
! 1462: "did not declare itself as Xauth capable\n");
! 1463: return NULL;
! 1464: }
! 1465:
! 1466: type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
! 1467:
! 1468: /* Sanity checks */
! 1469: switch(type) {
! 1470: case XAUTH_TYPE:
! 1471: if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
! 1472: plog(LLV_ERROR, LOCATION, NULL,
! 1473: "Unexpected long XAUTH_TYPE attribute\n");
! 1474: return NULL;
! 1475: }
! 1476: if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
! 1477: plog(LLV_ERROR, LOCATION, NULL,
! 1478: "Unsupported Xauth authentication %d\n",
! 1479: ntohs(attr->lorv));
! 1480: return NULL;
! 1481: }
! 1482: ashort = 1;
! 1483: dlen = 0;
! 1484: value = XAUTH_TYPE_GENERIC;
! 1485: break;
! 1486:
! 1487: case XAUTH_USER_NAME:
! 1488: if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
! 1489: plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
! 1490: "with no login supplied\n");
! 1491: return NULL;
! 1492: }
! 1493:
! 1494: dlen = iph1->rmconf->xauth->login->l - 1;
! 1495: iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
! 1496: break;
! 1497:
! 1498: case XAUTH_USER_PASSWORD:
! 1499: if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
! 1500: return NULL;
! 1501:
! 1502: skip = sizeof(struct ipsecdoi_id_b);
! 1503: usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
! 1504: if (usr == NULL) {
! 1505: plog(LLV_ERROR, LOCATION, NULL,
! 1506: "Cannot allocate memory\n");
! 1507: return NULL;
! 1508: }
! 1509: memset(usr->v, 0, skip);
! 1510: memcpy(usr->v + skip,
! 1511: iph1->rmconf->xauth->login->v,
! 1512: iph1->rmconf->xauth->login->l - 1);
! 1513:
! 1514: if (iph1->rmconf->xauth->pass) {
! 1515: /* A key given through racoonctl */
! 1516: pwd = iph1->rmconf->xauth->pass;
! 1517: } else {
! 1518: if ((pwd = getpskbyname(usr)) == NULL) {
! 1519: plog(LLV_ERROR, LOCATION, NULL,
! 1520: "No password was found for login %s\n",
! 1521: iph1->rmconf->xauth->login->v);
! 1522: vfree(usr);
! 1523: return NULL;
! 1524: }
! 1525: /* We have to free it before returning */
! 1526: freepwd = 1;
! 1527: }
! 1528: vfree(usr);
! 1529:
! 1530: iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
! 1531: dlen = pwd->l;
! 1532:
! 1533: break;
! 1534: case XAUTH_MESSAGE:
! 1535: if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
! 1536: dlen = ntohs(attr->lorv);
! 1537: if (dlen > 0) {
! 1538: mraw = (char*)(attr + 1);
! 1539: mdata = binsanitize(mraw, dlen);
! 1540: if (mdata == NULL) {
! 1541: plog(LLV_ERROR, LOCATION, iph1->remote,
! 1542: "Cannot allocate memory\n");
! 1543: return NULL;
! 1544: }
! 1545: plog(LLV_NOTIFY,LOCATION, iph1->remote,
! 1546: "XAUTH Message: '%s'.\n",
! 1547: mdata);
! 1548: racoon_free(mdata);
! 1549: }
! 1550: }
! 1551: return NULL;
! 1552: default:
! 1553: plog(LLV_WARNING, LOCATION, NULL,
! 1554: "Ignored attribute %s\n", s_isakmp_cfg_type(type));
! 1555: return NULL;
! 1556: break;
! 1557: }
! 1558:
! 1559: if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
! 1560: plog(LLV_ERROR, LOCATION, NULL,
! 1561: "Cannot allocate memory\n");
! 1562: goto out;
! 1563: }
! 1564:
! 1565: attr = (struct isakmp_data *)buffer->v;
! 1566: if (ashort) {
! 1567: attr->type = htons(type | ISAKMP_GEN_TV);
! 1568: attr->lorv = htons(value);
! 1569: goto out;
! 1570: }
! 1571:
! 1572: attr->type = htons(type | ISAKMP_GEN_TLV);
! 1573: attr->lorv = htons(dlen);
! 1574: data = (char *)(attr + 1);
! 1575:
! 1576: switch(type) {
! 1577: case XAUTH_USER_NAME:
! 1578: /*
! 1579: * iph1->rmconf->xauth->login->v is valid,
! 1580: * we just checked it in the previous switch case
! 1581: */
! 1582: memcpy(data, iph1->rmconf->xauth->login->v, dlen);
! 1583: break;
! 1584: case XAUTH_USER_PASSWORD:
! 1585: memcpy(data, pwd->v, dlen);
! 1586: break;
! 1587: default:
! 1588: break;
! 1589: }
! 1590:
! 1591: out:
! 1592: if (freepwd)
! 1593: vfree(pwd);
! 1594:
! 1595: return buffer;
! 1596: }
! 1597:
! 1598: vchar_t *
! 1599: isakmp_xauth_set(iph1, attr)
! 1600: struct ph1handle *iph1;
! 1601: struct isakmp_data *attr;
! 1602: {
! 1603: int type;
! 1604: vchar_t *buffer = NULL;
! 1605: char *data;
! 1606: struct xauth_state *xst;
! 1607: size_t dlen = 0;
! 1608: char* mraw = NULL, *mdata;
! 1609:
! 1610: if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
! 1611: plog(LLV_ERROR, LOCATION, NULL,
! 1612: "Xauth mode config set but peer "
! 1613: "did not declare itself as Xauth capable\n");
! 1614: return NULL;
! 1615: }
! 1616:
! 1617: type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
! 1618:
! 1619: switch(type) {
! 1620: case XAUTH_STATUS:
! 1621: /*
! 1622: * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS
! 1623: * when running as a client (initiator).
! 1624: */
! 1625: xst = &iph1->mode_cfg->xauth;
! 1626: switch (iph1->approval->authmethod) {
! 1627: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
! 1628: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
! 1629: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
! 1630: /* Not implemented ... */
! 1631: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
! 1632: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
! 1633: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
! 1634: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
! 1635: break;
! 1636: default:
! 1637: plog(LLV_ERROR, LOCATION, NULL,
! 1638: "Unexpected XAUTH_STATUS_OK\n");
! 1639: return NULL;
! 1640: break;
! 1641: }
! 1642:
! 1643: /* If we got a failure, delete iph1 */
! 1644: if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
! 1645: plog(LLV_ERROR, LOCATION, NULL,
! 1646: "Xauth authentication failed\n");
! 1647:
! 1648: evt_phase1(iph1, EVT_PHASE1_XAUTH_FAILED, NULL);
! 1649:
! 1650: iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
! 1651: } else {
! 1652: evt_phase1(iph1, EVT_PHASE1_XAUTH_SUCCESS, NULL);
! 1653: }
! 1654:
! 1655:
! 1656: /* We acknowledge it */
! 1657: break;
! 1658: case XAUTH_MESSAGE:
! 1659: if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
! 1660: dlen = ntohs(attr->lorv);
! 1661: if (dlen > 0) {
! 1662: mraw = (char*)(attr + 1);
! 1663: mdata = binsanitize(mraw, dlen);
! 1664: if (mdata == NULL) {
! 1665: plog(LLV_ERROR, LOCATION, iph1->remote,
! 1666: "Cannot allocate memory\n");
! 1667: return NULL;
! 1668: }
! 1669: plog(LLV_NOTIFY,LOCATION, iph1->remote,
! 1670: "XAUTH Message: '%s'.\n",
! 1671: mdata);
! 1672: racoon_free(mdata);
! 1673: }
! 1674: }
! 1675:
! 1676: default:
! 1677: plog(LLV_WARNING, LOCATION, NULL,
! 1678: "Ignored attribute %s\n", s_isakmp_cfg_type(type));
! 1679: return NULL;
! 1680: break;
! 1681: }
! 1682:
! 1683: if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
! 1684: plog(LLV_ERROR, LOCATION, NULL,
! 1685: "Cannot allocate memory\n");
! 1686: return NULL;
! 1687: }
! 1688:
! 1689: attr = (struct isakmp_data *)buffer->v;
! 1690: attr->type = htons(type | ISAKMP_GEN_TV);
! 1691: attr->lorv = htons(0);
! 1692:
! 1693: return buffer;
! 1694: }
! 1695:
! 1696:
! 1697: void
! 1698: xauth_rmstate(xst)
! 1699: struct xauth_state *xst;
! 1700: {
! 1701: switch (xst->authtype) {
! 1702: case XAUTH_TYPE_GENERIC:
! 1703: if (xst->authdata.generic.usr)
! 1704: racoon_free(xst->authdata.generic.usr);
! 1705:
! 1706: if (xst->authdata.generic.pwd)
! 1707: racoon_free(xst->authdata.generic.pwd);
! 1708:
! 1709: break;
! 1710:
! 1711: case XAUTH_TYPE_CHAP:
! 1712: case XAUTH_TYPE_OTP:
! 1713: case XAUTH_TYPE_SKEY:
! 1714: plog(LLV_WARNING, LOCATION, NULL,
! 1715: "Unsupported authtype %d\n", xst->authtype);
! 1716: break;
! 1717:
! 1718: default:
! 1719: plog(LLV_WARNING, LOCATION, NULL,
! 1720: "Unexpected authtype %d\n", xst->authtype);
! 1721: break;
! 1722: }
! 1723:
! 1724: #ifdef HAVE_LIBLDAP
! 1725: if (xst->udn != NULL)
! 1726: racoon_free(xst->udn);
! 1727: #endif
! 1728: return;
! 1729: }
! 1730:
! 1731: int
! 1732: xauth_rmconf_used(xauth_rmconf)
! 1733: struct xauth_rmconf **xauth_rmconf;
! 1734: {
! 1735: if (*xauth_rmconf == NULL) {
! 1736: *xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf));
! 1737: if (*xauth_rmconf == NULL) {
! 1738: plog(LLV_ERROR, LOCATION, NULL,
! 1739: "xauth_rmconf_used: malloc failed\n");
! 1740: return -1;
! 1741: }
! 1742:
! 1743: (*xauth_rmconf)->login = NULL;
! 1744: (*xauth_rmconf)->pass = NULL;
! 1745: (*xauth_rmconf)->state = 0;
! 1746: }
! 1747:
! 1748: return 0;
! 1749: }
! 1750:
! 1751: void
! 1752: xauth_rmconf_delete(xauth_rmconf)
! 1753: struct xauth_rmconf **xauth_rmconf;
! 1754: {
! 1755: if (*xauth_rmconf != NULL) {
! 1756: if ((*xauth_rmconf)->login != NULL)
! 1757: vfree((*xauth_rmconf)->login);
! 1758: if ((*xauth_rmconf)->pass != NULL)
! 1759: vfree((*xauth_rmconf)->pass);
! 1760:
! 1761: racoon_free(*xauth_rmconf);
! 1762: *xauth_rmconf = NULL;
! 1763: }
! 1764:
! 1765: return;
! 1766: }
! 1767:
! 1768: struct xauth_rmconf *
! 1769: xauth_rmconf_dup(xauth_rmconf)
! 1770: struct xauth_rmconf *xauth_rmconf;
! 1771: {
! 1772: struct xauth_rmconf *new;
! 1773:
! 1774: if (xauth_rmconf != NULL) {
! 1775: new = racoon_malloc(sizeof(*new));
! 1776: if (new == NULL) {
! 1777: plog(LLV_ERROR, LOCATION, NULL,
! 1778: "xauth_rmconf_dup: malloc failed\n");
! 1779: return NULL;
! 1780: }
! 1781:
! 1782: memcpy(new, xauth_rmconf, sizeof(*new));
! 1783:
! 1784: if (xauth_rmconf->login != NULL) {
! 1785: new->login = vdup(xauth_rmconf->login);
! 1786: if (new->login == NULL) {
! 1787: plog(LLV_ERROR, LOCATION, NULL,
! 1788: "xauth_rmconf_dup: malloc failed (login)\n");
! 1789: return NULL;
! 1790: }
! 1791: }
! 1792: if (xauth_rmconf->pass != NULL) {
! 1793: new->pass = vdup(xauth_rmconf->pass);
! 1794: if (new->pass == NULL) {
! 1795: plog(LLV_ERROR, LOCATION, NULL,
! 1796: "xauth_rmconf_dup: malloc failed (password)\n");
! 1797: return NULL;
! 1798: }
! 1799: }
! 1800:
! 1801: return new;
! 1802: }
! 1803:
! 1804: return NULL;
! 1805: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>