24 RCSID(
"$Id: c1767c5a35bbb45e44c79447ba96e7801e3daae5 $")
26 #include <freeradius-devel/radiusd.h>
27 #include <freeradius-devel/modules.h>
28 #include <freeradius-devel/map_proc.h>
29 #include <freeradius-devel/state.h>
30 #include <freeradius-devel/rad_assert.h>
49 #ifdef RADIUSD_VERSION_COMMIT
50 " (git #" STRINGIFY(RADIUSD_VERSION_COMMIT)
")"
52 ", for host " HOSTINFO
", built on " __DATE__
" at " __TIME__;
57 static void usage(
int);
75 if (!
this)
return NULL;
102 if (!client)
return NULL;
118 gettimeofday(&now, NULL);
119 request->timestamp = now;
122 if (!request->packet) {
124 talloc_free(request);
127 request->packet->timestamp = now;
130 if (!request->reply) {
132 talloc_free(request);
143 request->handle = NULL;
153 talloc_free(request);
162 request->packet->src_ipaddr.af = AF_INET;
163 request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
164 request->packet->src_port = 18120;
166 request->packet->dst_ipaddr.af = AF_INET;
167 request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
168 request->packet->dst_port = 1812;
185 vp->vp_strvalue = vp->xlat;
199 request->packet->code = vp->vp_integer;
202 case PW_PACKET_DST_PORT:
203 request->packet->dst_port = (vp->vp_integer & 0xffff);
206 case PW_PACKET_DST_IP_ADDRESS:
207 request->packet->dst_ipaddr.af = AF_INET;
208 request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
209 request->packet->dst_ipaddr.prefix = 32;
212 case PW_PACKET_DST_IPV6_ADDRESS:
213 request->packet->dst_ipaddr.af = AF_INET6;
214 request->packet->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
215 request->packet->dst_ipaddr.prefix = 128;
218 case PW_PACKET_SRC_PORT:
219 request->packet->src_port = (vp->vp_integer & 0xffff);
222 case PW_PACKET_SRC_IP_ADDRESS:
223 request->packet->src_ipaddr.af = AF_INET;
224 request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
225 request->packet->src_ipaddr.prefix = 32;
228 case PW_PACKET_SRC_IPV6_ADDRESS:
229 request->packet->src_ipaddr.af = AF_INET6;
230 request->packet->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
231 request->packet->src_ipaddr.prefix = 128;
234 case PW_CHAP_PASSWORD: {
244 if (vp->vp_length == 17) {
245 for (i = 0; i < 17; i++) {
246 if (vp->vp_octets[i] < 32) {
260 len = len2 = vp->vp_length;
261 if (len2 < 17) len2 = 17;
263 p = talloc_zero_array(vp, uint8_t, len2);
265 memcpy(p, vp->vp_strvalue, len);
274 case PW_DIGEST_REALM:
275 case PW_DIGEST_NONCE:
276 case PW_DIGEST_METHOD:
279 case PW_DIGEST_ALGORITHM:
280 case PW_DIGEST_BODY_DIGEST:
281 case PW_DIGEST_CNONCE:
282 case PW_DIGEST_NONCE_COUNT:
283 case PW_DIGEST_USER_NAME:
289 p = talloc_array(vp, uint8_t, vp->vp_length + 2);
291 memcpy(p + 2, vp->vp_octets, vp->vp_length);
292 p[0] = vp->
da->
attr - PW_DIGEST_REALM + 1;
294 p[1] = vp->vp_length;
309 memcpy(&q, &vp->vp_octets,
sizeof(q));
312 vp->vp_octets = talloc_steal(vp, p);
331 ERROR(
"Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));
347 request->packet->src_ipaddr.af = AF_INET;
348 request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
349 request->packet->src_port = 18120;
351 request->packet->dst_ipaddr.af = AF_INET;
352 request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
353 request->packet->dst_port = 1812;
358 request->reply->sockfd = request->packet->sockfd;
359 request->reply->dst_ipaddr = request->packet->src_ipaddr;
360 request->reply->src_ipaddr = request->packet->dst_ipaddr;
361 request->reply->dst_port = request->packet->src_port;
362 request->reply->src_port = request->packet->dst_port;
363 request->reply->id = request->packet->id;
364 request->reply->code = 0;
365 memcpy(request->reply->vector, request->packet->vector,
366 sizeof(request->reply->vector));
367 request->reply->vps = NULL;
368 request->reply->data = NULL;
369 request->reply->data_len = 0;
403 ERROR(
"Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));
415 #include <freeradius-devel/modpriv.h>
421 UNUSED void const *mod_inst,
UNUSED void const *xlat_inst,
422 REQUEST *request,
char const *fmt)
441 if (!modules)
return 0;
443 buffer = talloc_strdup(request, fmt);
444 if (!buffer)
return 0;
446 p = strchr(buffer,
'.');
453 RDEBUG(
"Failed finding module '%s'", buffer);
461 RDEBUG(
"Failed finding '=' in string '%s'", fmt);
467 if (strchr(p,
'.') != NULL) {
468 RDEBUG(
"Can't do sub-sections right now");
474 RDEBUG(
"No such item '%s'", p);
485 RDEBUG(
"Failed replacing pair");
495 for (i = 0; variables[i].
name != NULL; i++) {
504 if (strcmp(variables[i].
name, p) != 0)
continue;
506 if (variables[i].data) {
507 data = variables[i].
data;
509 data = ((
char *)base) + variables[i].
offset;
511 DEBUG2(
"Internal sanity check 2 failed in cf_section_parse");
519 data, variables[i].
dflt, variables[i].
quote);
521 DEBUG2(
"Failed inserting new value into module instance data");
536 static bool do_xlats(
char const *filename, FILE *fp)
550 gettimeofday(&now, NULL);
551 request->timestamp = now;
558 while (fgets(input,
sizeof(input), fp) != NULL) {
565 while (isspace((
int) *p)) p++;
567 if (*p <
' ')
continue;
568 if (*p ==
'#')
continue;
573 fprintf(stderr,
"Line %d too long in %s\n",
575 TALLOC_FREE(request);
585 if (strncmp(input,
"xlat ", 5) == 0) {
587 char const *error = NULL;
594 snprintf(output,
sizeof(output),
"ERROR offset %d '%s'", (
int) -slen, error);
598 if (input[slen + 5] !=
'\0') {
600 snprintf(output,
sizeof(output),
"ERROR offset %d 'Too much text' ::%s::", (
int) slen, input + slen + 5);
617 if (strncmp(input,
"data ", 5) == 0) {
618 if (strcmp(input + 5, output) != 0) {
619 fprintf(stderr,
"Mismatch at line %d of %s\n\tgot : %s\n\texpected : %s\n",
620 lineno, filename, output, input + 5);
621 TALLOC_FREE(request);
627 fprintf(stderr,
"Unknown keyword in %s[%d]\n", filename, lineno);
628 TALLOC_FREE(request);
632 TALLOC_FREE(request);
646 int main(
int argc,
char *argv[])
648 int rcode = EXIT_SUCCESS;
650 const char *input_file = NULL;
651 const char *output_file = NULL;
652 const char *filter_file = NULL;
657 bool xlat_only =
false;
695 while ((argval = getopt(argc, argv,
"d:D:f:hi:mMn:o:O:xX")) != EOF) {
707 filter_file = optarg;
723 memory_report =
true;
732 output_file = optarg;
736 if (strcmp(optarg,
"xlat_only") == 0) {
741 fprintf(stderr,
"Unknown option '%s'\n", optarg);
775 #ifdef HAVE_OPENSSL_CRYPTO_H
776 if (tls_global_init() < 0) {
777 rcode = EXIT_FAILURE;
783 rcode = EXIT_FAILURE;
788 rcode = EXIT_FAILURE;
796 rcode = EXIT_FAILURE;
838 panic_action = getenv(
"PANIC_ACTION");
841 if (panic_action && (
fr_fault_setup(panic_action, argv[0]) < 0)) {
849 if (!input_file || (strcmp(input_file,
"-") == 0)) {
852 fp = fopen(input_file,
"r");
854 fprintf(stderr,
"Failed reading %s: %s\n",
855 input_file, strerror(errno));
856 rcode = EXIT_FAILURE;
865 if (!
do_xlats(input_file, fp)) rcode = EXIT_FAILURE;
866 if (input_file) fclose(fp);
875 fprintf(stderr,
"Failed reading input: %s\n",
fr_strerror());
876 rcode = EXIT_FAILURE;
885 if (!filter_file || filedone ||
886 ((input_file != NULL) && (strcmp(filter_file, input_file) != 0))) {
901 fp = fopen(filter_file,
"r");
903 fprintf(stderr,
"Failed reading %s: %s\n", filter_file, strerror(errno));
904 rcode = EXIT_FAILURE;
911 fprintf(stderr,
"Failed reading attributes from %s: %s\n",
913 rcode = EXIT_FAILURE;
925 if (!output_file || (strcmp(output_file,
"-") == 0)) {
928 fp = fopen(output_file,
"w");
930 fprintf(stderr,
"Failed writing %s: %s\n",
931 output_file, strerror(errno));
938 if (output_file) fclose(fp);
944 PW_RESPONSE_PACKET_TYPE, 0);
952 fr_perror(
"Output file %s does not match attributes in filter %s (%s)",
953 output_file ? output_file : input_file, filter_file,
fr_strerror());
954 rcode = EXIT_FAILURE;
959 INFO(
"Exiting normally");
962 talloc_free(request);
980 INFO(
"Allocated memory at time of report:");
993 FILE *output = status?stderr:stdout;
996 fprintf(output,
"Options:\n");
997 fprintf(output,
" -d raddb_dir Configuration files are in \"raddb_dir/*\".\n");
998 fprintf(output,
" -D dict_dir Dictionary files are in \"dict_dir/*\".\n");
999 fprintf(output,
" -f file Filter reply against attributes in 'file'.\n");
1000 fprintf(output,
" -h Print this help message.\n");
1001 fprintf(output,
" -i file File containing request attributes.\n");
1002 fprintf(output,
" -m On SIGINT or SIGQUIT exit cleanly instead of immediately.\n");
1003 fprintf(output,
" -n name Read raddb/name.conf instead of raddb/radiusd.conf.\n");
1004 fprintf(output,
" -X Turn on full debugging.\n");
1005 fprintf(output,
" -x Turn on additional debugging. (-xx gives more debugging).\n");
VALUE_PAIR has a single value.
FR_TOKEN quote
Quoting around the default value. Only used for templates.
static bool already_hex(VALUE_PAIR *vp)
int cf_pair_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *data, char const *dflt, FR_TOKEN dflt_quote)
Parses a CONF_PAIR into a C data type, with a default value.
void * data
Pointer to a static variable to write the parsed value to.
int xlat_register(void *mod_inst, char const *name, xlat_func_t func, xlat_escape_t escape, xlat_instantiate_t instantiate, size_t inst_size, size_t buf_len)
Register an xlat function.
Main server configuration.
static rlm_rcode_t mod_map_proc(UNUSED void *mod_inst, UNUSED void *proc_inst, UNUSED REQUEST *request, UNUSED char const *src, UNUSED vp_map_t const *maps)
char const * name
Name of the CONF_ITEM to parse.
int main_config_init(void)
char const * fr_packet_codes[FR_MAX_PACKET_CODE]
CONF_PARSER const * config
Configuration information.
int type
A PW_TYPE value, may be or'd with one or more PW_TYPE_* flags.
uint32_t fr_rand(void)
Return a 32-bit random number.
void listen_free(UNUSED rad_listen_t **head)
int virtual_servers_init(CONF_SECTION *config)
VALUE_PAIR * radius_pair_create(TALLOC_CTX *ctx, VALUE_PAIR **vps, unsigned int attribute, unsigned int vendor)
Create a VALUE_PAIR and add it to a list of VALUE_PAIR s.
static bool do_xlats(char const *filename, FILE *fp)
void fr_pair_validate_debug(TALLOC_CTX *ctx, VALUE_PAIR const *failed[2])
Write an error to the library errorbuff detailing the mismatch.
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
module_instance_t * module_find(CONF_SECTION *modules, char const *askedname)
Find an existing module instance.
VALUE_PAIR * fr_cursor_init(vp_cursor_t *cursor, VALUE_PAIR *const *node)
Setup a cursor to iterate over attribute pairs.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
int main_config_free(void)
fr_state_tree_t * fr_state_tree_init(TALLOC_CTX *ctx, uint32_t max_sessions, uint32_t timeout)
Initialise a new state tree.
int map_proc_register(void *mod_inst, char const *name, map_proc_func_t evaluate, xlat_escape_t escape, map_proc_instantiate_t instantiate, size_t inst_size)
Register a map processor.
size_t offset
Relative offset of field or structure to write the parsed value to.
valuepair value must be xlat expanded when it's added to VALUE_PAIR tree.
int fr_log_talloc_report(TALLOC_CTX *ctx)
Generate a talloc memory report for a context and print to stderr/stdout.
char const * name
Name of the daemon, usually 'radiusd'.
#define XLAT_DEFAULT_BUF_LEN
int virtual_servers_bootstrap(CONF_SECTION *config)
void fr_pair_fprint(FILE *, VALUE_PAIR const *vp)
Print one attribute and value to FP.
void set_radius_dir(TALLOC_CTX *ctx, char const *path)
Set the global radius config directory.
#define PW_TYPE_SUBSECTION
Defines a CONF_PAIR to C data type mapping.
Abstraction to allow iterating over different configurations of VALUE_PAIRs.
CONF_PAIR * cf_pair_find(CONF_SECTION const *, char const *name)
char const * cf_pair_value(CONF_PAIR const *pair)
int listen_bootstrap(UNUSED CONF_SECTION *server, UNUSED CONF_SECTION *cs, UNUSED char const *server_name)
void vradlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg, va_list ap) CC_HINT(format(printf
int fr_fault_setup(char const *cmd, char const *program)
Registers signal handlers to execute panic_action on fatal signal.
main_config_t * root
Pointer to the main config hack to try and deal with hup.
#define PW_DIGEST_ATTRIBUTES
RFC2865 - Access-Request.
int modules_init(CONF_SECTION *)
Instantiate the modules.
int main(int argc, char *argv[])
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
int cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value)
Replace pair in a given section with a new pair, of the given value.
static void print_packet(FILE *fp, RADIUS_PACKET *packet)
bool debug_memory
Cleanup the server properly on exit, freeing up any memory we allocated.
RADIUS_PACKET * fr_radius_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new RADIUS_PACKET.
static REQUEST * request_setup(FILE *fp)
void void fr_perror(char const *,...) CC_HINT(format(printf
unsigned int attr
Attribute number.
int fr_radius_encode_chap_password(uint8_t *output, RADIUS_PACKET *packet, int id, VALUE_PAIR *password)
unsigned int code
Packet code (type).
const void * dflt
Default as it would appear in radiusd.conf.
static char panic_action[512]
The command to execute when panicking.
unsigned int vendor
Vendor that defines this attribute.
Stores an attribute, a value and various bits of other data.
bool log_auth_goodpass
Log failed authentications.
RADIUS_PACKET * reply
Outgoing response.
ssize_t ssize_t radius_xlat_struct(char *out, size_t outlen, REQUEST *request, xlat_exp_t const *xlat, xlat_escape_t escape, void *ctx) CC_HINT(nonnull(1
bool fr_pair_validate(VALUE_PAIR const *failed[2], VALUE_PAIR *filter, VALUE_PAIR *list)
Uses fr_pair_cmp to verify all VALUE_PAIRs in list match the filter defined by check.
Configuration AVP similar to a VALUE_PAIR.
bool log_auth
Log authentication attempts.
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
static ssize_t xlat_poke(char **out, size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt)
char const * fr_strerror(void)
Get the last library error.
CONF_SECTION * cf_section_sub_find(CONF_SECTION const *, char const *name)
Find a sub-section in a section.
void xlat_free(void)
De-register all xlat functions, used mainly for debugging.
Describes a host allowed to send packets to the server.
Module failed, don't reply.
value_type_t type
Type of pointer in value union.
CONF_SECTION * config
Root of the server config.
log_lvl_t rad_debug_lvl
Global debugging level.
VALUE_PAIR * fr_cursor_next(vp_cursor_t *cursor)
Advanced the cursor to the next VALUE_PAIR.
int fr_pair_list_afrom_file(TALLOC_CTX *ctx, VALUE_PAIR **out, FILE *fp, bool *pfiledone)
bool fr_hostname_lookups
hostname -> IP lookups?
char const * radiusd_version
ssize_t ssize_t ssize_t ssize_t ssize_t xlat_tokenize(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head, char const **error)
CONF_SECTION * cf_section_alloc(CONF_SECTION *parent, char const *name1, char const *name2)
Allocate a CONF_SECTION.
char const * dictionary_dir
Where to load dictionaries from.
int modules_bootstrap(CONF_SECTION *)
main_config_t main_config
Main server configuration.
static RADCLIENT * client_alloc(void *ctx)
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
char const * panic_action
Command to execute if the server receives a fatal signal.
void fr_talloc_fault_setup(void)
Register talloc fault handlers.
bool log_auth_badpass
Log successful authentications.
size_t strlcpy(char *dst, char const *src, size_t siz)
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
log_dst_t dst
Log destination.
fr_dict_attr_t const * fr_dict_attr_by_num(fr_dict_t *dict, unsigned int vendor, unsigned int attr)
Lookup a fr_dict_attr_t by its vendor and attribute numbers.
int rad_virtual_server(REQUEST *)
void cf_section_add(CONF_SECTION *parent, CONF_SECTION *cs)
char * talloc_typed_strdup(void const *t, char const *p)
Call talloc strdup, setting the type on the new chunk correctly.
int fd
File descriptor to write messages to.
static bool memory_report
void xlat_unregister(void *mod_inst, char const *name, xlat_func_t func)
REQUEST * request_alloc(TALLOC_CTX *ctx)
Create a new REQUEST data structure.
static rad_listen_t * listen_alloc(void *ctx)
#define RADIUSD_MAGIC_NUMBER