summaryrefslogtreecommitdiff
path: root/src/charon/plugins/eap_radius/radius_message.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/plugins/eap_radius/radius_message.c')
-rw-r--r--src/charon/plugins/eap_radius/radius_message.c476
1 files changed, 0 insertions, 476 deletions
diff --git a/src/charon/plugins/eap_radius/radius_message.c b/src/charon/plugins/eap_radius/radius_message.c
deleted file mode 100644
index 11a1d8dfc..000000000
--- a/src/charon/plugins/eap_radius/radius_message.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "radius_message.h"
-
-#include <daemon.h>
-#include <crypto/hashers/hasher.h>
-
-typedef struct private_radius_message_t private_radius_message_t;
-typedef struct rmsg_t rmsg_t;
-typedef struct rattr_t rattr_t;
-
-/**
- * RADIUS message header
- */
-struct rmsg_t {
- /** message code, radius_message_code_t */
- u_int8_t code;
- /** message identifier */
- u_int8_t identifier;
- /** length of Code, Identifier, Length, Authenticator and Attributes */
- u_int16_t length;
- /** message authenticator, MD5 hash */
- u_int8_t authenticator[HASH_SIZE_MD5];
- /** variable list of packed attributes */
- u_int8_t attributes[];
-} __attribute__((packed));
-
-/**
- * RADIUS message attribute.
- */
-struct rattr_t {
- /** attribute type, radius_attribute_type_t */
- u_int8_t type;
- /** length of the attriubte, including the Type, Length and Value fields */
- u_int8_t length;
- /** variable length attribute value */
- u_int8_t value[];
-} __attribute__((packed));
-
-/**
- * Private data of an radius_message_t object.
- */
-struct private_radius_message_t {
-
- /**
- * Public radius_message_t interface.
- */
- radius_message_t public;
-
- /**
- * message data, allocated
- */
- rmsg_t *msg;
-};
-
-ENUM_BEGIN(radius_message_code_names, RMC_ACCESS_REQUEST, RMC_ACCOUNTING_RESPONSE,
- "Access-Request",
- "Access-Accept",
- "Access-Reject",
- "Accounting-Request",
- "Accounting-Response");
-ENUM_NEXT(radius_message_code_names, RMC_ACCESS_CHALLENGE, RMC_ACCESS_CHALLENGE, RMC_ACCOUNTING_RESPONSE,
- "Access-Challenge");
-ENUM_END(radius_message_code_names, RMC_ACCESS_CHALLENGE);
-
-ENUM(radius_attribute_type_names, RAT_USER_NAME, RAT_MIP6_HOME_LINK_PREFIX,
- "User-Name",
- "User-Password",
- "CHAP-Password",
- "NAS-IP-Address",
- "NAS-Port",
- "Service-Type",
- "Framed-Protocol",
- "Framed-IP-Address",
- "Framed-IP-Netmask",
- "Framed-Routing",
- "Filter-Id",
- "Framed-MTU",
- "Framed-Compression",
- "Login-IP-Host",
- "Login-Service",
- "Login-TCP-Port",
- "Unassigned",
- "Reply-Message",
- "Callback-Number",
- "Callback-Id",
- "Unassigned",
- "Framed-Route",
- "Framed-IPX-Network",
- "State",
- "Class",
- "Vendor-Specific",
- "Session-Timeout",
- "Idle-Timeout",
- "Termination-Action",
- "Called-Station-Id",
- "Calling-Station-Id",
- "NAS-Identifier",
- "Proxy-State",
- "Login-LAT-Service",
- "Login-LAT-Node",
- "Login-LAT-Group",
- "Framed-AppleTalk-Link",
- "Framed-AppleTalk-Network",
- "Framed-AppleTalk-Zone",
- "Acct-Status-Type",
- "Acct-Delay-Time",
- "Acct-Input-Octets",
- "Acct-Output-Octets",
- "Acct-Session-Id",
- "Acct-Authentic",
- "Acct-Session-Time",
- "Acct-Input-Packets",
- "Acct-Output-Packets",
- "Acct-Terminate-Cause",
- "Acct-Multi-Session-Id",
- "Acct-Link-Count",
- "Acct-Input-Gigawords",
- "Acct-Output-Gigawords",
- "Unassigned",
- "Event-Timestamp",
- "Egress-VLANID",
- "Ingress-Filters",
- "Egress-VLAN-Name",
- "User-Priority-Table",
- "CHAP-Challenge",
- "NAS-Port-Type",
- "Port-Limit",
- "Login-LAT-Port",
- "Tunnel-Type",
- "Tunnel-Medium-Type",
- "Tunnel-Client-Endpoint",
- "Tunnel-Server-Endpoint",
- "Acct-Tunnel-Connection",
- "Tunnel-Password",
- "ARAP-Password",
- "ARAP-Features",
- "ARAP-Zone-Access",
- "ARAP-Security",
- "ARAP-Security-Data",
- "Password-Retry",
- "Prompt",
- "Connect-Info",
- "Configuration-Token",
- "EAP-Message",
- "Message-Authenticator",
- "Tunnel-Private-Group-ID",
- "Tunnel-Assignment-ID",
- "Tunnel-Preference",
- "ARAP-Challenge-Response",
- "Acct-Interim-Interval",
- "Acct-Tunnel-Packets-Lost",
- "NAS-Port-Id",
- "Framed-Pool",
- "CUI",
- "Tunnel-Client-Auth-ID",
- "Tunnel-Server-Auth-ID",
- "NAS-Filter-Rule",
- "Unassigned",
- "Originating-Line-Info",
- "NAS-IPv6-Address",
- "Framed-Interface-Id",
- "Framed-IPv6-Prefix",
- "Login-IPv6-Host",
- "Framed-IPv6-Route",
- "Framed-IPv6-Pool",
- "Error-Cause",
- "EAP-Key-Name",
- "Digest-Response",
- "Digest-Realm",
- "Digest-Nonce",
- "Digest-Response-Auth",
- "Digest-Nextnonce",
- "Digest-Method",
- "Digest-URI",
- "Digest-Qop",
- "Digest-Algorithm",
- "Digest-Entity-Body-Hash",
- "Digest-CNonce",
- "Digest-Nonce-Count",
- "Digest-Username",
- "Digest-Opaque",
- "Digest-Auth-Param",
- "Digest-AKA-Auts",
- "Digest-Domain",
- "Digest-Stale",
- "Digest-HA1",
- "SIP-AOR",
- "Delegated-IPv6-Prefix",
- "MIP6-Feature-Vector",
- "MIP6-Home-Link-Prefix");
-
-/**
- * Attribute enumerator implementation
- */
-typedef struct {
- /** implements enumerator interface */
- enumerator_t public;
- /** currently pointing attribute */
- rattr_t *next;
- /** bytes left */
- int left;
-} attribute_enumerator_t;
-
-
-/**
- * Implementation of attribute_enumerator_t.enumerate
- */
-static bool attribute_enumerate(attribute_enumerator_t *this,
- int *type, chunk_t *data)
-
-{
- if (this->left == 0)
- {
- return FALSE;
- }
- if (this->left < sizeof(rattr_t) ||
- this->left < this->next->length)
- {
- DBG1(DBG_IKE, "RADIUS message truncated");
- return FALSE;
- }
- *type = this->next->type;
- data->ptr = this->next->value;
- data->len = this->next->length - sizeof(rattr_t);
- this->left -= this->next->length;
- this->next = ((void*)this->next) + this->next->length;
- return TRUE;
-}
-
-/**
- * Implementation of radius_message_t.create_enumerator
- */
-static enumerator_t* create_enumerator(private_radius_message_t *this)
-{
- attribute_enumerator_t *e;
-
- if (ntohs(this->msg->length) < sizeof(rmsg_t) + sizeof(rattr_t))
- {
- return enumerator_create_empty();
- }
-
- e = malloc_thing(attribute_enumerator_t);
- e->public.enumerate = (void*)attribute_enumerate;
- e->public.destroy = (void*)free;
- e->next = (rattr_t*)this->msg->attributes;
- e->left = ntohs(this->msg->length) - sizeof(rmsg_t);
- return &e->public;
-}
-
-/**
- * Implementation of radius_message_t.add
- */
-static void add(private_radius_message_t *this, radius_attribute_type_t type,
- chunk_t data)
-{
- rattr_t *attribute;
-
- data.len = min(data.len, 253);
- this->msg = realloc(this->msg,
- ntohs(this->msg->length) + sizeof(rattr_t) + data.len);
- attribute = ((void*)this->msg) + ntohs(this->msg->length);
- attribute->type = type;
- attribute->length = data.len + sizeof(rattr_t);
- memcpy(attribute->value, data.ptr, data.len);
- this->msg->length = htons(ntohs(this->msg->length) + attribute->length);
-}
-
-/**
- * Implementation of radius_message_t.sign
- */
-static void sign(private_radius_message_t *this, rng_t *rng, signer_t *signer)
-{
- char buf[HASH_SIZE_MD5];
-
- /* build Request-Authenticator */
- rng->get_bytes(rng, HASH_SIZE_MD5, this->msg->authenticator);
-
- /* build Message-Authenticator attribute, using 16 null bytes */
- memset(buf, 0, sizeof(buf));
- add(this, RAT_MESSAGE_AUTHENTICATOR, chunk_create(buf, sizeof(buf)));
- signer->get_signature(signer,
- chunk_create((u_char*)this->msg, ntohs(this->msg->length)),
- ((u_char*)this->msg) + ntohs(this->msg->length) - HASH_SIZE_MD5);
-}
-
-/**
- * Implementation of radius_message_t.verify
- */
-static bool verify(private_radius_message_t *this, u_int8_t *req_auth,
- chunk_t secret, hasher_t *hasher, signer_t *signer)
-{
- char buf[HASH_SIZE_MD5], res_auth[HASH_SIZE_MD5];
- enumerator_t *enumerator;
- int type;
- chunk_t data, msg;
- bool has_eap = FALSE, has_auth = FALSE;
-
- /* replace Response by Request Authenticator for verification */
- memcpy(res_auth, this->msg->authenticator, HASH_SIZE_MD5);
- memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
- msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
-
- /* verify Response-Authenticator */
- hasher->get_hash(hasher, msg, NULL);
- hasher->get_hash(hasher, secret, buf);
- if (!memeq(buf, res_auth, HASH_SIZE_MD5))
- {
- DBG1(DBG_CFG, "RADIUS Response-Authenticator verification failed");
- return FALSE;
- }
-
- /* verify Message-Authenticator attribute */
- enumerator = create_enumerator(this);
- while (enumerator->enumerate(enumerator, &type, &data))
- {
- if (type == RAT_MESSAGE_AUTHENTICATOR)
- {
- if (data.len != HASH_SIZE_MD5)
- {
- DBG1(DBG_CFG, "RADIUS Message-Authenticator invalid length");
- enumerator->destroy(enumerator);
- return FALSE;
- }
- memcpy(buf, data.ptr, data.len);
- memset(data.ptr, 0, data.len);
- if (signer->verify_signature(signer, msg,
- chunk_create(buf, sizeof(buf))))
- {
- /* restore Message-Authenticator */
- memcpy(data.ptr, buf, data.len);
- has_auth = TRUE;
- break;
- }
- else
- {
- DBG1(DBG_CFG, "RADIUS Message-Authenticator verification failed");
- enumerator->destroy(enumerator);
- return FALSE;
- }
- }
- else if (type == RAT_EAP_MESSAGE)
- {
- has_eap = TRUE;
- }
- }
- enumerator->destroy(enumerator);
- /* restore Response-Authenticator */
- memcpy(this->msg->authenticator, res_auth, HASH_SIZE_MD5);
-
- if (has_eap && !has_auth)
- { /* Message-Authenticator is required if we have an EAP-Message */
- DBG1(DBG_CFG, "RADIUS Message-Authenticator attribute missing");
- return FALSE;
- }
- return TRUE;
-}
-
-/**
- * Implementation of radius_message_t.get_code
- */
-static radius_message_code_t get_code(private_radius_message_t *this)
-{
- return this->msg->code;
-}
-
-/**
- * Implementation of radius_message_t.get_identifier
- */
-static u_int8_t get_identifier(private_radius_message_t *this)
-{
- return this->msg->identifier;
-}
-
-/**
- * Implementation of radius_message_t.set_identifier
- */
-static void set_identifier(private_radius_message_t *this, u_int8_t identifier)
-{
- this->msg->identifier = identifier;
-}
-
-/**
- * Implementation of radius_message_t.get_authenticator
- */
-static u_int8_t* get_authenticator(private_radius_message_t *this)
-{
- return this->msg->authenticator;
-}
-
-
-/**
- * Implementation of radius_message_t.get_encoding
- */
-static chunk_t get_encoding(private_radius_message_t *this)
-{
- return chunk_create((u_char*)this->msg, ntohs(this->msg->length));
-}
-
-/**
- * Implementation of radius_message_t.destroy.
- */
-static void destroy(private_radius_message_t *this)
-{
- free(this->msg);
- free(this);
-}
-
-/**
- * Generic constructor
- */
-static private_radius_message_t *radius_message_create()
-{
- private_radius_message_t *this = malloc_thing(private_radius_message_t);
-
- this->public.create_enumerator = (enumerator_t*(*)(radius_message_t*))create_enumerator;
- this->public.add = (void(*)(radius_message_t*, radius_attribute_type_t,chunk_t))add;
- this->public.get_code = (radius_message_code_t(*)(radius_message_t*))get_code;
- this->public.get_identifier = (u_int8_t(*)(radius_message_t*))get_identifier;
- this->public.set_identifier = (void(*)(radius_message_t*, u_int8_t identifier))set_identifier;
- this->public.get_authenticator = (u_int8_t*(*)(radius_message_t*))get_authenticator;
- this->public.get_encoding = (chunk_t(*)(radius_message_t*))get_encoding;
- this->public.sign = (void(*)(radius_message_t*, rng_t *rng, signer_t *signer))sign;
- this->public.verify = (bool(*)(radius_message_t*, u_int8_t *req_auth, chunk_t secret, hasher_t *hasher, signer_t *signer))verify;
- this->public.destroy = (void(*)(radius_message_t*))destroy;
-
- return this;
-}
-
-/**
- * See header
- */
-radius_message_t *radius_message_create_request()
-{
- private_radius_message_t *this = radius_message_create();
-
- this->msg = malloc_thing(rmsg_t);
- this->msg->code = RMC_ACCESS_REQUEST;
- this->msg->identifier = 0;
- this->msg->length = htons(sizeof(rmsg_t));
-
- return &this->public;
-}
-
-/**
- * See header
- */
-radius_message_t *radius_message_parse_response(chunk_t data)
-{
- private_radius_message_t *this = radius_message_create();
-
- this->msg = malloc(data.len);
- memcpy(this->msg, data.ptr, data.len);
- if (data.len < sizeof(rmsg_t) ||
- ntohs(this->msg->length) != data.len)
- {
- DBG1(DBG_IKE, "RADIUS message has invalid length");
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-