*/
offset = 8;
if ((length & (1 << 31)) != 0) {
- int attribute;
uint32_t vendor;
DICT_ATTR *da;
memcpy(&vendor, data, sizeof(vendor));
vendor = ntohl(vendor);
- if (vendor > 65535) {
- RDEBUG2("Vendor codes larger than 65535 are not supported");
+ if (vendor > FR_MAX_VENDOR) {
+ RDEBUG2("Vendor codes larger than 2^24 are not supported");
return 0;
}
- attribute = (vendor << 16) | attr;
-
- da = dict_attrbyvalue(attribute);
+ da = dict_attrbyvalue(attr, vendor);
/*
* SHOULD check ((length & (1 << 30)) != 0)
const uint8_t *data, size_t data_len)
{
uint32_t attr;
+ uint32_t vendor;
uint32_t length;
size_t offset;
size_t size;
memcpy(&attr, data, sizeof(attr));
data += 4;
attr = ntohl(attr);
+ vendor = 0;
memcpy(&length, data, sizeof(length));
data += 4;
*/
offset = 8;
if ((length & (1 << 31)) != 0) {
- uint32_t vendor;
-
memcpy(&vendor, data, sizeof(vendor));
vendor = ntohl(vendor);
- if (attr > 65535) {
- RDEBUG2("Cannot handle vendor attributes greater than 65535");
- pairfree(&first);
- return NULL;
- }
-
- if (vendor > 32767) {
- RDEBUG2("Cannot handle vendor Id greater than 32767");
+ if (vendor > FR_MAX_VENDOR) {
+ RDEBUG2("Cannot handle vendor Id greater than 2^&24");
pairfree(&first);
return NULL;
}
- attr |= (vendor << 16);
-
data += 4; /* skip the vendor field, it's zero */
offset += 4; /* offset to value field */
}
* Vendor attributes can be larger than 255.
* Normal attributes cannot be.
*/
- if ((attr > 255) && (VENDOR(attr) == 0)) {
+ if ((attr > 255) && (vendor == 0)) {
RDEBUG2("Cannot handle Diameter attributes");
pairfree(&first);
return NULL;
/*
* Create it.
*/
- vp = paircreate(attr, PW_TYPE_OCTETS);
+ vp = paircreate(attr, vendor, PW_TYPE_OCTETS);
if (!vp) {
RDEBUG2("Failure in creating VP");
pairfree(&first);
if (size == 0) break;
- vp = paircreate(attr, PW_TYPE_OCTETS);
+ vp = paircreate(attr, vendor, PW_TYPE_OCTETS);
if (!vp) {
RDEBUG2("Failure in creating VP");
pairfree(&first);
* issues.
*/
length = vp->length;
- vendor = (vp->attribute >> 16) & 0xffff;
+ vendor = vp->vendor;
if (vendor != 0) {
attr = vp->attribute & 0xffff;
length |= (1 << 31);
if ((debug_flag > 2) && fr_log_fp) {
for (i = 0; i < total; i++) {
- if ((i & 0x0f) == 0) fprintf(fr_log_fp, " TTLS tunnel data out %04x: ", i);
+ if ((i & 0x0f) == 0) fprintf(fr_log_fp, " TTLS tunnel data out %04x: ", (int) i);
fprintf(fr_log_fp, "%02x ", buffer[i]);
/*
* FIXME: Check the return code.
*/
- tls_handshake_send(tls_session);
+ tls_handshake_send(request, tls_session);
}
/*
ttls_tunnel_t *t = tls_session->opaque;
handler = handler; /* -Wunused */
+ rad_assert(request != NULL);
+ rad_assert(handler->request == request);
/*
* If the response packet was Access-Accept, then
* packet, and we will send EAP-Success.
*/
vp = NULL;
- pairmove2(&vp, &reply->vps, PW_MSCHAP2_SUCCESS);
+ pairmove2(&vp, &reply->vps, PW_MSCHAP2_SUCCESS, VENDORPEC_MICROSOFT);
if (vp) {
RDEBUG("Got MS-CHAP2-Success, tunneling it to the client in a challenge.");
rcode = RLM_MODULE_HANDLED;
* Delete MPPE keys & encryption policy. We don't
* want these here.
*/
- pairdelete(&reply->vps, ((311 << 16) | 7));
- pairdelete(&reply->vps, ((311 << 16) | 8));
- pairdelete(&reply->vps, ((311 << 16) | 16));
- pairdelete(&reply->vps, ((311 << 16) | 17));
+ pairdelete(&reply->vps, 7, VENDORPEC_MICROSOFT);
+ pairdelete(&reply->vps, 8, VENDORPEC_MICROSOFT);
+ pairdelete(&reply->vps, 16, VENDORPEC_MICROSOFT);
+ pairdelete(&reply->vps, 17, VENDORPEC_MICROSOFT);
/*
* Use the tunneled reply, but not now.
*/
if (t->use_tunneled_reply) {
- t->reply = reply->vps;
+ t->accept_vps = reply->vps;
reply->vps = NULL;
}
* can figure it out, from the non-tunneled
* EAP-Success packet.
*/
- pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE);
+ pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE, 0);
pairfree(&vp);
}
* tunneled user!
*/
if (t->use_tunneled_reply) {
- pairdelete(&reply->vps, PW_PROXY_STATE);
+ pairdelete(&reply->vps, PW_PROXY_STATE, 0);
pairadd(&request->reply->vps, reply->vps);
reply->vps = NULL;
}
* Get rid of the old State, too.
*/
pairfree(&t->state);
- pairmove2(&t->state, &reply->vps, PW_STATE);
+ pairmove2(&t->state, &reply->vps, PW_STATE, 0);
/*
* We should really be a bit smarter about this,
* method works in 99.9% of the situations.
*/
vp = NULL;
- pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE);
+ pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE, 0);
/*
* There MUST be a Reply-Message in the challenge,
* we MUST create one, with an empty string as
* it's value.
*/
- pairmove2(&vp, &reply->vps, PW_REPLY_MESSAGE);
+ pairmove2(&vp, &reply->vps, PW_REPLY_MESSAGE, 0);
/*
* Handle the ACK, by tunneling any necessary reply
}
+#ifdef WITH_PROXY
/*
* Do post-proxy processing,
*/
tls_session_t *tls_session = (tls_session_t *) data;
REQUEST *fake, *request = handler->request;
+ rad_assert(request != NULL);
RDEBUG("Passing reply from proxy back into the tunnel.");
/*
* Do the callback, if it exists, and if it was a success.
*/
if (fake && (handler->request->proxy_reply->code == PW_AUTHENTICATION_ACK)) {
- REQUEST *request = handler->request;
-
/*
* Terrible hacks.
*/
request->proxy_reply = NULL;
if ((debug_flag > 0) && fr_log_fp) {
- fprintf(fr_log_fp, "server %s {\n", fake->server);
+ fprintf(fr_log_fp, "server %s {\n",
+ (fake->server == NULL) ? "" : fake->server);
}
/*
RDEBUG2("post-auth returns %d", rcode);
if ((debug_flag > 0) && fr_log_fp) {
- fprintf(fr_log_fp, "} # server %s\n", fake->server);
+ fprintf(fr_log_fp, "} # server %s\n",
+ (fake->server == NULL) ? "" : fake->server);
RDEBUG("Final reply from tunneled session code %d",
fake->reply->code);
switch (rcode) {
case RLM_MODULE_FAIL:
request_free(&fake);
- eaptls_fail(handler->eap_ds, 0);
+ eaptls_fail(handler, 0);
return 0;
break;
default: /* Don't Do Anything */
- RDEBUG2("sGot reply %d",
+ RDEBUG2("Got reply %d",
request->proxy_reply->code);
break;
}
case RLM_MODULE_OK:
RDEBUG("Reply was OK");
- eaptls_success(handler->eap_ds, 0);
- eaptls_gen_mppe_keys(&handler->request->reply->vps,
- tls_session->ssl,
- "ttls keying material");
- return 1;
+
+ /*
+ * Success: Automatically return MPPE keys.
+ */
+ return eaptls_success(handler, 0);
default:
RDEBUG("Reply was unknown.");
break;
}
- eaptls_fail(handler->eap_ds, 0);
+ eaptls_fail(handler, 0);
return 0;
}
request_free(&request);
}
-
+#endif /* WITH_PROXY */
/*
* Process the "diameter" contents of the tunneled data.
*/
int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
{
- int err;
int rcode = PW_AUTHENTICATION_REJECT;
REQUEST *fake;
VALUE_PAIR *vp;
size_t data_len;
REQUEST *request = handler->request;
- /*
- * FIXME: if the SSL session says "want read", or
- * similar, leave the data in the clean_out buffer. This
- * lets the application data be sent across multiple
- * fragments.
- */
- err = tls_handshake_recv(tls_session);
- if (!err) {
- RDEBUG2("Failed in SSL");
- return RLM_MODULE_REJECT;
- }
+ rad_assert(request != NULL);
/*
* Just look at the buffer directly, without doing
size_t i;
for (i = 0; i < data_len; i++) {
- if ((i & 0x0f) == 0) fprintf(fr_log_fp, " TTLS tunnel data in %04x: ", i);
+ if ((i & 0x0f) == 0) fprintf(fr_log_fp, " TTLS tunnel data in %04x: ", (int) i);
fprintf(fr_log_fp, "%02x ", data[i]);
/*
* Tell the request that it's a fake one.
*/
- vp = pairmake("Freeradius-Proxied-T<o", "127.0.0.1", T_OP_EQ);
+ vp = pairmake("Freeradius-Proxied-To", "127.0.0.1", T_OP_EQ);
if (vp) {
pairadd(&fake->packet->vps, vp);
}
/*
* Update other items in the REQUEST data structure.
*/
- fake->username = pairfind(fake->packet->vps, PW_USER_NAME);
- fake->password = pairfind(fake->packet->vps, PW_USER_PASSWORD);
+ fake->username = pairfind(fake->packet->vps, PW_USER_NAME, 0);
+ fake->password = pairfind(fake->packet->vps, PW_USER_PASSWORD, 0);
/*
* No User-Name, try to create one from stored data.
* an EAP-Identity, and pull it out of there.
*/
if (!t->username) {
- vp = pairfind(fake->packet->vps, PW_EAP_MESSAGE);
+ vp = pairfind(fake->packet->vps, PW_EAP_MESSAGE, 0);
if (vp &&
(vp->length >= EAP_HEADER_LEN + 2) &&
(vp->vp_strvalue[0] == PW_EAP_RESPONSE) &&
*/
if (t->default_eap_type != 0) {
RDEBUG("Setting default EAP type for tunneled EAP session.");
- vp = paircreate(PW_EAP_TYPE,
+ vp = paircreate(PW_EAP_TYPE, 0,
PW_TYPE_INTEGER);
rad_assert(vp != NULL);
vp->vp_integer = t->default_eap_type;
if (t->username) {
vp = paircopy(t->username);
pairadd(&fake->packet->vps, vp);
- fake->username = pairfind(fake->packet->vps, PW_USER_NAME);
+ fake->username = pairfind(fake->packet->vps, PW_USER_NAME, 0);
}
} /* else the request ALREADY had a User-Name */
* don't copy it.
*/
if ((vp->attribute > 255) &&
- (((vp->attribute >> 16) & 0xffff) == 0)) {
+ (vp->vendor == 0)) {
continue;
}
* AND attributes which are copied there
* from below.
*/
- if (pairfind(fake->packet->vps, vp->attribute)) {
+ if (pairfind(fake->packet->vps, vp->attribute, vp->vendor)) {
continue;
}
* Don't copy from the head, we've already
* checked it.
*/
- copy = paircopy2(vp, vp->attribute);
+ copy = paircopy2(vp, vp->attribute, vp->vendor);
pairadd(&fake->packet->vps, copy);
}
}
- if ((vp = pairfind(request->config_items, PW_VIRTUAL_SERVER)) != NULL) {
+ if ((vp = pairfind(request->config_items, PW_VIRTUAL_SERVER, 0)) != NULL) {
fake->server = vp->vp_strvalue;
} else if (t->virtual_server) {
debug_pair_list(fake->packet->vps);
- fprintf(fr_log_fp, "server %s {\n", fake->server);
+ fprintf(fr_log_fp, "server %s {\n",
+ (fake->server == NULL) ? "" : fake->server);
}
/*
* attributes.
*/
if ((debug_flag > 0) && fr_log_fp) {
- fprintf(fr_log_fp, "} # server %s\n", fake->server);
+ fprintf(fr_log_fp, "} # server %s\n",
+ (fake->server == NULL) ? "" : fake->server);
RDEBUG("Got tunneled reply code %d", fake->reply->code);
*/
switch (fake->reply->code) {
case 0: /* No reply code, must be proxied... */
- vp = pairfind(fake->config_items, PW_PROXY_TO_REALM);
+#ifdef WITH_PROXY
+ vp = pairfind(fake->config_items, PW_PROXY_TO_REALM, 0);
if (vp) {
eap_tunnel_data_t *tunnel;
RDEBUG("Tunneled authentication will be proxied to %s", vp->vp_strvalue);
*/
pairmove2(&(request->config_items),
&(fake->config_items),
- PW_PROXY_TO_REALM);
+ PW_PROXY_TO_REALM, 0);
/*
* Seed the proxy packet with the
*/
rad_assert(request->proxy == NULL);
request->proxy = fake->packet;
+ memset(&request->proxy->src_ipaddr, 0,
+ sizeof(request->proxy->src_ipaddr));
+ memset(&request->proxy->src_ipaddr, 0,
+ sizeof(request->proxy->src_ipaddr));
+ request->proxy->src_port = 0;
+ request->proxy->dst_port = 0;
fake->packet = NULL;
rad_free(&fake->reply);
fake->reply = NULL;
*/
rcode = PW_STATUS_CLIENT;
- } else {
+ } else
+#endif /* WITH_PROXY */
+ {
RDEBUG("No tunneled reply was found for request %d , and the request was not proxied: rejecting the user.",
request->number);
rcode = PW_AUTHENTICATION_REJECT;