20 |
#include <sys/socket.h> |
#include <sys/socket.h> |
21 |
#include <netinet/in.h> |
#include <netinet/in.h> |
22 |
#include <stdio.h> |
#include <stdio.h> |
|
#include <pthread.h> |
|
23 |
#include <radius.h> |
#include <radius.h> |
24 |
#include <radpaths.h> |
#include <radpaths.h> |
25 |
#include <signal.h> |
#include <signal.h> |
26 |
#include <cfg.h> |
#include <cfg.h> |
27 |
|
#include <list.h> |
|
/* Debugging macros */ |
|
|
#define Pthread_mutex_lock(m) \ |
|
|
do { \ |
|
|
debug(100,("locking " #m)); \ |
|
|
pthread_mutex_lock(m);\ |
|
|
debug(100,("locked " #m)); \ |
|
|
} while (0) |
|
|
|
|
|
#define Pthread_mutex_unlock(m) \ |
|
|
do { \ |
|
|
debug(100,("unlocking " #m)); \ |
|
|
pthread_mutex_unlock(m);\ |
|
|
debug(100,("unlocked " #m)); \ |
|
|
} while (0) |
|
28 |
|
|
29 |
/* Server data structures */ |
/* Server data structures */ |
30 |
struct radutmp; /* declared in radutmp.h */ |
struct radutmp; /* declared in radutmp.h */ |
56 |
#define R_SNMP 3 /* SNMP request */ |
#define R_SNMP 3 /* SNMP request */ |
57 |
#define R_MAX 4 |
#define R_MAX 4 |
58 |
|
|
|
/* Request class structure |
|
|
*/ |
|
|
typedef struct request_class { |
|
|
char *name; /* Class name */ |
|
|
int max_requests; /* Max.number of pending requests of this type */ |
|
|
int ttl; /* Request time-to-live */ |
|
|
int cleanup_delay; /* Delay before cleaning the completed request */ |
|
|
int (*setup)(); /* Setup function */ |
|
|
int (*handler)(); /* Handler function */ |
|
|
void (*xmit)(); /* Retransmit function */ |
|
|
int (*comp)(); /* Compare function */ |
|
|
void (*free)(); /* Free */ |
|
|
void (*drop)(); /* Drop request error message */ |
|
|
void (*cleanup)(); /* Cleanup function */ |
|
|
} REQUEST_CLASS; |
|
|
|
|
|
typedef struct socket_list SOCKET_LIST; |
|
|
struct request_handler_tab { |
|
|
int (*success)(struct sockaddr *, int); |
|
|
int (*respond)(int fd, struct sockaddr *, int, u_char *, int); |
|
|
int (*failure)(struct sockaddr *, int); |
|
|
}; |
|
|
|
|
59 |
#define RS_WAITING 0 /* Request waiting for processing */ |
#define RS_WAITING 0 /* Request waiting for processing */ |
60 |
#define RS_PENDING 1 /* Request is being processed */ |
#define RS_COMPLETED 1 /* Request is completed */ |
|
#define RS_COMPLETED 2 /* Request is completed */ |
|
|
#define RS_HUNG 3 /* Request is (possibly) hung */ |
|
|
#define RS_DEAD 4 /* Request was killed */ |
|
61 |
|
|
62 |
typedef struct request { |
typedef struct request { |
|
struct request *next; /* Link to the next request */ |
|
63 |
int type; /* request type */ |
int type; /* request type */ |
64 |
int status; /* request status */ |
int status; /* request status */ |
65 |
time_t timestamp; /* when was the request accepted */ |
time_t timestamp; /* when was the request accepted */ |
66 |
pthread_t child_id; /* ID of the handling process (or -1) */ |
pid_t child_id; /* ID of the handling process */ |
67 |
int child_return; /* Child return code if completed */ |
int code; /* Child return code if completed */ |
68 |
void *data; /* Request-specific data */ |
void *data; /* Request-specific data */ |
69 |
|
void *rawdata; /* Raw data as received from the |
70 |
|
socket */ |
71 |
|
size_t rawsize; /* Size of the data */ |
72 |
int fd; /* socket the request came from */ |
int fd; /* socket the request came from */ |
73 |
|
struct sockaddr_in addr; /* Remote party address */ |
74 |
|
|
75 |
} REQUEST; |
} REQUEST; |
76 |
|
|
77 |
|
/* Request class structure |
78 |
|
*/ |
79 |
|
typedef struct request_class { |
80 |
|
char *name; /* Class name */ |
81 |
|
int max_requests; /* Max.number of pending requests of this type */ |
82 |
|
int ttl; /* Request time-to-live */ |
83 |
|
int cleanup_delay; /* Delay before cleaning the completed request */ |
84 |
|
int (*decode)(struct sockaddr_in *sa, |
85 |
|
void *input, size_t inputsize, void **output); |
86 |
|
int (*respond)(REQUEST *r); /* Handler function */ |
87 |
|
void (*xmit)(REQUEST *r); /* Retransmit function */ |
88 |
|
int (*comp)(void *a, void *b); /* Compare function */ |
89 |
|
void (*free)(void *data); /* Free the associated data */ |
90 |
|
void (*drop)(int type, void *data, void *old_data, int fd, char *msg); |
91 |
|
/* Drop the request */ |
92 |
|
void (*cleanup)(int type, void *data);/* Cleanup function */ |
93 |
|
int (*failure)(int type, struct sockaddr_in *addr); |
94 |
|
} REQUEST_CLASS; |
95 |
|
|
96 |
struct queue_stat { |
struct queue_stat { |
97 |
size_t waiting; |
size_t waiting; |
98 |
size_t pending; |
size_t pending; |
180 |
#define stat_inc(m,a,c) \ |
#define stat_inc(m,a,c) \ |
181 |
do {\ |
do {\ |
182 |
NAS *nas;\ |
NAS *nas;\ |
183 |
server_stat . ##m . ##c ++;\ |
server_stat . m . c ++;\ |
184 |
if ((nas = nas_lookup_ip(a)) != NULL && nas->app_data)\ |
if ((nas = nas_lookup_ip(a)) != NULL && nas->app_data)\ |
185 |
((struct nas_stat*)nas->app_data)-> ##m . ##c ++;\ |
((struct nas_stat*)nas->app_data)-> m . c ++;\ |
186 |
} while (0) |
} while (0) |
187 |
|
|
188 |
extern struct radstat radstat; |
extern struct radstat radstat; |
205 |
#define MAX_REQUEST_TIME 60 |
#define MAX_REQUEST_TIME 60 |
206 |
#define CLEANUP_DELAY 10 |
#define CLEANUP_DELAY 10 |
207 |
#define MAX_REQUESTS 255 |
#define MAX_REQUESTS 255 |
208 |
|
#define MAX_CHILDREN 8 |
209 |
|
|
210 |
/* |
/* |
211 |
* Authentication results |
* Authentication results |
242 |
/* |
/* |
243 |
* Global variables. |
* Global variables. |
244 |
*/ |
*/ |
|
extern SOCKET_LIST *socket_first; |
|
245 |
extern int radius_mode; |
extern int radius_mode; |
246 |
extern int debug_flag; |
extern int debug_flag; |
247 |
extern int auth_detail; |
extern int auth_detail; |
248 |
extern int acct_detail; |
extern int acct_detail; |
249 |
extern int strip_names; |
extern int strip_names; |
250 |
extern int checkrad_assume_logged; |
extern int checkrad_assume_logged; |
251 |
extern int max_requests; |
extern size_t max_requests; |
252 |
|
extern size_t max_children; |
253 |
extern char *exec_user; |
extern char *exec_user; |
254 |
extern UINT4 expiration_seconds; |
extern UINT4 expiration_seconds; |
255 |
extern UINT4 warning_seconds; |
extern UINT4 warning_seconds; |
265 |
extern char *username_valid_chars; |
extern char *username_valid_chars; |
266 |
extern unsigned long stat_start_time; |
extern unsigned long stat_start_time; |
267 |
extern REQUEST_CLASS request_class[]; |
extern REQUEST_CLASS request_class[]; |
|
extern pthread_attr_t thread_attr; |
|
268 |
extern int max_threads; |
extern int max_threads; |
269 |
extern int num_threads; |
extern int num_threads; |
270 |
#ifdef USE_SERVER_GUILE |
#ifdef USE_SERVER_GUILE |
277 |
extern Server_stat server_stat; |
extern Server_stat server_stat; |
278 |
extern struct cfg_stmt snmp_stmt[]; |
extern struct cfg_stmt snmp_stmt[]; |
279 |
#endif |
#endif |
280 |
|
extern int auth_comp_flag; |
281 |
|
extern int acct_comp_flag; |
282 |
|
|
283 |
/* |
/* Input subsystem (input.c) */ |
|
* Function prototypes. |
|
|
*/ |
|
284 |
|
|
285 |
/* acct.c */ |
typedef struct input_system INPUT; |
286 |
int rad_accounting(RADIUS_REQ *, int); |
|
287 |
int radzap(UINT4 nas, int port, char *user, time_t t); |
INPUT *input_create(); |
288 |
int rad_check_multi(char *name, VALUE_PAIR *request, int maxsimul, int *pcount); |
void input_register_method(INPUT *input, |
289 |
int rad_check_realm(REALM *realm); |
const char *name, |
290 |
int write_detail(RADIUS_REQ *radreq, int authtype, char *f); |
int (*handler)(int, void *), |
291 |
|
int (*close)(int, void *), |
292 |
|
int (*cmp)(const void *, const void *)); |
293 |
|
int input_register_channel(INPUT *input, char *name, int fd, void *data); |
294 |
|
void input_close_channels(INPUT *input); |
295 |
|
void input_close_channel_fd(INPUT *input, int fd); |
296 |
|
void input_close_channel_data(INPUT *input, char *name, void *data); |
297 |
|
int input_select(INPUT *input, struct timeval *tv); |
298 |
|
void *input_find_channel(INPUT *input, char *name, void *data); |
299 |
|
|
300 |
|
/* rpp.c */ |
301 |
|
int rpp_ready(); |
302 |
|
int rpp_forward_request(REQUEST *req); |
303 |
|
void rpp_remove(pid_t pid); |
304 |
|
void rpp_flush(); |
305 |
|
int rpp_input_handler(int fd, void *data); |
306 |
|
int rpp_input_close(int fd, void *data); |
307 |
|
void rpp_kill(pid_t pid, int signo); |
308 |
|
|
309 |
|
/* request.c */ |
310 |
|
REQUEST *request_create(int type, int fd, struct sockaddr_in *sa, |
311 |
|
u_char *buf, size_t bufsize); |
312 |
|
void request_free(REQUEST *req); |
313 |
|
int request_respond(REQUEST *req); |
314 |
|
int request_handle(REQUEST *req, int (*handler)(REQUEST *)); |
315 |
|
void request_fail(int type, struct sockaddr_in *addr); |
316 |
|
void request_init_queue(); |
317 |
|
void *request_scan_list(int type, list_iterator_t itr, void *closure); |
318 |
|
void request_set_status(pid_t pid, int status); |
319 |
|
|
320 |
/* radiusd.c */ |
/* radiusd.c */ |
321 |
int stat_request_list(QUEUE_STAT); |
int udp_input_handler(int fd, void *data); |
322 |
void *scan_request_list(int type, int (*handler)(), void *closure); |
int udp_input_close(int fd, void *data); |
323 |
int set_nonblocking(int fd); |
int udp_input_cmp(const void *a, const void *b); |
324 |
void radiusd_thread_init(); |
|
|
int radiusd_flush_queues(); |
|
|
void schedule_restart(); |
|
|
void radiusd_mainloop(); |
|
|
void rad_req_drop(int type, RADIUS_REQ *req, RADIUS_REQ *orig, int fd, |
|
|
char *status_str); |
|
|
int radiusd_mutex_lock(pthread_mutex_t *mutex, int type); |
|
|
int radiusd_mutex_unlock(pthread_mutex_t *mutex); |
|
325 |
void radiusd_pidfile_write(char *name); |
void radiusd_pidfile_write(char *name); |
326 |
pid_t radiusd_pidfile_read(char *name); |
pid_t radiusd_pidfile_read(char *name); |
327 |
void radiusd_pidfile_remove(char *name); |
void radiusd_pidfile_remove(char *name); |
328 |
int radiusd_is_watched(); |
|
329 |
int radiusd_restart(); |
void radiusd_signal_init(RETSIGTYPE (*)(int)); |
330 |
int radiusd_primitive_restart(); |
void radiusd_cleanup(); |
331 |
void run_before_config_hooks(void *data); |
void radiusd_restart(); |
332 |
void run_after_config_hooks(void *data); |
void radiusd_flush_queue(); |
333 |
void register_before_config_hook(config_hook_fp fp, void *data); |
void radiusd_exit(); |
334 |
void register_after_config_hook(config_hook_fp fp, void *data); |
void radiusd_reconfigure(); |
335 |
|
int radiusd_master(); |
336 |
|
|
337 |
|
/* exec.c */ |
338 |
|
int radius_exec_program(char *, RADIUS_REQ *, VALUE_PAIR **, int, char **); |
339 |
|
void filter_cleanup(pid_t pid, int status); |
340 |
|
int filter_auth(char *name, RADIUS_REQ *req, VALUE_PAIR **reply_pairs); |
341 |
|
int filter_acct(char *name, RADIUS_REQ *req); |
342 |
|
int filters_stmt_term(int finish, void *block_data, void *handler_data); |
343 |
|
extern struct cfg_stmt filters_stmt[]; |
344 |
|
|
345 |
|
/* scheme.c */ |
346 |
|
void rad_boot(); |
347 |
|
void scheme_load(char *filename); |
348 |
|
void scheme_load_path(char *pathname); |
349 |
|
void scheme_debug(int val); |
350 |
|
int scheme_auth(char *procname, RADIUS_REQ *req, |
351 |
|
VALUE_PAIR *user_check, VALUE_PAIR **user_reply_ptr); |
352 |
|
int scheme_acct(char *procname, RADIUS_REQ *req); |
353 |
|
void scheme_add_load_path(char *path); |
354 |
|
void scheme_read_eval_loop(); |
355 |
|
void start_guile(); |
356 |
|
int guile_cfg_handler(int argc, cfg_value_t *argv, |
357 |
|
void *block_data, void *handler_data); |
358 |
|
extern struct cfg_stmt guile_stmt[]; |
359 |
|
|
360 |
|
/* log.c */ |
361 |
|
void sqllog __PVAR((int status, char *msg, ...)); |
362 |
|
int logging_stmt_handler(int argc, cfg_value_t *argv, void *block_data, |
363 |
|
void *handler_data); |
364 |
|
int logging_stmt_end(void *block_data, void *handler_data); |
365 |
|
int logging_stmt_begin(int finish, void *block_data, void *handler_data); |
366 |
|
extern struct cfg_stmt logging_stmt[]; |
367 |
|
|
368 |
/* radius.c */ |
/* radius.c */ |
369 |
|
|
371 |
#define REQ_AUTH_ZERO 1 |
#define REQ_AUTH_ZERO 1 |
372 |
#define REQ_AUTH_BAD 2 |
#define REQ_AUTH_BAD 2 |
373 |
|
|
374 |
void rad_send_reply(int, RADIUS_REQ *, VALUE_PAIR *, char *, int); |
void radius_send_reply(int, RADIUS_REQ *, VALUE_PAIR *, char *, int); |
375 |
RADIUS_REQ *radrecv (UINT4, u_short, u_char *, int); |
void radius_send_challenge(RADIUS_REQ *radreq, char *msg, char *state, int fd); |
376 |
int validate_client(RADIUS_REQ *radreq); |
int radius_verify_digest(REQUEST *req); |
377 |
int calc_acctdigest(RADIUS_REQ *radreq); |
|
378 |
void send_challenge(RADIUS_REQ *radreq, char *msg, char *state, int activefd); |
int radius_req_decode(struct sockaddr_in *sa, |
379 |
|
void *input, size_t inputsize, void **output); |
380 |
|
int radius_req_cmp(void *a, void *b); |
381 |
|
void radius_req_free(void *req); |
382 |
|
void radius_req_drop(int type, void *radreq, void *origreq, |
383 |
|
int fd, char *status_str); |
384 |
|
void radius_req_xmit(REQUEST *request); |
385 |
|
int radius_req_failure(int type, struct sockaddr_in *addr); |
386 |
|
int radius_respond(REQUEST *req); |
387 |
|
|
388 |
|
/*FIXME*/ |
389 |
|
/* acct.c */ |
390 |
|
int rad_accounting(RADIUS_REQ *, int, int); |
391 |
|
int radzap(UINT4 nas, int port, char *user, time_t t); |
392 |
|
int rad_check_multi(char *name, VALUE_PAIR *request, int maxsimul, int *pcount); |
393 |
|
int rad_check_realm(REALM *realm); |
394 |
|
int write_detail(RADIUS_REQ *radreq, int authtype, char *f); |
395 |
|
|
396 |
|
|
397 |
/* files.c */ |
/* files.c */ |
429 |
#endif |
#endif |
430 |
|
|
431 |
/* proxy.c */ |
/* proxy.c */ |
432 |
int rad_proxy(RADIUS_REQ *radreq, int activefd); |
int rad_proxy(REQUEST *req); |
433 |
void rad_proxy_free(RADIUS_REQ *req); |
void rad_proxy_free(RADIUS_REQ *req); |
434 |
int proxy_send(RADIUS_REQ *radreq, int activefd); |
int proxy_send(RADIUS_REQ *radreq, int activefd); |
435 |
int proxy_receive(RADIUS_REQ *radreq, int activefd); |
int proxy_receive(RADIUS_REQ *radreq, int activefd); |
436 |
void proxy_retry(int type, RADIUS_REQ *radreq, RADIUS_REQ *orig_req, |
void proxy_retry(int type, void *radreq, void *orig_req, |
437 |
int fd, char *status_str); |
int fd, char *status_str); |
438 |
|
|
439 |
void proxy_cleanup(); |
void proxy_cleanup(); |
440 |
|
|
443 |
int rad_authenticate (RADIUS_REQ *, int); |
int rad_authenticate (RADIUS_REQ *, int); |
444 |
void req_decrypt_password(char *password, RADIUS_REQ *req, VALUE_PAIR *pair); |
void req_decrypt_password(char *password, RADIUS_REQ *req, VALUE_PAIR *pair); |
445 |
|
|
|
/* exec.c */ |
|
|
int radius_exec_program(char *, RADIUS_REQ *, VALUE_PAIR **, |
|
|
int, char **user_msg); |
|
|
void filter_cleanup(); |
|
|
int filter_auth(char *name, RADIUS_REQ *req, VALUE_PAIR **reply_pairs); |
|
|
int filter_acct(char *name, RADIUS_REQ *req); |
|
|
int filters_stmt_term(int finish, void *block_data, void *handler_data); |
|
|
extern struct cfg_stmt filters_stmt[]; |
|
|
|
|
446 |
/* menu.c */ |
/* menu.c */ |
447 |
void process_menu(RADIUS_REQ *radreq, int fd); |
void process_menu(RADIUS_REQ *radreq, int fd); |
448 |
char * get_menu(char *menu_name); |
char * get_menu(char *menu_name); |
506 |
char *radius_xlate(struct obstack *obp, char *str, |
char *radius_xlate(struct obstack *obp, char *str, |
507 |
RADIUS_REQ *req, VALUE_PAIR *reply_pairs); |
RADIUS_REQ *req, VALUE_PAIR *reply_pairs); |
508 |
|
|
|
/* log.c */ |
|
|
void sqllog __PVAR((int status, char *msg, ...)); |
|
|
int logging_stmt_handler(int argc, cfg_value_t *argv, void *block_data, |
|
|
void *handler_data); |
|
|
int logging_stmt_end(void *block_data, void *handler_data); |
|
|
int logging_stmt_begin(int finish, void *block_data, void *handler_data); |
|
|
extern struct cfg_stmt logging_stmt[]; |
|
|
|
|
509 |
/* rewrite.y */ |
/* rewrite.y */ |
510 |
extern struct cfg_stmt rewrite_stmt[]; |
extern struct cfg_stmt rewrite_stmt[]; |
511 |
int run_rewrite(char *name, RADIUS_REQ *req); |
int run_rewrite(char *name, RADIUS_REQ *req); |
519 |
VALUE_PAIR **pairs); |
VALUE_PAIR **pairs); |
520 |
void radck(); |
void radck(); |
521 |
|
|
|
/* scheme.c */ |
|
|
void rad_boot(); |
|
|
void scheme_load(char *filename); |
|
|
void scheme_load_path(char *pathname); |
|
|
void scheme_debug(int val); |
|
|
int scheme_auth(char *procname, RADIUS_REQ *req, |
|
|
VALUE_PAIR *user_check, VALUE_PAIR **user_reply_ptr); |
|
|
int scheme_acct(char *procname, RADIUS_REQ *req); |
|
|
void scheme_add_load_path(char *path); |
|
|
void scheme_read_eval_loop(); |
|
|
void start_guile(); |
|
|
int guile_cfg_handler(int argc, cfg_value_t *argv, |
|
|
void *block_data, void *handler_data); |
|
|
extern struct cfg_stmt guile_stmt[]; |
|
|
|
|
|
/* request.c */ |
|
|
typedef void (*request_thread_command_fp)(void *); |
|
|
|
|
|
int request_start_thread(); |
|
|
void request_signal(); |
|
|
REQUEST *request_put(int type, void *data, int fd, unsigned *numpending); |
|
|
REQUEST *request_get(); |
|
|
int request_flush_list(); |
|
|
int request_stat_list(QUEUE_STAT stat); |
|
|
void request_handle(REQUEST *req); |
|
|
void *request_scan_list(int type, int (*handler)(), void *closure); |
|
|
void request_thread_command(request_thread_command_fp fun, void *data); |
|
522 |
|
|
523 |
|
|
524 |
/* checkrad.c */ |
/* checkrad.c */ |
525 |
int checkrad(NAS *nas, struct radutmp *up); |
int checkrad(NAS *nas, struct radutmp *up); |
526 |
|
|
|
/* socklist.c */ |
|
|
int socket_list_add(SOCKET_LIST **slist, int type, UINT4 ipaddr, int port); |
|
|
void socket_list_init(SOCKET_LIST *slist); |
|
|
int socket_list_open(SOCKET_LIST **slist); |
|
|
int socket_list_select(struct socket_list *list, |
|
|
struct request_handler_tab *ht, |
|
|
size_t numh, |
|
|
struct timeval *tv); |
|
|
void socket_list_close(SOCKET_LIST **slist); |
|
|
void socket_list_iterate(SOCKET_LIST *slist, void (*fun)()); |
|
|
|
|
|
/* signal.c */ |
|
|
#define SH_SYNC 0 |
|
|
#define SH_ASYNC 1 |
|
|
#define SH_DELETED 2 |
|
|
|
|
|
typedef void *rad_sigid_t; |
|
|
typedef int (*rad_signal_t) (int sig, void *data, rad_sigid_t id, |
|
|
const void *owner); |
|
|
|
|
|
rad_sigid_t rad_signal_install (int sig, int type, |
|
|
rad_signal_t handler, void *data); |
|
|
rad_sigid_t rad_signal_remove (int sig, rad_sigid_t id, const void *owner); |
|
527 |
|
|
528 |
|
|