Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * hostapd / RADIUS message processing
      3  * Copyright (c) 2002-2005, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License version 2 as
      7  * published by the Free Software Foundation.
      8  *
      9  * Alternatively, this software may be distributed under the terms of BSD
     10  * license.
     11  *
     12  * See README and COPYING for more details.
     13  */
     14 
     15 #ifndef RADIUS_H
     16 #define RADIUS_H
     17 
     18 /* RFC 2865 - RADIUS */
     19 
     20 #ifdef _MSC_VER
     21 #pragma pack(push, 1)
     22 #endif /* _MSC_VER */
     23 
     24 struct radius_hdr {
     25 	u8 code;
     26 	u8 identifier;
     27 	u16 length; /* including this header */
     28 	u8 authenticator[16];
     29 	/* followed by length-20 octets of attributes */
     30 } STRUCT_PACKED;
     31 
     32 enum { RADIUS_CODE_ACCESS_REQUEST = 1,
     33        RADIUS_CODE_ACCESS_ACCEPT = 2,
     34        RADIUS_CODE_ACCESS_REJECT = 3,
     35        RADIUS_CODE_ACCOUNTING_REQUEST = 4,
     36        RADIUS_CODE_ACCOUNTING_RESPONSE = 5,
     37        RADIUS_CODE_ACCESS_CHALLENGE = 11,
     38        RADIUS_CODE_STATUS_SERVER = 12,
     39        RADIUS_CODE_STATUS_CLIENT = 13,
     40        RADIUS_CODE_RESERVED = 255
     41 };
     42 
     43 struct radius_attr_hdr {
     44 	u8 type;
     45 	u8 length; /* including this header */
     46 	/* followed by length-2 octets of attribute value */
     47 } STRUCT_PACKED;
     48 
     49 #define RADIUS_MAX_ATTR_LEN (255 - sizeof(struct radius_attr_hdr))
     50 
     51 enum { RADIUS_ATTR_USER_NAME = 1,
     52        RADIUS_ATTR_USER_PASSWORD = 2,
     53        RADIUS_ATTR_NAS_IP_ADDRESS = 4,
     54        RADIUS_ATTR_NAS_PORT = 5,
     55        RADIUS_ATTR_FRAMED_MTU = 12,
     56        RADIUS_ATTR_STATE = 24,
     57        RADIUS_ATTR_CLASS = 25,
     58        RADIUS_ATTR_VENDOR_SPECIFIC = 26,
     59        RADIUS_ATTR_SESSION_TIMEOUT = 27,
     60        RADIUS_ATTR_IDLE_TIMEOUT = 28,
     61        RADIUS_ATTR_TERMINATION_ACTION = 29,
     62        RADIUS_ATTR_CALLED_STATION_ID = 30,
     63        RADIUS_ATTR_CALLING_STATION_ID = 31,
     64        RADIUS_ATTR_NAS_IDENTIFIER = 32,
     65        RADIUS_ATTR_PROXY_STATE = 33,
     66        RADIUS_ATTR_ACCT_STATUS_TYPE = 40,
     67        RADIUS_ATTR_ACCT_DELAY_TIME = 41,
     68        RADIUS_ATTR_ACCT_INPUT_OCTETS = 42,
     69        RADIUS_ATTR_ACCT_OUTPUT_OCTETS = 43,
     70        RADIUS_ATTR_ACCT_SESSION_ID = 44,
     71        RADIUS_ATTR_ACCT_AUTHENTIC = 45,
     72        RADIUS_ATTR_ACCT_SESSION_TIME = 46,
     73        RADIUS_ATTR_ACCT_INPUT_PACKETS = 47,
     74        RADIUS_ATTR_ACCT_OUTPUT_PACKETS = 48,
     75        RADIUS_ATTR_ACCT_TERMINATE_CAUSE = 49,
     76        RADIUS_ATTR_ACCT_MULTI_SESSION_ID = 50,
     77        RADIUS_ATTR_ACCT_LINK_COUNT = 51,
     78        RADIUS_ATTR_ACCT_INPUT_GIGAWORDS = 52,
     79        RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS = 53,
     80        RADIUS_ATTR_EVENT_TIMESTAMP = 55,
     81        RADIUS_ATTR_NAS_PORT_TYPE = 61,
     82        RADIUS_ATTR_TUNNEL_TYPE = 64,
     83        RADIUS_ATTR_TUNNEL_MEDIUM_TYPE = 65,
     84        RADIUS_ATTR_CONNECT_INFO = 77,
     85        RADIUS_ATTR_EAP_MESSAGE = 79,
     86        RADIUS_ATTR_MESSAGE_AUTHENTICATOR = 80,
     87        RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID = 81,
     88        RADIUS_ATTR_ACCT_INTERIM_INTERVAL = 85,
     89        RADIUS_ATTR_NAS_IPV6_ADDRESS = 95
     90 };
     91 
     92 
     93 /* Termination-Action */
     94 #define RADIUS_TERMINATION_ACTION_DEFAULT 0
     95 #define RADIUS_TERMINATION_ACTION_RADIUS_REQUEST 1
     96 
     97 /* NAS-Port-Type */
     98 #define RADIUS_NAS_PORT_TYPE_IEEE_802_11 19
     99 
    100 /* Acct-Status-Type */
    101 #define RADIUS_ACCT_STATUS_TYPE_START 1
    102 #define RADIUS_ACCT_STATUS_TYPE_STOP 2
    103 #define RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE 3
    104 #define RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON 7
    105 #define RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF 8
    106 
    107 /* Acct-Authentic */
    108 #define RADIUS_ACCT_AUTHENTIC_RADIUS 1
    109 #define RADIUS_ACCT_AUTHENTIC_LOCAL 2
    110 #define RADIUS_ACCT_AUTHENTIC_REMOTE 3
    111 
    112 /* Acct-Terminate-Cause */
    113 #define RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST 1
    114 #define RADIUS_ACCT_TERMINATE_CAUSE_LOST_CARRIER 2
    115 #define RADIUS_ACCT_TERMINATE_CAUSE_LOST_SERVICE 3
    116 #define RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT 4
    117 #define RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT 5
    118 #define RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_RESET 6
    119 #define RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT 7
    120 #define RADIUS_ACCT_TERMINATE_CAUSE_PORT_ERROR 8
    121 #define RADIUS_ACCT_TERMINATE_CAUSE_NAS_ERROR 9
    122 #define RADIUS_ACCT_TERMINATE_CAUSE_NAS_REQUEST 10
    123 #define RADIUS_ACCT_TERMINATE_CAUSE_NAS_REBOOT 11
    124 #define RADIUS_ACCT_TERMINATE_CAUSE_PORT_UNNEEDED 12
    125 #define RADIUS_ACCT_TERMINATE_CAUSE_PORT_PREEMPTED 13
    126 #define RADIUS_ACCT_TERMINATE_CAUSE_PORT_SUSPENDED 14
    127 #define RADIUS_ACCT_TERMINATE_CAUSE_SERVICE_UNAVAILABLE 15
    128 #define RADIUS_ACCT_TERMINATE_CAUSE_CALLBACK 16
    129 #define RADIUS_ACCT_TERMINATE_CAUSE_USER_ERROR 17
    130 #define RADIUS_ACCT_TERMINATE_CAUSE_HOST_REQUEST 18
    131 
    132 #define RADIUS_TUNNEL_TAGS 32
    133 
    134 /* Tunnel-Type */
    135 #define RADIUS_TUNNEL_TYPE_PPTP 1
    136 #define RADIUS_TUNNEL_TYPE_L2TP 3
    137 #define RADIUS_TUNNEL_TYPE_IPIP 7
    138 #define RADIUS_TUNNEL_TYPE_GRE 10
    139 #define RADIUS_TUNNEL_TYPE_VLAN 13
    140 
    141 /* Tunnel-Medium-Type */
    142 #define RADIUS_TUNNEL_MEDIUM_TYPE_IPV4 1
    143 #define RADIUS_TUNNEL_MEDIUM_TYPE_IPV6 2
    144 #define RADIUS_TUNNEL_MEDIUM_TYPE_802 6
    145 
    146 
    147 struct radius_attr_vendor {
    148 	u8 vendor_type;
    149 	u8 vendor_length;
    150 } STRUCT_PACKED;
    151 
    152 #define RADIUS_VENDOR_ID_CISCO 9
    153 #define RADIUS_CISCO_AV_PAIR 1
    154 
    155 /* RFC 2548 - Microsoft Vendor-specific RADIUS Attributes */
    156 #define RADIUS_VENDOR_ID_MICROSOFT 311
    157 
    158 enum { RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY = 16,
    159        RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY = 17
    160 };
    161 
    162 #ifdef _MSC_VER
    163 #pragma pack(pop)
    164 #endif /* _MSC_VER */
    165 
    166 struct radius_ms_mppe_keys {
    167 	u8 *send;
    168 	size_t send_len;
    169 	u8 *recv;
    170 	size_t recv_len;
    171 };
    172 
    173 
    174 /* RADIUS message structure for new and parsed messages */
    175 struct radius_msg {
    176 	unsigned char *buf;
    177 	size_t buf_size; /* total size allocated for buf */
    178 	size_t buf_used; /* bytes used in buf */
    179 
    180 	struct radius_hdr *hdr;
    181 
    182 	struct radius_attr_hdr **attrs; /* array of pointers to attributes */
    183 	size_t attr_size; /* total size of the attribute pointer array */
    184 	size_t attr_used; /* total number of attributes in the array */
    185 };
    186 
    187 
    188 /* Default size to be allocated for new RADIUS messages */
    189 #define RADIUS_DEFAULT_MSG_SIZE 1024
    190 
    191 /* Default size to be allocated for attribute array */
    192 #define RADIUS_DEFAULT_ATTR_COUNT 16
    193 
    194 
    195 /* MAC address ASCII format for IEEE 802.1X use
    196  * (draft-congdon-radius-8021x-20.txt) */
    197 #define RADIUS_802_1X_ADDR_FORMAT "%02X-%02X-%02X-%02X-%02X-%02X"
    198 /* MAC address ASCII format for non-802.1X use */
    199 #define RADIUS_ADDR_FORMAT "%02x%02x%02x%02x%02x%02x"
    200 
    201 struct radius_msg *radius_msg_new(u8 code, u8 identifier);
    202 int radius_msg_initialize(struct radius_msg *msg, size_t init_len);
    203 void radius_msg_set_hdr(struct radius_msg *msg, u8 code, u8 identifier);
    204 void radius_msg_free(struct radius_msg *msg);
    205 void radius_msg_dump(struct radius_msg *msg);
    206 int radius_msg_finish(struct radius_msg *msg, u8 *secret, size_t secret_len);
    207 int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
    208 			  size_t secret_len, const u8 *req_authenticator);
    209 void radius_msg_finish_acct(struct radius_msg *msg, u8 *secret,
    210 			    size_t secret_len);
    211 struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
    212 					    const u8 *data, size_t data_len);
    213 struct radius_msg *radius_msg_parse(const u8 *data, size_t len);
    214 int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
    215 		       size_t data_len);
    216 u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *len);
    217 int radius_msg_verify(struct radius_msg *msg, const u8 *secret,
    218 		      size_t secret_len, struct radius_msg *sent_msg,
    219 		      int auth);
    220 int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret,
    221 			       size_t secret_len, const u8 *req_auth);
    222 int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src,
    223 			 u8 type);
    224 void radius_msg_make_authenticator(struct radius_msg *msg,
    225 				   const u8 *data, size_t len);
    226 struct radius_ms_mppe_keys *
    227 radius_msg_get_ms_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
    228 		       u8 *secret, size_t secret_len);
    229 struct radius_ms_mppe_keys *
    230 radius_msg_get_cisco_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
    231 			  u8 *secret, size_t secret_len);
    232 int radius_msg_add_mppe_keys(struct radius_msg *msg,
    233 			     const u8 *req_authenticator,
    234 			     const u8 *secret, size_t secret_len,
    235 			     const u8 *send_key, size_t send_key_len,
    236 			     const u8 *recv_key, size_t recv_key_len);
    237 struct radius_attr_hdr *
    238 radius_msg_add_attr_user_password(struct radius_msg *msg,
    239 				  u8 *data, size_t data_len,
    240 				  u8 *secret, size_t secret_len);
    241 int radius_msg_get_attr(struct radius_msg *msg, u8 type, u8 *buf, size_t len);
    242 int radius_msg_get_vlanid(struct radius_msg *msg);
    243 
    244 static inline int radius_msg_add_attr_int32(struct radius_msg *msg, u8 type,
    245 					    u32 value)
    246 {
    247 	u32 val = htonl(value);
    248 	return radius_msg_add_attr(msg, type, (u8 *) &val, 4) != NULL;
    249 }
    250 
    251 static inline int radius_msg_get_attr_int32(struct radius_msg *msg, u8 type,
    252 					    u32 *value)
    253 {
    254 	u32 val;
    255 	int res;
    256 	res = radius_msg_get_attr(msg, type, (u8 *) &val, 4);
    257 	if (res != 4)
    258 		return -1;
    259 
    260 	*value = ntohl(val);
    261 	return 0;
    262 }
    263 int radius_msg_get_attr_ptr(struct radius_msg *msg, u8 type, u8 **buf,
    264 			    size_t *len, const u8 *start);
    265 int radius_msg_count_attr(struct radius_msg *msg, u8 type, int min_len);
    266 
    267 #endif /* RADIUS_H */
    268