#ifndef RADIUSD_LOCAL_H
#define RADIUSD_LOCAL_H 1
#include <sys/socket.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <event.h>
#include <imsg.h>
#include <stdarg.h>
#include <stdbool.h>
#include <radius.h>
#define MODULE_IO_TIMEOUT 2000
#define CONFFILE "/etc/radiusd.conf"
struct radius_query;
struct radiusd_addr {
union {
struct in_addr ipv4;
struct in6_addr ipv6;
uint32_t addr32[4];
} addr;
};
struct radiusd_listen {
struct radiusd *radiusd;
struct event ev;
int sock;
int accounting;
union {
struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6;
} addr;
int stype;
int sproto;
TAILQ_ENTRY(radiusd_listen) next;
};
TAILQ_HEAD(radiusd_listen_head, radiusd_listen);
struct radiusd_client {
char secret[RADIUSD_SECRET_MAX];
bool msgauth_required;
int af;
struct radiusd_addr addr;
struct radiusd_addr mask;
TAILQ_ENTRY(radiusd_client) next;
};
struct radiusd_module {
char name[RADIUSD_MODULE_NAME_LEN];
struct radiusd *radiusd;
pid_t pid;
int fd;
struct imsgbuf ibuf;
struct event ev;
bool writeready;
bool stopped;
uint32_t capabilities;
u_char *radpkt;
int radpktsiz;
int radpktoff;
char *secret;
TAILQ_ENTRY(radiusd_module) next;
int (*request_decoration)(void *, struct radius_query *);
int (*response_decoration)(void *, struct radius_query *);
};
struct radiusd_module_ref {
struct radiusd_module *module;
unsigned int type;
TAILQ_ENTRY(radiusd_module_ref) next;
};
struct radiusd_authentication {
char **username;
struct radiusd_module_ref *auth;
bool isfilter;
TAILQ_HEAD(,radiusd_module_ref) deco;
TAILQ_ENTRY(radiusd_authentication) next;
};
struct radiusd_accounting {
char **username;
char *secret;
struct radiusd_module_ref *acct;
int quick;
TAILQ_HEAD(,radiusd_module_ref) deco;
TAILQ_ENTRY(radiusd_accounting) next;
};
struct radiusd {
struct radiusd_listen_head listen;
struct event ev_sigterm;
struct event ev_sighup;
struct event ev_sigint;
struct event ev_sigchld;
TAILQ_HEAD(,radiusd_module) module;
TAILQ_HEAD(,radiusd_authentication) authen;
TAILQ_HEAD(,radiusd_accounting) account;
TAILQ_HEAD(,radiusd_client) client;
TAILQ_HEAD(,radius_query) query;
int error;
};
struct radius_query {
u_int id;
struct radiusd *radiusd;
struct sockaddr_storage clientaddr;
int clientaddrlen;
int req_id;
bool hasnext;
u_char req_auth[16];
struct radiusd_listen *listen;
struct radiusd_client *client;
struct radiusd_authentication *authen;
RADIUS_PACKET *req;
RADIUS_PACKET *res;
char username[256];
TAILQ_ENTRY(radius_query) next;
struct radiusd_module_ref *deco;
struct radius_query *prev;
};
struct imsgev {
struct imsgbuf ibuf;
void (*handler)(int, short, void *);
struct event ev;
short events;
};
extern struct radiusd *radiusd_s;
#ifndef nitems
#define nitems(_x) (sizeof((_x)) / sizeof((_x)[0]))
#endif
#ifdef RADIUSD_DEBUG
#define RADIUSD_DBG(x) log_debug x
#else
#define RADIUSD_DBG(x) ((void)0)
#endif
#define RADIUSD_ASSERT(_cond) \
do { \
if (!(_cond)) { \
log_warnx( \
"ASSERT(%s) failed in %s() at %s:%d",\
#_cond, __func__, __FILE__, __LINE__);\
if (debug) abort(); \
} \
} while (0)
#define MODULE_DO_USERPASS(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_USERPASS) != 0)
#define MODULE_DO_ACCSREQ(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_ACCSREQ) != 0)
#define MODULE_DO_ACCTREQ(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_ACCTREQ) != 0)
#define MODULE_DO_REQDECO(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_REQDECO) != 0)
#define MODULE_DO_RESDECO(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_RESDECO) != 0)
#define MODULE_DO_NEXTRES(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_NEXTRES) != 0)
int parse_config(const char *, struct radiusd *);
void radiusd_conf_init(struct radiusd *);
struct radiusd_module *radiusd_module_load(struct radiusd *, const char *,
const char *);
void radiusd_module_unload(struct radiusd_module *);
void radiusd_access_request_answer(struct radius_query *);
void radiusd_access_request_next(struct radius_query *, RADIUS_PACKET *);
void radiusd_access_request_aborted(struct radius_query *);
int radiusd_imsg_compose_module(struct radiusd *, const char *,
uint32_t, uint32_t, pid_t, int, void *, size_t);
int radiusd_module_set(struct radiusd_module *, const char *, int,
char * const *);
void imsg_event_add(struct imsgev *);
int imsg_compose_event(struct imsgev *, uint32_t, uint32_t, pid_t,
int, void *, size_t);
int imsg_composev_event (struct imsgev *, uint32_t, uint32_t,
pid_t, int, struct iovec *, int);
#endif