1189251Ssam/*
2214734Srpaulo * RADIUS client
3214734Srpaulo * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
4189251Ssam *
5189251Ssam * This program is free software; you can redistribute it and/or modify
6189251Ssam * it under the terms of the GNU General Public License version 2 as
7189251Ssam * published by the Free Software Foundation.
8189251Ssam *
9189251Ssam * Alternatively, this software may be distributed under the terms of BSD
10189251Ssam * license.
11189251Ssam *
12189251Ssam * See README and COPYING for more details.
13189251Ssam */
14189251Ssam
15189251Ssam#ifndef RADIUS_CLIENT_H
16189251Ssam#define RADIUS_CLIENT_H
17189251Ssam
18189251Ssam#include "ip_addr.h"
19189251Ssam
20189251Ssamstruct radius_msg;
21189251Ssam
22214734Srpaulo/**
23214734Srpaulo * struct hostapd_radius_server - RADIUS server information for RADIUS client
24214734Srpaulo *
25214734Srpaulo * This structure contains information about a RADIUS server. The values are
26214734Srpaulo * mainly for MIB information. The MIB variable prefix (radiusAuth or
27214734Srpaulo * radiusAcc) depends on whether this is an authentication or accounting
28214734Srpaulo * server.
29214734Srpaulo *
30214734Srpaulo * radiusAuthClientPendingRequests (or radiusAccClientPendingRequests) is the
31214734Srpaulo * number struct radius_client_data::msgs for matching msg_type.
32214734Srpaulo */
33189251Ssamstruct hostapd_radius_server {
34214734Srpaulo	/**
35214734Srpaulo	 * addr - radiusAuthServerAddress or radiusAccServerAddress
36214734Srpaulo	 */
37214734Srpaulo	struct hostapd_ip_addr addr;
38214734Srpaulo
39214734Srpaulo	/**
40214734Srpaulo	 * port - radiusAuthClientServerPortNumber or radiusAccClientServerPortNumber
41214734Srpaulo	 */
42214734Srpaulo	int port;
43214734Srpaulo
44214734Srpaulo	/**
45214734Srpaulo	 * shared_secret - Shared secret for authenticating RADIUS messages
46214734Srpaulo	 */
47189251Ssam	u8 *shared_secret;
48214734Srpaulo
49214734Srpaulo	/**
50214734Srpaulo	 * shared_secret_len - Length of shared_secret in octets
51214734Srpaulo	 */
52189251Ssam	size_t shared_secret_len;
53189251Ssam
54189251Ssam	/* Dynamic (not from configuration file) MIB data */
55214734Srpaulo
56214734Srpaulo	/**
57214734Srpaulo	 * index - radiusAuthServerIndex or radiusAccServerIndex
58214734Srpaulo	 */
59214734Srpaulo	int index;
60214734Srpaulo
61214734Srpaulo	/**
62214734Srpaulo	 * round_trip_time - radiusAuthClientRoundTripTime or radiusAccClientRoundTripTime
63214734Srpaulo	 * Round-trip time in hundredths of a second.
64214734Srpaulo	 */
65214734Srpaulo	int round_trip_time;
66214734Srpaulo
67214734Srpaulo	/**
68214734Srpaulo	 * requests - radiusAuthClientAccessRequests or radiusAccClientRequests
69214734Srpaulo	 */
70214734Srpaulo	u32 requests;
71214734Srpaulo
72214734Srpaulo	/**
73214734Srpaulo	 * retransmissions - radiusAuthClientAccessRetransmissions or radiusAccClientRetransmissions
74214734Srpaulo	 */
75214734Srpaulo	u32 retransmissions;
76214734Srpaulo
77214734Srpaulo	/**
78214734Srpaulo	 * access_accepts - radiusAuthClientAccessAccepts
79214734Srpaulo	 */
80214734Srpaulo	u32 access_accepts;
81214734Srpaulo
82214734Srpaulo	/**
83214734Srpaulo	 * access_rejects - radiusAuthClientAccessRejects
84214734Srpaulo	 */
85214734Srpaulo	u32 access_rejects;
86214734Srpaulo
87214734Srpaulo	/**
88214734Srpaulo	 * access_challenges - radiusAuthClientAccessChallenges
89214734Srpaulo	 */
90214734Srpaulo	u32 access_challenges;
91214734Srpaulo
92214734Srpaulo	/**
93214734Srpaulo	 * responses - radiusAccClientResponses
94214734Srpaulo	 */
95214734Srpaulo	u32 responses;
96214734Srpaulo
97214734Srpaulo	/**
98214734Srpaulo	 * malformed_responses - radiusAuthClientMalformedAccessResponses or radiusAccClientMalformedResponses
99214734Srpaulo	 */
100214734Srpaulo	u32 malformed_responses;
101214734Srpaulo
102214734Srpaulo	/**
103214734Srpaulo	 * bad_authenticators - radiusAuthClientBadAuthenticators or radiusAccClientBadAuthenticators
104214734Srpaulo	 */
105214734Srpaulo	u32 bad_authenticators;
106214734Srpaulo
107214734Srpaulo	/**
108214734Srpaulo	 * timeouts - radiusAuthClientTimeouts or radiusAccClientTimeouts
109214734Srpaulo	 */
110214734Srpaulo	u32 timeouts;
111214734Srpaulo
112214734Srpaulo	/**
113214734Srpaulo	 * unknown_types - radiusAuthClientUnknownTypes or radiusAccClientUnknownTypes
114214734Srpaulo	 */
115214734Srpaulo	u32 unknown_types;
116214734Srpaulo
117214734Srpaulo	/**
118214734Srpaulo	 * packets_dropped - radiusAuthClientPacketsDropped or radiusAccClientPacketsDropped
119214734Srpaulo	 */
120214734Srpaulo	u32 packets_dropped;
121189251Ssam};
122189251Ssam
123214734Srpaulo/**
124214734Srpaulo * struct hostapd_radius_servers - RADIUS servers for RADIUS client
125214734Srpaulo */
126189251Ssamstruct hostapd_radius_servers {
127214734Srpaulo	/**
128214734Srpaulo	 * auth_servers - RADIUS Authentication servers in priority order
129214734Srpaulo	 */
130214734Srpaulo	struct hostapd_radius_server *auth_servers;
131214734Srpaulo
132214734Srpaulo	/**
133214734Srpaulo	 * num_auth_servers - Number of auth_servers entries
134214734Srpaulo	 */
135189251Ssam	int num_auth_servers;
136214734Srpaulo
137214734Srpaulo	/**
138214734Srpaulo	 * auth_server - The current Authentication server
139214734Srpaulo	 */
140214734Srpaulo	struct hostapd_radius_server *auth_server;
141214734Srpaulo
142214734Srpaulo	/**
143214734Srpaulo	 * acct_servers - RADIUS Accounting servers in priority order
144214734Srpaulo	 */
145214734Srpaulo	struct hostapd_radius_server *acct_servers;
146214734Srpaulo
147214734Srpaulo	/**
148214734Srpaulo	 * num_acct_servers - Number of acct_servers entries
149214734Srpaulo	 */
150189251Ssam	int num_acct_servers;
151189251Ssam
152214734Srpaulo	/**
153214734Srpaulo	 * acct_server - The current Accounting server
154214734Srpaulo	 */
155214734Srpaulo	struct hostapd_radius_server *acct_server;
156214734Srpaulo
157214734Srpaulo	/**
158214734Srpaulo	 * retry_primary_interval - Retry interval for trying primary server
159214734Srpaulo	 *
160214734Srpaulo	 * This specifies a retry interval in sexconds for trying to return to
161214734Srpaulo	 * the primary RADIUS server. RADIUS client code will automatically try
162214734Srpaulo	 * to use the next server when the current server is not replying to
163214734Srpaulo	 * requests. If this interval is set (non-zero), the primary server
164214734Srpaulo	 * will be retried after the specified number of seconds has passed
165214734Srpaulo	 * even if the current used secondary server is still working.
166214734Srpaulo	 */
167189251Ssam	int retry_primary_interval;
168189251Ssam
169214734Srpaulo	/**
170214734Srpaulo	 * msg_dumps - Whether RADIUS message details are shown in stdout
171214734Srpaulo	 */
172189251Ssam	int msg_dumps;
173189251Ssam
174214734Srpaulo	/**
175214734Srpaulo	 * client_addr - Client (local) address to use if force_client_addr
176214734Srpaulo	 */
177189251Ssam	struct hostapd_ip_addr client_addr;
178214734Srpaulo
179214734Srpaulo	/**
180214734Srpaulo	 * force_client_addr - Whether to force client (local) address
181214734Srpaulo	 */
182189251Ssam	int force_client_addr;
183189251Ssam};
184189251Ssam
185189251Ssam
186214734Srpaulo/**
187214734Srpaulo * RadiusType - RADIUS server type for RADIUS client
188214734Srpaulo */
189189251Ssamtypedef enum {
190214734Srpaulo	/**
191214734Srpaulo	 * RADIUS authentication
192214734Srpaulo	 */
193189251Ssam	RADIUS_AUTH,
194214734Srpaulo
195214734Srpaulo	/**
196214734Srpaulo	 * RADIUS_ACCT - RADIUS accounting
197214734Srpaulo	 */
198189251Ssam	RADIUS_ACCT,
199214734Srpaulo
200214734Srpaulo	/**
201214734Srpaulo	 * RADIUS_ACCT_INTERIM - RADIUS interim accounting message
202214734Srpaulo	 *
203214734Srpaulo	 * Used only with radius_client_send(). This behaves just like
204214734Srpaulo	 * RADIUS_ACCT, but removes any pending interim RADIUS Accounting
205214734Srpaulo	 * messages for the same STA before sending the new interim update.
206214734Srpaulo	 */
207214734Srpaulo	RADIUS_ACCT_INTERIM
208189251Ssam} RadiusType;
209189251Ssam
210214734Srpaulo/**
211214734Srpaulo * RadiusRxResult - RADIUS client RX handler result
212214734Srpaulo */
213189251Ssamtypedef enum {
214214734Srpaulo	/**
215214734Srpaulo	 * RADIUS_RX_PROCESSED - Message processed
216214734Srpaulo	 *
217214734Srpaulo	 * This stops handler calls and frees the message.
218214734Srpaulo	 */
219189251Ssam	RADIUS_RX_PROCESSED,
220214734Srpaulo
221214734Srpaulo	/**
222214734Srpaulo	 * RADIUS_RX_QUEUED - Message has been queued
223214734Srpaulo	 *
224214734Srpaulo	 * This stops handler calls, but does not free the message; the handler
225214734Srpaulo	 * that returned this is responsible for eventually freeing the
226214734Srpaulo	 * message.
227214734Srpaulo	 */
228189251Ssam	RADIUS_RX_QUEUED,
229214734Srpaulo
230214734Srpaulo	/**
231214734Srpaulo	 * RADIUS_RX_UNKNOWN - Message is not for this handler
232214734Srpaulo	 */
233189251Ssam	RADIUS_RX_UNKNOWN,
234214734Srpaulo
235214734Srpaulo	/**
236214734Srpaulo	 * RADIUS_RX_INVALID_AUTHENTICATOR - Message has invalid Authenticator
237214734Srpaulo	 */
238189251Ssam	RADIUS_RX_INVALID_AUTHENTICATOR
239189251Ssam} RadiusRxResult;
240189251Ssam
241189251Ssamstruct radius_client_data;
242189251Ssam
243189251Ssamint radius_client_register(struct radius_client_data *radius,
244189251Ssam			   RadiusType msg_type,
245189251Ssam			   RadiusRxResult (*handler)
246189251Ssam			   (struct radius_msg *msg, struct radius_msg *req,
247189251Ssam			    const u8 *shared_secret, size_t shared_secret_len,
248189251Ssam			    void *data),
249189251Ssam			   void *data);
250189251Ssamint radius_client_send(struct radius_client_data *radius,
251189251Ssam		       struct radius_msg *msg,
252189251Ssam		       RadiusType msg_type, const u8 *addr);
253189251Ssamu8 radius_client_get_id(struct radius_client_data *radius);
254189251Ssamvoid radius_client_flush(struct radius_client_data *radius, int only_auth);
255189251Ssamstruct radius_client_data *
256189251Ssamradius_client_init(void *ctx, struct hostapd_radius_servers *conf);
257189251Ssamvoid radius_client_deinit(struct radius_client_data *radius);
258214734Srpaulovoid radius_client_flush_auth(struct radius_client_data *radius,
259214734Srpaulo			      const u8 *addr);
260189251Ssamint radius_client_get_mib(struct radius_client_data *radius, char *buf,
261189251Ssam			  size_t buflen);
262189251Ssam
263189251Ssam#endif /* RADIUS_CLIENT_H */
264