?? xauth.c
字號:
{ openswan_log("Attribute was too short: %d", len); return STF_FAIL; } attrs->cur += len; continue; } if (attr.isaat_af_type & 0x8000) { len = 4; val = attr.isaat_lv; } else { len = attr.isaat_lv; val = ntohs(*(u_int16_t *)strattr.cur); } switch(attr.isaat_af_type) { case XAUTH_TYPE: if(val != 0) return NO_PROPOSAL_CHOSEN; break; case XAUTH_USER_NAME: clonetochunk(name,strattr.cur,attr.isaat_lv+1,"username"); name.ptr[name.len-1] = 0; /* Pass NULL terminated strings */ gotname = TRUE; break; case XAUTH_USER_PASSWORD: clonetochunk(password,strattr.cur,attr.isaat_lv+1,"password"); password.ptr[password.len-1] = 0; gotpassword = TRUE; break; default: openswan_log("XAUTH: Unsupported XAUTH parameter %s received." , enum_show(&modecfg_attr_names, attr.isaat_af_type)); break; } } } /** we must get a username and a password value */ if(!gotname || !gotpassword) { openswan_log("Expected MODE_CFG_REPLY did not contain %s%s%s attribute" , (!gotname ? "username" : "") , ((!gotname && !gotpassword) ? " or " : "") , (!gotpassword ? "password" : "")); if(st->hidden_variables.st_xauth_client_attempt++ < XAUTH_PROMPT_TRIES) { stf_status stat = xauth_send_request(st); openswan_log("XAUTH: User %s: Authentication Failed (retry %d)" , (!gotname ? "<unknown>" : (char *)name.ptr) , st->hidden_variables.st_xauth_client_attempt); /** * STF_OK means that we transmitted again okay, but actually * the state transition failed, as we are prompting again. */ if(stat == STF_OK) { return STF_IGNORE; } else { return stat; } } else { stf_status stat = xauth_send_status(st, FALSE); openswan_log("XAUTH: User %s: Authentication Failed (Retried %d times)" , (!gotname ? "<unknown>" : (char *)name.ptr) , st->hidden_variables.st_xauth_client_attempt); if(stat == STF_OK) { return STF_FAIL; } else { return stat; } } } else { clonetochunk(connname , st->st_connection->name , strlen(st->st_connection->name)+1 ,"connname"); connname.ptr[connname.len-1] = 0; /* Pass NULL terminated strings */ xauth_launch_authent(st,name,password,connname); } return STF_IGNORE;}/** STATE_XAUTH_R1: * STATUS sent, expect for ACK * HDR*, ATTR(STATUS), HASH --> Done * * @param md Message Digest * @return stf_status */stf_statusxauth_inR1(struct msg_digest *md){ struct state *const st = md->st; openswan_log("XAUTH: xauth_inR1(STF_OK)"); /* Back to where we were */ st->st_oakley.xauth = 0; if(!st->st_connection->spd.this.modecfg_server) { DBG(DBG_CONTROL , DBG_log("Not server, starting new exchange")); st->st_msgid_phase15 = 0; } if(st->st_connection->spd.this.modecfg_server && st->hidden_variables.st_modecfg_vars_set) { DBG(DBG_CONTROL , DBG_log("modecfg server, vars are set. Starting new exchange.")); st->st_msgid_phase15 = 0; } if(st->st_connection->spd.this.modecfg_server && st->st_connection->policy & POLICY_MODECFG_PULL) { DBG(DBG_CONTROL , DBG_log("modecfg server, pull mode. Starting new exchange.")); st->st_msgid_phase15 = 0; } return STF_OK;}/* * * STATE_MODE_CFG_R0: * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP) * * This state occurs both in the responder and in the initiator. * * In the responding server, it occurs when the client *asks* for an IP * address or other information. * * Otherwise, it occurs in the initiator when the server sends a challenge * a set, or has a reply to our request. * * @param md Message Digest * @return stf_status */stf_statusmodecfg_inR0(struct msg_digest *md){ struct state *const st = md->st; struct payload_digest *p; pb_stream *attrs; stf_status stat; DBG(DBG_CONTROLMORE, DBG_log("arrived in modecfg_inR0")); st->st_msgid_phase15 = md->hdr.isa_msgid; CHECK_QUICK_HASH(md ,xauth_mode_cfg_hash(hash_val ,hash_pbs->roof , md->message_pbs.roof, st) , "MODECFG-HASH", "MODE R0"); /* process the MODECFG payloads therein */ for(p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next) { struct isakmp_attribute attr; pb_stream strattr; unsigned int resp = LEMPTY; attrs = &p->pbs; switch(p->payload.attribute.isama_type) { default: openswan_log("Expecting ISAKMP_CFG_REQUEST, got %s instead (ignored)." , enum_name(&attr_msg_type_names , p->payload.attribute.isama_type)); while(pbs_left(attrs) > sizeof(struct isakmp_attribute)) { if (!in_struct(&attr, &isakmp_xauth_attribute_desc, attrs, &strattr)) { /* Skip unknown */ int len; if (attr.isaat_af_type & 0x8000) len = 4; else len = attr.isaat_lv; if(len < 4) { openswan_log("Attribute was too short: %d", len); return STF_FAIL; } attrs->cur += len; } openswan_log("ignored mode cfg attribute %s." , enum_show(&modecfg_attr_names , (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ))); } break; case ISAKMP_CFG_REQUEST: while(pbs_left(attrs) > sizeof(struct isakmp_attribute)) { if (!in_struct(&attr, &isakmp_xauth_attribute_desc, attrs, &strattr)) { /* Skip unknown */ int len; if (attr.isaat_af_type & 0x8000) len = 4; else len = attr.isaat_lv; if(len < 4) { openswan_log("Attribute was too short: %d", len); return STF_FAIL; } attrs->cur += len; } switch(attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ) { case INTERNAL_IP4_ADDRESS: case INTERNAL_IP4_NETMASK: case INTERNAL_IP4_DNS: case INTERNAL_IP4_SUBNET: case INTERNAL_IP4_NBNS: resp |= LELEM(attr.isaat_af_type); break; default: openswan_log("unsupported mode cfg attribute %s received." , enum_show(&modecfg_attr_names , (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ))); break; } } stat = modecfg_resp(st, resp ,&md->rbody ,ISAKMP_CFG_REPLY ,TRUE ,p->payload.attribute.isama_identifier); if(stat != STF_OK) { /* notification payload - not exactly the right choice, but okay */ md->note = CERTIFICATE_UNAVAILABLE; return stat; } /* they asked us, we reponsed, msgid is done */ st->st_msgid_phase15 = 0; } } openswan_log("modecfg_inR0(STF_OK)"); return STF_OK;}/** STATE_MODE_CFG_R2: * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK) * * used in server push mode, on the client (initiator). * * @param md Message Digest * @return stf_status */static stf_statusmodecfg_inI2(struct msg_digest *md){ struct state *const st = md->st; pb_stream *attrs = &md->chain[ISAKMP_NEXT_ATTR]->pbs; int resp = LEMPTY; stf_status stat; struct payload_digest *p; u_int16_t isama_id = 0; DBG(DBG_CONTROL, DBG_log("modecfg_inI2")); st->st_msgid_phase15 = md->hdr.isa_msgid; CHECK_QUICK_HASH(md , xauth_mode_cfg_hash(hash_val ,hash_pbs->roof , md->message_pbs.roof , st) , "MODECFG-HASH", "MODE R1"); for(p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next) { struct isakmp_attribute attr; pb_stream strattr; isama_id = p->payload.attribute.isama_identifier; if (p->payload.attribute.isama_type != ISAKMP_CFG_SET) { openswan_log("Expecting MODE_CFG_SET, got %x instead." ,md->chain[ISAKMP_NEXT_ATTR]->payload.attribute.isama_type); return STF_IGNORE; } /* CHECK that SET has been received. */ while(pbs_left(attrs) > sizeof(struct isakmp_attribute)) { if (!in_struct(&attr, &isakmp_xauth_attribute_desc , attrs, &strattr)) { /* Skip unknown */ int len; if (attr.isaat_af_type & 0x8000) len = 4; else len = attr.isaat_lv; if(len < 4) { openswan_log("Attribute was too short: %d", len); return STF_FAIL; } attrs->cur += len; } switch(attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ) { case INTERNAL_IP4_ADDRESS: { struct connection *c = st->st_connection; ip_address a; char caddr[SUBNETTOT_BUF]; u_int32_t *ap = (u_int32_t *)(strattr.cur); a.u.v4.sin_family = AF_INET; memcpy(&a.u.v4.sin_addr.s_addr, ap , sizeof(a.u.v4.sin_addr.s_addr)); addrtosubnet(&a, &c->spd.this.client); /* make sure that the port info is zeroed */ setportof(0, &c->spd.this.client.addr); c->spd.this.has_client = TRUE; subnettot(&c->spd.this.client, 0 , caddr, sizeof(caddr)); openswan_log("setting client address to %s", caddr); if(addrbytesptr(&c->spd.this.host_srcip, NULL) == 0 || isanyaddr(&c->spd.this.host_srcip)) { openswan_log("setting ip source address to %s" , caddr); c->spd.this.host_srcip = a; } } resp |= LELEM(attr.isaat_af_type); break; case INTERNAL_IP4_NETMASK: case INTERNAL_IP4_DNS: case INTERNAL_IP4_SUBNET: case INTERNAL_IP4_NBNS: resp |= LELEM(attr.isaat_af_type); break; default: openswan_log("unsupported mode cfg attribute %s received." , enum_show(&modecfg_attr_names, (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ))); break; } } /* loglog(LOG_DEBUG,"ModeCfg ACK: %x",resp); */ } /* ack things */ stat = modecfg_resp(st, resp ,&md->rbody ,ISAKMP_CFG_ACK ,FALSE ,isama_id); if(stat != STF_OK) { /* notification payload - not exactly the right choice, but okay */ md->note = CERTIFICATE_UNAVAILABLE; return stat; } /* * we are done with this exchange, clear things so * that we can start phase 2 properly */ st->st_msgid_phase15 = 0; if(resp) { st->hidden_variables.st_modecfg_vars_set = TRUE; } DBG(DBG_CONTROL, DBG_log("modecfg_inI2(STF_OK)")); return STF_OK;}/** STATE_MODE_CFG_R1: * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK) * * @param md Message Digest * @return stf_status */stf_statusmodecfg_inR1(struct msg_digest *md){ struct state *const st = md->st; pb_stream *attrs = &md->chain[ISAKMP_NEXT_ATTR]->pbs; int resp = LEMPTY; struct payload_digest *p; DBG(DBG_CONTROL, DBG_log("modecfg_inR1")); openswan_log("received mode cfg reply"); st->st_msgid_phase15 = md->hdr.isa_msgid; CHECK_QUICK_HASH(md,xauth_mode_cfg_hash(hash_val,hash_pbs->roof, md->message_pbs.roof, st) , "MODECFG-HASH", "MODE R1"); /* process the MODECFG payloads therein */ for(p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next) { struct isakmp_attribute attr; pb_stream strattr; attrs = &p->pbs; switch(p->payload.attribute.isama_type) { default: { openswan_log("Expecting MODE_CFG_ACK, got %x instead.",md->chain[ISAKMP_NEXT_ATTR]->payload.attribute.isama_type); return STF_IGNORE; } break; case ISAKMP_CFG_ACK: /* CHECK that ACK has been received. */ while(pbs_left(attrs) > sizeof(struct isakmp_attribute)) { if (!in_struct(&attr, &isakmp_xauth_attribute_desc , attrs, &strattr)) { /* Skip unknown */ int len; if (attr.isaat_af_type & 0x8000) len = 4; else len = attr.isaat_lv; if(len < 4) { openswan_log("Attribute was too short: %d", len); return STF_FAIL; } attrs->cur += len; } switch(attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ) { case INTERNAL_IP4_ADDRESS: case INTERNAL_IP4_NETMASK: case INTERNAL_IP4_DNS: case INTERNAL_IP4_SUBNET: case INTERNAL_IP4_NBNS: resp |= LELEM(attr.isaat_af_type); break; default: openswan_log("unsupported mode cfg attribute %s received." , enum_show(&modecfg_attr_names, (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ))); break; } } break; case ISAKMP_CFG_REPLY: while(pbs_left(attrs) > sizeof(struct isakmp_attribute)) { if (!in_struct(&attr, &isakmp_xauth_attribute_desc , attrs, &strattr)) { /* Skip unknown */ int len; if (attr.isaat_af_type & 0x8000) len = 4; else len = attr.isaat_lv; if(len < 4) { openswan_log("Attribute was too short: %d", len); return STF_FAIL; } attrs->cur += len; } switch(attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ) { case INTERNAL_IP4_ADDRESS: { struct connection *c = st->st_connection; ip_address a; char caddr[SUBNETTOT_BUF]; u_int32_t *ap = (u_int32_t *)(strattr.cur); a.u.v4.sin_family = AF_INET; memcpy(&a.u.v4.sin_addr.s_addr, ap , sizeof(a.u.v4.sin_addr.s_addr)); addrtosubnet(&a, &c->spd.this.client); /* make sure that the port info is zeroed */ setportof(0, &c->spd.this.client.addr); c->spd.this.has_client = TRUE; subnettot(&c->spd.this.client, 0 , caddr, sizeof(caddr)); openswan_log("setting client address to %s" , caddr); if(addrbytesptr(&c->spd.this.host_srcip, NULL) == 0 || isanyaddr(&c->spd.this.host_srcip)) { openswan_log("setting ip source address to %s" , caddr); c->spd.this.host_srcip = a; } } resp |= LELEM(attr.isaat_af_type); break; case INTERNAL_IP4_NETMASK: case INTERNAL_IP4_DNS: case INTERNAL_IP4_SUBNET: case INTERNAL_IP4_NBNS: resp |= LELEM(attr.isaat_af_type); break; default: openswan_log("unsupported mode cfg attribute %s received." , enum_show(&modecfg_attr_names, (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ))); break; } } /* loglog(LOG_DEBUG,"ModeCfg ACK: %x",resp); */ break; /* loglog(LOG_DEBUG,"ModeCfg ACK: %x",resp); */ } } /* we are done with this exchange, clear things so that we can start phase 2 properly */ st->st_msgid_phase15 = 0; if(resp) { st->hidden_variables.st_modecfg_vars_set = TRUE; } DBG(DBG_CONTROL, DBG_log("modecfg_inR1(STF_OK)")); return STF_OK;}/** XAUTH client code - response to challenge. May open filehandle to console * in order to prompt user for password * * @param st State * @param xauth_resp XAUTH Reponse * @param rbody Reply Body * @param ap_id * @return stf_status */stf_status xauth_client_resp(struct state *st ,unsigned int xauth_resp
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -