-/* $Id: isakmp_xauth.c,v 1.17.2.5 2005/05/20 07:31:09 manubsd Exp $ */
+/* $NetBSD: isakmp_xauth.c,v 1.11.6.1 2007/08/07 04:49:24 manu Exp $ */
+
+/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
/*
* Copyright (C) 2004-2005 Emmanuel Dreyfus
#include <string.h>
#include <errno.h>
#include <pwd.h>
-#ifdef HAVE_SHADOW_H
-#include <shadow.h>
-#endif
+#include <grp.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#endif
#include <ctype.h>
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "sockmisc.h"
#include "schedule.h"
#include "debug.h"
+#include "fsm.h"
#include "crypto_openssl.h"
#include "isakmp_var.h"
#include "isakmp.h"
-#include "admin.h"
-#include "privsep.h"
-#include "evt.h"
#include "handler.h"
#include "throttle.h"
#include "remoteconf.h"
#include "ipsec_doi.h"
#include "remoteconf.h"
#include "localconf.h"
-
-#ifdef HAVE_LIBRADIUS
-#include <radlib.h>
-
-struct rad_handle *radius_auth_state = NULL;
-struct rad_handle *radius_acct_state = NULL;
-#endif
-
-#ifdef HAVE_LIBPAM
-#ifdef __APPLE__
-#include <pam/pam_appl.h>
-#else
-#include <security/pam_appl.h>
-#endif
-
-static char *PAM_usr = NULL;
-static char *PAM_pwd = NULL;
-static int PAM_conv(int, const struct pam_message **,
- struct pam_response **, void *);
-static struct pam_conv PAM_chat = { &PAM_conv, NULL };
-#endif
+#include "vpn_control.h"
+#include "vpn_control_var.h"
+#include "ipsecSessionTracer.h"
+#include "ipsecMessageTracer.h"
void
xauth_sendreq(iph1)
- struct ph1handle *iph1;
+ phase1_handle_t *iph1;
{
vchar_t *buffer;
struct isakmp_pl_attr *attr;
size_t tlen;
/* Status checks */
- if (iph1->status != PHASE1ST_ESTABLISHED) {
- plog(LLV_ERROR, LOCATION, NULL,
+ if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
+ plog(ASL_LEVEL_ERR,
"Xauth request while phase 1 is not completed\n");
return;
}
if (xst->status != XAUTHST_NOTYET) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Xauth request whith Xauth state %d\n", xst->status);
return;
}
- plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n");
+ plog(ASL_LEVEL_NOTICE, "Sending Xauth request\n");
tlen = sizeof(*attr) +
+ sizeof(*typeattr) +
+ sizeof(*pwdattr);
if ((buffer = vmalloc(tlen)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
+ plog(ASL_LEVEL_ERR, "Cannot allocate buffer\n");
return;
}
pwdattr->lorv = htons(0);
isakmp_cfg_send(iph1, buffer,
- ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
+ ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL);
vfree(buffer);
return;
}
-void
+int
xauth_attr_reply(iph1, attr, id)
- struct ph1handle *iph1;
+ phase1_handle_t *iph1;
struct isakmp_data *attr;
int id;
{
struct xauth_state *xst = &iph1->mode_cfg->xauth;
if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Xauth reply but peer did not declare "
"itself as Xauth capable\n");
- return;
+ return -1;
}
if (xst->status != XAUTHST_REQSENT) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Xauth reply while Xauth state is %d\n", xst->status);
- return;
+ return -1;
}
type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
xst->authtype = XAUTH_TYPE_GENERIC;
break;
default:
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_WARNING,
"Unexpected authentication type %d\n",
ntohs(type));
- return;
+ return -1;
}
break;
break;
default:
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_WARNING,
"ignored Xauth attribute %d\n", type);
break;
}
if (outlet != NULL) {
alen = ntohs(attr->lorv);
- if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ if ((*outlet = racoon_realloc(*outlet, alen + 1)) == NULL) {
+ plog(ASL_LEVEL_ERR,
"Cannot allocate memory for Xauth Data\n");
- return;
+ return -1;
}
memcpy(*outlet, attr + 1, alen);
time_t throttle_delay = 0;
#if 0 /* Real debug, don't do that at home */
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"Got username \"%s\", password \"%s\"\n", usr, pwd);
#endif
- strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
- iph1->mode_cfg->login[LOGINLEN] = '\0';
+ strlcpy(iph1->mode_cfg->login, usr, sizeof(iph1->mode_cfg->login));
res = -1;
if ((port = isakmp_cfg_getport(iph1)) == -1) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Port pool depleted\n");
goto skip_auth;
}
switch (isakmp_cfg_config.authsource) {
case ISAKMP_CFG_AUTH_SYSTEM:
- res = privsep_xauth_login_system(usr, pwd);
+ res = xauth_login_system(usr, pwd);
break;
-#ifdef HAVE_LIBRADIUS
- case ISAKMP_CFG_AUTH_RADIUS:
- res = xauth_login_radius(iph1, usr, pwd);
- break;
-#endif
-#ifdef HAVE_LIBPAM
- case ISAKMP_CFG_AUTH_PAM:
- res = privsep_xauth_login_pam(iph1->mode_cfg->port,
- iph1->remote, usr, pwd);
- break;
-#endif
+
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Unexpected authentication source\n");
res = -1;
break;
}
+ /*
+ * Optional group authentication
+ */
+ if (!res && (isakmp_cfg_config.groupcount))
+ res = group_check(iph1,
+ isakmp_cfg_config.grouplist,
+ isakmp_cfg_config.groupcount);
+
/*
* On failure, throttle the connexion for the remote host
* in order to make password attacks more difficult.
if (throttle_delay > 0) {
char *str;
- str = saddrwop2str(iph1->remote);
+ str = saddrwop2str((struct sockaddr *)iph1->remote);
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Throttling in action for %s: delay %lds\n",
str, (unsigned long)throttle_delay);
res = -1;
struct xauth_reply_arg *xra;
if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"malloc failed, bypass throttling\n");
- xauth_reply(iph1, port, id, res);
- return;
+ return xauth_reply(iph1, port, id, res);
}
/*
xra->res = res;
sched_new(throttle_delay, xauth_reply_stub, xra);
} else {
- xauth_reply(iph1, port, id, res);
+ return xauth_reply(iph1, port, id, res);
}
}
- return;
+ return 0;
}
void
void *args;
{
struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
- struct ph1handle *iph1;
+ phase1_handle_t *iph1;
- if ((iph1 = getph1byindex(&xra->index)) != NULL)
- xauth_reply(iph1, xra->port, xra->id, xra->res);
+ if ((iph1 = ike_session_getph1byindex(NULL, &xra->index)) != NULL)
+ (void)xauth_reply(iph1, xra->port, xra->id, xra->res);
else
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Delayed Xauth reply: phase 1 no longer exists.\n");
racoon_free(xra);
return;
}
-void
+int
xauth_reply(iph1, port, id, res)
- struct ph1handle *iph1;
+ phase1_handle_t *iph1;
int port;
int id;
{
struct xauth_state *xst = &iph1->mode_cfg->xauth;
char *usr = xst->authdata.generic.usr;
+ if (iph1->is_dying) {
+ plog(ASL_LEVEL_NOTICE,
+ "dropped login for user \"%s\"\n", usr);
+ return -1;
+ }
+
if (res != 0) {
if (port != -1)
isakmp_cfg_putport(iph1, port);
- plog(LLV_INFO, LOCATION, NULL,
+ plog(ASL_LEVEL_NOTICE,
"login failed for user \"%s\"\n", usr);
xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
xst->status = XAUTHST_NOTYET;
/* Delete Phase 1 SA */
- if (iph1->status == PHASE1ST_ESTABLISHED)
+ if (FSM_STATE_IS_ESTABLISHED(iph1->status))
isakmp_info_send_d1(iph1);
- remph1(iph1);
- delph1(iph1);
+ isakmp_ph1expire(iph1);
- return;
+ return -1;
}
xst->status = XAUTHST_OK;
- plog(LLV_INFO, LOCATION, NULL,
+ plog(ASL_LEVEL_NOTICE,
"login succeeded for user \"%s\"\n", usr);
xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
- return;
+ return 0;
}
void
xauth_sendstatus(iph1, status, id)
- struct ph1handle *iph1;
+ phase1_handle_t *iph1;
int status;
int id;
{
+ sizeof(*stattr);
if ((buffer = vmalloc(tlen)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
+ plog(ASL_LEVEL_ERR, "Cannot allocate buffer\n");
return;
}
stattr->lorv = htons(status);
isakmp_cfg_send(iph1, buffer,
- ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
+ ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL);
vfree(buffer);
return;
}
-#ifdef HAVE_LIBRADIUS
-int
-xauth_radius_init(void)
-{
- /* For first time use, initialize Radius */
- if ((isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_RADIUS) &&
- (radius_auth_state == NULL)) {
- if ((radius_auth_state = rad_auth_open()) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Cannot init libradius\n");
- return -1;
- }
-
- if (rad_config(radius_auth_state, NULL) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Cannot open librarius config file: %s\n",
- rad_strerror(radius_auth_state));
- rad_close(radius_auth_state);
- radius_auth_state = NULL;
- return -1;
- }
- }
-
- if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) &&
- (radius_acct_state == NULL)) {
- if ((radius_acct_state = rad_auth_open()) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Cannot init libradius\n");
- return -1;
- }
-
- if (rad_config(radius_acct_state, NULL) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "Cannot open librarius config file: %s\n",
- rad_strerror(radius_acct_state));
- rad_close(radius_acct_state);
- radius_acct_state = NULL;
- return -1;
- }
- }
-
- return 0;
-}
-
-int
-xauth_login_radius(iph1, usr, pwd)
- struct ph1handle *iph1;
- char *usr;
- char *pwd;
-{
- int res;
- const void *data;
- size_t len;
- int type;
-
- if (rad_create_request(radius_auth_state, RAD_ACCESS_REQUEST) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "rad_create_request failed: %s\n",
- rad_strerror(radius_auth_state));
- return -1;
- }
-
- if (rad_put_string(radius_auth_state, RAD_USER_NAME, usr) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "rad_put_string failed: %s\n",
- rad_strerror(radius_auth_state));
- return -1;
- }
-
- if (rad_put_string(radius_auth_state, RAD_USER_PASSWORD, pwd) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "rad_put_string failed: %s\n",
- rad_strerror(radius_auth_state));
- return -1;
- }
-
- if (isakmp_cfg_radius_common(radius_auth_state, iph1->mode_cfg->port) != 0)
- return -1;
-
- switch (res = rad_send_request(radius_auth_state)) {
- case RAD_ACCESS_ACCEPT:
- while ((type = rad_get_attr(radius_auth_state, &data, &len)) != 0) {
- switch (type) {
- case RAD_FRAMED_IP_ADDRESS:
- iph1->mode_cfg->addr4 = rad_cvt_addr(data);
- iph1->mode_cfg->flags
- |= ISAKMP_CFG_ADDR4_RADIUS;
- break;
-
- case RAD_FRAMED_IP_NETMASK:
- iph1->mode_cfg->mask4 = rad_cvt_addr(data);
- iph1->mode_cfg->flags
- |= ISAKMP_CFG_MASK4_RADIUS;
- break;
-
- default:
- plog(LLV_INFO, LOCATION, NULL,
- "Unexpected attribute: %d\n", type);
- break;
- }
- }
-
- return 0;
- break;
-
- case RAD_ACCESS_REJECT:
- return -1;
- break;
-
- case -1:
- plog(LLV_ERROR, LOCATION, NULL,
- "rad_send_request failed: %s\n",
- rad_strerror(radius_auth_state));
- return -1;
- break;
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "rad_send_request returned %d\n", res);
- return -1;
- break;
- }
-
- return -1;
-}
-#endif
-
-#ifdef HAVE_LIBPAM
-static int
-PAM_conv(msg_count, msg, rsp, dontcare)
- int msg_count;
- const struct pam_message **msg;
- struct pam_response **rsp;
- void *dontcare;
-{
- int i;
- int replies = 0;
- struct pam_response *reply = NULL;
-
- if ((reply = racoon_malloc(sizeof(*reply) * msg_count)) == NULL)
- return PAM_CONV_ERR;
- bzero(reply, sizeof(*reply) * msg_count);
-
- for (i = 0; i < msg_count; i++) {
- switch (msg[i]->msg_style) {
- case PAM_PROMPT_ECHO_ON:
- /* Send the username, libpam frees resp */
- reply[i].resp_retcode = PAM_SUCCESS;
- reply[i].resp = strdup(PAM_usr);
- break;
-
- case PAM_PROMPT_ECHO_OFF:
- /* Send the password, libpam frees resp */
- reply[i].resp_retcode = PAM_SUCCESS;
- reply[i].resp = strdup(PAM_pwd);
- break;
-
- case PAM_TEXT_INFO:
- case PAM_ERROR_MSG:
- reply[i].resp_retcode = PAM_SUCCESS;
- reply[i].resp = NULL;
- break;
-
- default:
- if (reply != NULL)
- racoon_free(reply);
- return PAM_CONV_ERR;
- break;
- }
- }
-
- if (reply != NULL)
- *rsp = reply;
-
- return PAM_SUCCESS;
-}
-
-int
-xauth_login_pam(port, raddr, usr, pwd)
- int port;
- struct sockaddr *raddr;
- char *usr;
- char *pwd;
-{
- int error;
- int res;
- const void *data;
- size_t len;
- int type;
- char *remote;
- pam_handle_t *pam = NULL;
-
- if (isakmp_cfg_config.port_pool == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "isakmp_cfg_config.port_pool == NULL\n");
- return -1;
- }
-
- if ((error = pam_start("racoon", usr,
- &PAM_chat, &isakmp_cfg_config.port_pool[port].pam)) != 0) {
- if (isakmp_cfg_config.port_pool[port].pam == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "pam_start failed\n");
- return -1;
- } else {
- plog(LLV_ERROR, LOCATION, NULL,
- "pam_start failed: %s\n",
- pam_strerror(isakmp_cfg_config.port_pool[port].pam,
- error));
- goto out;
- }
- }
- pam = isakmp_cfg_config.port_pool[port].pam;
-
- if ((remote = strdup(saddrwop2str(raddr))) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "cannot allocate memory: %s\n", strerror(errno));
- goto out;
- }
-
- if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "pam_set_item failed: %s\n",
- pam_strerror(pam, error));
- goto out;
- }
-
- PAM_usr = usr;
- PAM_pwd = pwd;
- error = pam_authenticate(pam, 0);
- PAM_usr = NULL;
- PAM_pwd = NULL;
- if (error != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "pam_authenticate failed: %s\n",
- pam_strerror(pam, error));
- goto out;
- }
-
- if ((error = pam_acct_mgmt(pam, 0)) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "pam_acct_mgmt failed: %s\n",
- pam_strerror(pam, error));
- goto out;
- }
-
- if ((error = pam_setcred(pam, 0)) != 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "pam_setcred failed: %s\n",
- pam_strerror(pam, error));
- goto out;
- }
-
- return 0;
-
-out:
- pam_end(pam, error);
- isakmp_cfg_config.port_pool[port].pam = NULL;
- return -1;
-}
-#endif
int
xauth_login_system(usr, pwd)
return -1;
}
+int
+xauth_group_system(usr, grp)
+ char * usr;
+ char * grp;
+{
+ struct group * gr;
+ char * member;
+ int index = 0;
+
+ gr = getgrnam(grp);
+ if (gr == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "the system group name \'%s\' is unknown\n",
+ grp);
+ return -1;
+ }
+
+ while ((member = gr->gr_mem[index++])!=NULL) {
+ if (!strcmp(member,usr)) {
+ plog(ASL_LEVEL_NOTICE,
+ "membership validated\n");
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
int
xauth_check(iph1)
- struct ph1handle *iph1;
+ phase1_handle_t *iph1;
{
struct xauth_state *xst = &iph1->mode_cfg->xauth;
- /* If we don't use Xauth, then we pass */
- switch (iph1->approval->authmethod) {
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
- case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
+ /*
+ * Only the server side (edge device) really check for Xauth
+ * status. It does it if the chose authmethod is using Xauth.
+ * On the client side (roadwarrior), we don't check anything.
+ */
+ switch (AUTHMETHOD(iph1)) {
+ case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
/* The following are not yet implemented */
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
- case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Hybrid auth negotiated but peer did not "
"announced as Xauth capable\n");
return -1;
}
if (xst->status != XAUTHST_OK) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Hybrid auth negotiated but peer did not "
"succeed Xauth exchange\n");
return -1;
return 0;
}
+int
+group_check(iph1, grp_list, grp_count)
+ phase1_handle_t *iph1;
+ char **grp_list;
+ int grp_count;
+{
+ int res = -1;
+ int grp_index = 0;
+ char * usr = NULL;
+
+ /* check for presence of modecfg data */
+
+ if(iph1->mode_cfg == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "xauth group specified but modecfg not found\n");
+ return res;
+ }
+
+ /* loop through our group list */
+
+ for(; grp_index < grp_count; grp_index++) {
+
+ /* check for presence of xauth data */
+
+ usr = iph1->mode_cfg->xauth.authdata.generic.usr;
+
+ if(usr == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "xauth group specified but xauth not found\n");
+ return res;
+ }
+
+ /* call appropriate group validation funtion */
+
+ switch (isakmp_cfg_config.groupsource) {
+
+ case ISAKMP_CFG_GROUP_SYSTEM:
+ res = xauth_group_system(
+ usr,
+ grp_list[grp_index]);
+ break;
+
+ default:
+ /* we should never get here */
+ plog(ASL_LEVEL_ERR,
+ "Unknown group auth source\n");
+ break;
+ }
+
+ if( !res ) {
+ plog(ASL_LEVEL_NOTICE,
+ "user \"%s\" is a member of group \"%s\"\n",
+ usr,
+ grp_list[grp_index]);
+ break;
+ } else {
+ plog(ASL_LEVEL_NOTICE,
+ "user \"%s\" is not a member of group \"%s\"\n",
+ usr,
+ grp_list[grp_index]);
+ }
+ }
+
+ return res;
+}
+
vchar_t *
isakmp_xauth_req(iph1, attr)
- struct ph1handle *iph1;
+ phase1_handle_t *iph1;
struct isakmp_data *attr;
{
int type;
int ashort = 0;
int value = 0;
vchar_t *buffer = NULL;
+ char* mraw = NULL;
+ vchar_t *mdata = NULL;
char *data;
vchar_t *usr = NULL;
vchar_t *pwd = NULL;
int freepwd = 0;
if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Xauth mode config request but peer "
"did not declare itself as Xauth capable\n");
return NULL;
switch(type) {
case XAUTH_TYPE:
if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Unexpected long XAUTH_TYPE attribute\n");
return NULL;
}
if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Unsupported Xauth authentication %d\n",
ntohs(attr->lorv));
return NULL;
break;
case XAUTH_USER_NAME:
- if (iph1->rmconf->idvtype != IDTYPE_LOGIN) {
- plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
- "while identifier is not a login\n");
- return NULL;
- }
-
- if (iph1->rmconf->idv == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
+ if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
+ plog(ASL_LEVEL_ERR, "Xauth performed "
"with no login supplied\n");
return NULL;
}
- dlen = iph1->rmconf->idv->l;
+ dlen = iph1->rmconf->xauth->login->l - 1;
+ iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
break;
case XAUTH_USER_PASSWORD:
- if (iph1->rmconf->idvtype != IDTYPE_LOGIN)
- return NULL;
-
- if (iph1->rmconf->idv == NULL)
+ case XAUTH_PASSCODE:
+ if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
return NULL;
skip = sizeof(struct ipsecdoi_id_b);
- if ((usr = vmalloc(iph1->rmconf->idv->l + skip)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
+ if (usr == NULL) {
+ plog(ASL_LEVEL_ERR,
"Cannot allocate memory\n");
return NULL;
}
-
memset(usr->v, 0, skip);
memcpy(usr->v + skip,
- iph1->rmconf->idv->v,
- iph1->rmconf->idv->l);
+ iph1->rmconf->xauth->login->v,
+ iph1->rmconf->xauth->login->l - 1);
- if (iph1->rmconf->key) {
+ if (iph1->rmconf->xauth->pass) {
/* A key given through racoonctl */
- pwd = iph1->rmconf->key;
+ pwd = iph1->rmconf->xauth->pass;
} else {
if ((pwd = getpskbyname(usr)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"No password was found for login %s\n",
- iph1->rmconf->idv->v);
+ iph1->rmconf->xauth->login->v);
vfree(usr);
return NULL;
}
}
vfree(usr);
- dlen = pwd->l;
+ iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
+ dlen = pwd->l - 1;
break;
-
+
+ case XAUTH_MESSAGE:
+ if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
+ dlen = ntohs(attr->lorv);
+ if (dlen > 0) {
+ mraw = (char*)(attr + 1);
+ if ((mdata = vmalloc(dlen)) == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "Cannot allocate memory\n");
+ return NULL;
+ }
+ memcpy(mdata->v, mraw, mdata->l);
+ plog(ASL_LEVEL_NOTICE, "XAUTH Message: '%s'.\n",
+ binsanitize(mdata->v, mdata->l));
+ vfree(mdata);
+ }
+ }
+ return NULL;
default:
- plog(LLV_WARNING, LOCATION, NULL,
- "Ignored attribute %d\n", type);
+ plog(ASL_LEVEL_WARNING,
+ "Ignored attribute %s\n", s_isakmp_cfg_type(type));
return NULL;
break;
}
if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"Cannot allocate memory\n");
goto out;
}
switch(type) {
case XAUTH_USER_NAME:
- memcpy(data, iph1->rmconf->idv->v, dlen);
+ /*
+ * iph1->rmconf->xauth->login->v is valid,
+ * we just checked it in the previous switch case
+ */
+ memcpy(data, iph1->rmconf->xauth->login->v, dlen);
break;
case XAUTH_USER_PASSWORD:
+ case XAUTH_PASSCODE:
memcpy(data, pwd->v, dlen);
break;
default:
vchar_t *
isakmp_xauth_set(iph1, attr)
- struct ph1handle *iph1;
+ phase1_handle_t *iph1;
struct isakmp_data *attr;
{
int type;
vchar_t *buffer = NULL;
- char *data;
+ struct xauth_state *xst;
+ size_t dlen = 0;
+ char* mraw = NULL;
+ vchar_t *mdata = NULL;
if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ IPSECSESSIONTRACEREVENT(iph1->parent_session,
+ IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+ CONSTSTR("XAUTH is not supported by peer"),
+ CONSTSTR("XAUTH dropped (not supported by peer)"));
+ plog(ASL_LEVEL_ERR,
"Xauth mode config set but peer "
"did not declare itself as Xauth capable\n");
return NULL;
switch(type) {
case XAUTH_STATUS:
+ /*
+ * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS
+ * when running as a client (initiator).
+ */
+ xst = &iph1->mode_cfg->xauth;
+ switch(AUTHMETHOD(iph1)) {
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+ if (!iph1->is_rekey) {
+ IPSECSESSIONTRACEREVENT(iph1->parent_session,
+ IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+ CONSTSTR("Unexpected XAUTH Status"),
+ CONSTSTR("Xauth dropped (unexpected Xauth status)... not a Phase 1 rekey"));
+ plog(ASL_LEVEL_ERR,
+ "Unexpected XAUTH_STATUS_OK... not a Phase 1 rekey\n");
+ return NULL;
+ }
+ case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
+ case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
+ /* Not implemented ... */
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
+ case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
+ break;
+ default:
+ IPSECSESSIONTRACEREVENT(iph1->parent_session,
+ IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+ CONSTSTR("Unexpected XAUTH Status"),
+ CONSTSTR("Xauth dropped (unexpected Xauth status)"));
+ plog(ASL_LEVEL_ERR,
+ "Unexpected XAUTH_STATUS_OK\n");
+ return NULL;
+ break;
+ }
+
/* If we got a failure, delete iph1 */
if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
- plog(LLV_ERROR, LOCATION, NULL,
+ IPSECSESSIONTRACEREVENT(iph1->parent_session,
+ IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL,
+ CONSTSTR("XAUTH Status is not OK"),
+ CONSTSTR("Xauth Failed (status not ok)"));
+ plog(ASL_LEVEL_ERR,
"Xauth authentication failed\n");
- EVT_PUSH(iph1->local, iph1->remote,
- EVTT_XAUTH_FAILED, NULL);
+ vpncontrol_notify_ike_failed(VPNCTL_NTYPE_AUTHENTICATION_FAILED, FROM_LOCAL,
+ iph1_get_remote_v4_address(iph1), 0, NULL);
iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
+
+ IPSECLOGASLMSG("IPSec Extended Authentication Failed.\n");
} else {
- EVT_PUSH(iph1->local,
- iph1->remote, EVTT_XAUTH_SUCCESS, NULL);
+ IPSECSESSIONTRACEREVENT(iph1->parent_session,
+ IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC,
+ CONSTSTR("XAUTH Status is OK"),
+ CONSTSTR(NULL));
+ if (iph1->is_rekey) {
+ xst->status = XAUTHST_OK;
+ }
+
+ IPSECLOGASLMSG("IPSec Extended Authentication Passed.\n");
}
/* We acknowledge it */
break;
+ case XAUTH_MESSAGE:
+ if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
+ dlen = ntohs(attr->lorv);
+ if (dlen > 0) {
+ mraw = (char*)(attr + 1);
+ if ((mdata = vmalloc(dlen)) == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "Cannot allocate memory\n");
+ return NULL;
+ }
+ memcpy(mdata->v, mraw, mdata->l);
+ plog(ASL_LEVEL_NOTICE, "XAUTH Message: '%s'.\n",
+ binsanitize(mdata->v, mdata->l));
+ vfree(mdata);
+ }
+ }
+
default:
- plog(LLV_WARNING, LOCATION, NULL,
- "Ignored attribute %d\n", type);
+ IPSECSESSIONTRACEREVENT(iph1->parent_session,
+ IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+ CONSTSTR("ignored attribute"),
+ CONSTSTR("Xauth dropped (ignored attribute)"));
+ plog(ASL_LEVEL_WARNING,
+ "Ignored attribute %s\n", s_isakmp_cfg_type(type));
return NULL;
break;
}
if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ IPSECSESSIONTRACEREVENT(iph1->parent_session,
+ IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
+ CONSTSTR("Failed to allocate attribute"),
+ CONSTSTR("Xauth dropped (failed to allocate attribute)"));
+ plog(ASL_LEVEL_ERR,
"Cannot allocate memory\n");
return NULL;
}
case XAUTH_TYPE_CHAP:
case XAUTH_TYPE_OTP:
case XAUTH_TYPE_SKEY:
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_WARNING,
"Unsupported authtype %d\n", xst->authtype);
break;
default:
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_WARNING,
"Unexpected authtype %d\n", xst->authtype);
break;
}
return;
}
+int
+xauth_rmconf_used(xauth_rmconf)
+ struct xauth_rmconf **xauth_rmconf;
+{
+ if (*xauth_rmconf == NULL) {
+ *xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf));
+ if (*xauth_rmconf == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "xauth_rmconf_used: malloc failed\n");
+ return -1;
+ }
+
+ (*xauth_rmconf)->login = NULL;
+ (*xauth_rmconf)->pass = NULL;
+ (*xauth_rmconf)->state = 0;
+ } else {
+ if ((*xauth_rmconf)->login) {
+ vfree((*xauth_rmconf)->login);
+ (*xauth_rmconf)->login = NULL;
+ }
+ if ((*xauth_rmconf)->pass != NULL) {
+ vfree((*xauth_rmconf)->pass);
+ (*xauth_rmconf)->pass = NULL;
+ }
+ (*xauth_rmconf)->state = 0;
+ }
+
+ return 0;
+}
+
+void
+xauth_rmconf_delete(xauth_rmconf)
+ struct xauth_rmconf **xauth_rmconf;
+{
+ if (*xauth_rmconf != NULL) {
+ if ((*xauth_rmconf)->login != NULL)
+ vfree((*xauth_rmconf)->login);
+ if ((*xauth_rmconf)->pass != NULL)
+ vfree((*xauth_rmconf)->pass);
+
+ racoon_free(*xauth_rmconf);
+ *xauth_rmconf = NULL;
+ }
+
+ return;
+}