25#include <radcli/radcli.h>
29#include "dict_rfc_gen.h"
36static int rc_conf_int_2(rc_handle
const *rh,
char const *optname,
int complain);
41static OPTION config_options_default[] = {
42#define RADCLI_OPT_ENTRY(id, name, type) {name, type, ST_UNDEF, NULL},
44#undef RADCLI_OPT_ENTRY
47#define NUM_OPTIONS ((sizeof(config_options_default))/(sizeof(config_options_default[0])))
65static OPTION *find_option(rc_handle
const *rh,
char const *optname,
unsigned int type)
70 for (i = 0; i < NUM_OPTIONS; i++) {
71 if (!strcmp(rh->config_options[i].name, optname) &&
72 (rh->config_options[i].type & type))
74 return &rh->config_options[i];
89static int rc_ignored_option(
char const *name)
91#define X(n) if (!strcmp(name, n)) return 1;
92 RC_IGNORED_OPTION_TABLE
108static inline OPTION *rc_option_by_id(rc_handle
const *rh, rc_option_id
id)
110 assert(rh != NULL && rh->config_options != NULL);
111 assert((
unsigned)
id < NUM_OPTIONS);
112 return &rh->config_options[id];
121int rc_conf_int_id(rc_handle
const *rh, rc_option_id
id)
123 OPTION *option = rc_option_by_id(rh,
id);
125 assert(option->type & RADCLI_OPT_TYPE_INT);
128 return *((
int *)option->val);
130 rc_log(LOG_INFO,
"radcli2_priv_conf_int: config option %s was not set", option->name);
140char *rc_conf_str_id(rc_handle
const *rh, rc_option_id
id)
142 OPTION *option = rc_option_by_id(rh,
id);
144 assert(option->type & RADCLI_OPT_TYPE_STR);
146 return (
char *)option->val;
157static int set_option_str(
char const *filename,
int line, OPTION *option,
char const *p)
160 option->val = (
void *) strdup(p);
161 if (option->val == NULL) {
162 rc_log(LOG_CRIT,
"read_config: out of memory");
191static int set_option_int(
char const *filename,
int line, OPTION *option,
char const *p)
197 rc_log(LOG_ERR,
"%s: line %d: bogus option value", filename, line);
203 if (strcmp(option->name,
"watchdog-interval") == 0 && val >= 1 && val <= 5) {
204 rc_log(LOG_ERR,
"%s: line %d: watchdog-interval must be 0 (disabled) "
205 "or at least 6 seconds, not %d", filename, line, val);
209 if ((iptr = malloc(
sizeof(*iptr))) == NULL) {
210 rc_log(LOG_CRIT,
"read_config: out of memory");
215 option->val = (
void *) iptr;
230static void server_free_entries(SERVER *serv,
unsigned from,
unsigned to)
234 for (i = from; i < to; i++) {
236 free(serv->secret[i]);
237 serv->name[i] = NULL;
238 serv->secret[i] = NULL;
252static int set_option_srv(rc_handle *rh,
char const *filename,
int line, OPTION *option,
char const *p)
265 if (p_dupe == NULL) {
266 rc_log(LOG_ERR,
"%s: line %d: Invalid option or memory failure", filename, line);
270 serv = (SERVER *) option->val;
272 serv = calloc(1,
sizeof(*serv));
274 rc_log(LOG_CRIT,
"read_config: out of memory");
280 start_max = serv->max;
282 p_pointer = strtok_r(p_dupe,
", \t", &p_save);
284 while(p_pointer != NULL) {
285 if (serv->max >= RC_SERVER_MAX) {
286 DEBUG(rh, LOG_ERR,
"cannot set more than %d servers", RC_SERVER_MAX);
290 DEBUG(rh, LOG_ERR,
"processing server: %s", p_pointer);
292 if ((q = strchr(p_pointer,
'[')) != NULL) {
297 q = strchr(p_pointer,
']');
299 rc_log(LOG_CRIT,
"read_config: IPv6 parse error");
310 if((s=strchr(q,
':')) != NULL) {
313 serv->secret[serv->max] = strdup(s);
314 if (serv->secret[serv->max] == NULL) {
315 rc_log(LOG_CRIT,
"read_config: out of memory");
321 if ((q = strchr(p_pointer,
':')) != NULL) {
326 if((s = strchr(q,
':')) != NULL) {
329 serv->secret[serv->max] = strdup(s);
330 if (serv->secret[serv->max] == NULL) {
331 rc_log(LOG_CRIT,
"read_config: out of memory");
337 if(q && strlen(q) > 0) {
338 serv->port[serv->max] = atoi(q);
340 if (!strcmp(option->name,
"authserver"))
341 if ((svp = getservbyname (
"radius",
"udp")) == NULL)
342 serv->port[serv->max] = PW_AUTH_UDP_PORT;
344 serv->port[serv->max] = ntohs ((
unsigned int) svp->s_port);
345 else if (!strcmp(option->name,
"acctserver"))
346 if ((svp = getservbyname (
"radacct",
"udp")) == NULL)
347 serv->port[serv->max] = PW_ACCT_UDP_PORT;
349 serv->port[serv->max] = ntohs ((
unsigned int) svp->s_port);
351 rc_log(LOG_ERR,
"%s: line %d: no default port for %s", filename, line, option->name);
356 serv->name[serv->max] = strdup(p_pointer);
357 if (serv->name[serv->max] == NULL) {
358 rc_log(LOG_CRIT,
"read_config: out of memory");
363 p_pointer = strtok_r(NULL,
", \t", &p_save);
367 if (option->val == NULL)
368 option->val = (
void *)serv;
379 server_free_entries(serv, start_max, serv->max);
380 serv->max = start_max;
381 if (serv->max < RC_SERVER_MAX) {
382 free(serv->secret[serv->max]);
383 serv->secret[serv->max] = NULL;
385 if (option->val == NULL)
401int radcli2_priv_add_config(rc_handle *rh,
char const *option_name,
char const *option_val,
char const *source,
int line)
405 if ((option = find_option(rh, option_name, OT_ANY)) == NULL)
407 if (rc_ignored_option(option_name))
409 rc_log(LOG_ERR,
"ERROR: unrecognized option: %s", option_name);
413 if (option->status != ST_UNDEF)
415 rc_log(LOG_ERR,
"ERROR: duplicate option: %s", option_name);
419 switch (option->type) {
420 case RADCLI_OPT_TYPE_STR:
421 if (set_option_str(source, line, option, option_val) < 0) {
425 case RADCLI_OPT_TYPE_INT:
426 if (set_option_int(source, line, option, option_val) < 0) {
430 case RADCLI_OPT_TYPE_SRV:
431 if (set_option_srv(rh, source, line, option, option_val) < 0) {
436 rc_log(LOG_CRIT,
"radcli2_priv_add_config: impossible case branch!");
453rc_handle *radcli2_priv_config_init(rc_handle *rh)
455 SERVER *authservers = NULL;
460 rh->config_options = malloc(
sizeof(config_options_default));
461 if (rh->config_options == NULL)
463 rc_log(LOG_CRIT,
"radcli2_priv_config_init: out of memory");
464 radcli2_priv_destroy(rh);
467 memcpy(rh->config_options, &config_options_default,
sizeof(config_options_default));
469 auth = find_option(rh,
"authserver", OT_ANY);
471 authservers = calloc(1,
sizeof(SERVER));
472 if(authservers == NULL) {
473 rc_log(LOG_CRIT,
"radcli2_priv_config_init: error initializing server structs");
474 radcli2_priv_destroy(rh);
477 auth->val = authservers;
480 acct = find_option(rh,
"acctserver", OT_ANY);
482 acctservers = calloc(1,
sizeof(SERVER));
483 if(acctservers == NULL) {
484 rc_log(LOG_CRIT,
"radcli2_priv_config_init: error initializing server structs");
485 radcli2_priv_destroy(rh);
486 if(authservers) free(authservers);
489 acct->val = acctservers;
498static ssize_t plain_sendto(
void *ptr,
int sockfd,
499 const void *buf,
size_t len,
int flags,
500 const struct sockaddr *dest_addr, socklen_t addrlen)
502 return sendto(sockfd, buf, len, flags, dest_addr, addrlen);
508static ssize_t plain_tcp_sendto(
void *ptr,
int sockfd,
509 const void *buf,
size_t len,
int flags,
510 const struct sockaddr *dest_addr, socklen_t addrlen)
512 if((connect(sockfd, dest_addr, addrlen)) != 0){
513 rc_log(LOG_ERR,
"%s: Connect Call Failed : %s", __FUNCTION__, strerror(errno));
516 return sendto(sockfd, buf, len, flags, dest_addr, addrlen);
522static ssize_t plain_recvfrom(
void *ptr,
int sockfd,
523 void *buf,
size_t len,
int flags,
524 struct sockaddr *src_addr, socklen_t * addrlen)
526 return recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
532static void plain_close_fd(
int fd)
544static int plain_get_fd(
void *ptr,
struct sockaddr *our_sockaddr)
548 sockfd = socket(our_sockaddr->sa_family, SOCK_DGRAM, 0);
553 if (our_sockaddr->sa_family == AF_INET)
554 ((
struct sockaddr_in *)our_sockaddr)->sin_port = 0;
556 ((
struct sockaddr_in6 *)our_sockaddr)->sin6_port = 0;
558 if (bind(sockfd, SA(our_sockaddr), SA_LEN(our_sockaddr)) < 0) {
572static int plain_tcp_get_fd(
void *ptr,
struct sockaddr *our_sockaddr)
576 sockfd = socket(our_sockaddr->sa_family, SOCK_STREAM, 0);
581 if (our_sockaddr->sa_family == AF_INET)
582 ((
struct sockaddr_in *)our_sockaddr)->sin_port = 0;
584 ((
struct sockaddr_in6 *)our_sockaddr)->sin6_port = 0;
586 if (bind(sockfd, SA(our_sockaddr), SA_LEN(our_sockaddr)) < 0) {
593static const rc_sockets_override default_socket_funcs = {
594 .get_fd = plain_get_fd,
595 .close_fd = plain_close_fd,
596 .sendto = plain_sendto,
597 .recvfrom = plain_recvfrom
600static const rc_sockets_override default_tcp_socket_funcs = {
601 .get_fd = plain_tcp_get_fd,
602 .close_fd = plain_close_fd,
603 .sendto = plain_tcp_sendto,
604 .recvfrom = plain_recvfrom
613static int set_addr(
struct sockaddr_storage *ss,
const char *ip)
615 memset(ss, 0,
sizeof(*ss));
616 if (inet_pton(AF_INET, ip, &((
struct sockaddr_in *)ss)->sin_addr) == 1) {
617 ss->ss_family = AF_INET;
618 }
else if (inet_pton(AF_INET6, ip, &((
struct sockaddr_in6 *)ss)->sin6_addr) == 1) {
619 ss->ss_family = AF_INET6;
621 rc_log(LOG_CRIT,
"invalid IP address for nas-ip: %s", ip);
646static void apply_secret_fallback_one(rc_handle *rh,
const char *optname,
const char *secret)
648 SERVER *serv = radcli2_priv_conf_srv(rh, optname);
651 if (serv == NULL || serv->max == 0)
653 if (serv->secret[0] != NULL && serv->secret[0][0] !=
'\0')
656 dup = strdup(secret);
660 free(serv->secret[0]);
661 serv->secret[0] = dup;
669static void apply_secret_fallback(rc_handle *rh)
671 const char *secret = rc_conf_str_id(rh, OPT_SECRET);
673 if (secret == NULL || secret[0] ==
'\0')
676 apply_secret_fallback_one(rh,
"authserver", secret);
677 apply_secret_fallback_one(rh,
"acctserver", secret);
689static void apply_int_default(rc_handle *rh,
char const *optname,
int def)
691 OPTION *option = find_option(rh, optname, RADCLI_OPT_TYPE_INT);
694 if (option == NULL || option->val != NULL)
697 val = malloc(
sizeof(*val));
720static int radcli2_priv_check_config(rc_handle *rh,
char const *source)
732 srv = radcli2_priv_conf_srv(rh,
"authserver");
733 if (!srv || !srv->max)
735 if (rc_conf_str_id(rh, OPT_DAE_ACCEPT) == NULL)
737 rc_log(LOG_ERR,
"%s: no authserver or DAE listener specified", source);
748 srv = radcli2_priv_conf_srv(rh,
"acctserver");
749 if (!srv || !srv->max)
755 const char *stype = rc_conf_str_id(rh, OPT_SERV_TYPE);
757 stype = rc_conf_str_id(rh, OPT_SERV_AUTH_TYPE);
759 (strcasecmp(stype,
"tls") != 0 && strcasecmp(stype,
"dtls") != 0))
760 rc_log(LOG_DEBUG,
"%s: no acctserver specified", source);
764 if (rc_conf_int_id(rh, OPT_RADIUS_TIMEOUT) <= 0)
766 rc_log(LOG_ERR,
"%s: radius_timeout <= 0 is illegal", source);
769 if (rc_conf_int_id(rh, OPT_RADIUS_RETRIES) < 0)
771 rc_log(LOG_ERR,
"%s: radius_retries < 0 is illegal", source);
790int radcli2_priv_apply_config(rc_handle *rh)
795 if (radcli2_priv_check_config(rh,
"radcli2_priv_apply_config") == -1)
798 apply_secret_fallback(rh);
799 apply_int_default(rh,
"watchdog-interval", 15);
800 apply_int_default(rh,
"dae-max-clock-skew", 300);
802 memset(&rh->own_bind_addr, 0,
sizeof(rh->own_bind_addr));
803 rh->own_bind_addr_set = 0;
804 rc_own_bind_addr(rh, &rh->own_bind_addr);
805 rh->own_bind_addr_set = 1;
807 txt = rc_conf_str_id(rh, OPT_NAS_IP);
809 if (set_addr(&rh->nas_addr, txt) < 0)
811 rh->nas_addr_set = 1;
814 txt = rc_conf_str_id(rh, OPT_SERV_TYPE);
816 txt = rc_conf_str_id(rh, OPT_SERV_AUTH_TYPE);
821 if (strcasecmp(txt,
"udp") == 0) {
822 memset(&rh->so, 0,
sizeof(rh->so));
824 memcpy(&rh->so, &default_socket_funcs,
sizeof(rh->so));
826 }
else if (strcasecmp(txt,
"tcp") == 0) {
827 memset(&rh->so, 0,
sizeof(rh->so));
829 memcpy(&rh->so, &default_tcp_socket_funcs,
sizeof(rh->so));
832 }
else if (strcasecmp(txt,
"dtls") == 0) {
833 ret = rc_init_tls(rh, SEC_FLAG_DTLS);
834 }
else if (strcasecmp(txt,
"tls") == 0) {
835 ret = rc_init_tls(rh, 0);
838 rc_log(LOG_CRIT,
"unknown server type: %s", txt);
843 rc_log(LOG_CRIT,
"error initializing %s", txt);
859int radcli2_priv_load_builtin_dict(rc_handle *rh)
861 if (radcli2_priv_read_dictionary_from_buffer(rh, rc_rfc_dictionary,
862 sizeof(rc_rfc_dictionary) - 1) != 0) {
863 rc_log(LOG_CRIT,
"radcli2_priv_load_builtin_dict: failed to load built-in RFC dictionary");
880rc_handle *radcli2_priv_read_config(
char const *filename,
int skip_builtin_dict)
883 char *buffer = NULL, *p;
892 rh = radcli2_priv_new();
896 rh->config_options = malloc(
sizeof(config_options_default));
897 if (rh->config_options == NULL) {
898 rc_log(LOG_CRIT,
"radcli2_priv_read_config: out of memory");
899 radcli2_priv_destroy(rh);
902 memcpy(rh->config_options, &config_options_default,
sizeof(config_options_default));
904 if ((configfd = fopen(filename,
"r")) == NULL)
906 rc_log(LOG_ERR,
"radcli2_priv_read_config: can't open %s: %s", filename, strerror(errno));
907 radcli2_priv_destroy(rh);
912 while ((nread = getline(&buffer, &bufsize, configfd)) != -1)
916 if (nread > 0 && buffer[nread-1] ==
'\n')
917 buffer[--nread] =
'\0';
921 if ((*p ==
'#') || (*p ==
'\0'))
924 if ((pos = strcspn(p,
"\t ")) == 0) {
925 rc_log(LOG_ERR,
"%s: line %d: bogus format: %s", filename, line, p);
931 if ((option = find_option(rh, p, OT_ANY)) == NULL) {
932 if (rc_ignored_option(p)) {
933 rc_log(LOG_INFO,
"%s: line %d: option '%s' is no longer used, ignoring", filename, line, p);
936 rc_log(LOG_ERR,
"%s: line %d: unrecognized keyword: %s", filename, line, p);
940 if (option->status != ST_UNDEF) {
941 rc_log(LOG_ERR,
"%s: line %d: duplicate option line: %s", filename, line, p);
950 while (pos != 0 && isspace(p[pos]))
955 switch (option->type) {
956 case RADCLI_OPT_TYPE_STR:
957 if (set_option_str(filename, line, option, p) < 0)
960 case RADCLI_OPT_TYPE_INT:
961 if (set_option_int(filename, line, option, p) < 0)
964 case RADCLI_OPT_TYPE_SRV:
965 if (set_option_srv(rh, filename, line, option, p) < 0)
969 rc_log(LOG_CRIT,
"radcli2_priv_read_config: impossible case branch!");
976 if (radcli2_priv_test_config(rh, filename) == -1) {
977 radcli2_priv_destroy(rh);
982 int clientdebug = rc_conf_int_2(rh,
"clientdebug", FALSE);
983 if(clientdebug > 0) {
984 rh->debug = clientdebug;
991 if (!skip_builtin_dict && radcli2_priv_load_builtin_dict(rh) != 0) {
992 radcli2_priv_destroy(rh);
996 p = rc_conf_str_id(rh, OPT_DICTIONARY);
998 if (radcli2_priv_read_dictionary(rh, p) != 0) {
999 rc_log(LOG_CRIT,
"could not load dictionary");
1000 radcli2_priv_destroy(rh);
1010 radcli2_priv_destroy(rh);
1020char *radcli2_priv_conf_str(rc_handle
const *rh,
char const *optname)
1024 option = find_option(rh, optname, RADCLI_OPT_TYPE_STR);
1026 if (option != NULL) {
1027 return (
char *)option->val;
1029 rc_log(LOG_CRIT,
"radcli2_priv_conf_str: unknown config option requested: %s", optname);
1042static int rc_conf_int_2(rc_handle
const *rh,
char const *optname,
int complain)
1046 option = find_option(rh, optname, RADCLI_OPT_TYPE_INT);
1048 if (option != NULL) {
1050 return *((
int *)option->val);
1051 }
else if(complain) {
1052 rc_log(LOG_ERR,
"radcli2_priv_conf_int: config option %s was not set", optname);
1056 rc_log(LOG_CRIT,
"radcli2_priv_conf_int: unknown config option requested: %s", optname);
1067int radcli2_priv_conf_int(rc_handle
const *rh,
char const *optname)
1069 return rc_conf_int_2(rh, optname, TRUE);
1078SERVER *radcli2_priv_conf_srv(rc_handle
const *rh,
char const *optname)
1082 option = find_option(rh, optname, RADCLI_OPT_TYPE_SRV);
1084 if (option != NULL) {
1085 return (SERVER *)option->val;
1087 rc_log(LOG_CRIT,
"radcli2_priv_conf_srv: unknown config option requested: %s", optname);
1098int radcli2_priv_test_config(rc_handle *rh,
char const *filename)
1100 if (radcli2_priv_check_config(rh, filename) == -1)
1103 if (radcli2_priv_apply_config(rh) == -1) {
1116static int find_match (
const struct addrinfo* addr,
const struct addrinfo *hostname)
1118 const struct addrinfo *ptr, *ptr2;
1119 unsigned len1, len2;
1125 len1 = SA_GET_INLEN(ptr->ai_addr);
1126 len2 = SA_GET_INLEN(ptr2->ai_addr);
1130 memcmp(SA_GET_INADDR(ptr->ai_addr), SA_GET_INADDR(ptr2->ai_addr), len1) == 0) {
1133 ptr2 = ptr2->ai_next;
1145static int rc_ipaddr_local(
const struct sockaddr *addr)
1147 int temp_sock, res, serrno;
1148 struct sockaddr_storage tmpaddr;
1150 memcpy(&tmpaddr, addr, SA_LEN(addr));
1152 temp_sock = socket(addr->sa_family, SOCK_DGRAM, 0);
1153 if (temp_sock == -1)
1156 if (addr->sa_family == AF_INET) {
1157 ((
struct sockaddr_in*)&tmpaddr)->sin_port = 0;
1159 ((
struct sockaddr_in6*)&tmpaddr)->sin6_port = 0;
1161 res = bind(temp_sock, SA(&tmpaddr), SS_LEN(&tmpaddr));
1166 if (serrno == EADDRNOTAVAIL)
1176static int rc_is_myname(
const struct addrinfo *info)
1178 const struct addrinfo *p;
1183 res = rc_ipaddr_local(p->ai_addr);
1184 if (res == 0 || res == -1) {
1202int radcli2_priv_find_server_addr (rc_handle
const *rh,
char const *server_name,
1203 struct addrinfo** info,
char *secret,
rc_type type)
1209 char *buffer = NULL;
1211 char hostnm[AUTH_ID_LEN + 1];
1215 struct addrinfo *tmpinfo = NULL;
1216 const char *fservers;
1217 char const *optname;
1220 if ((*info = rc_getaddrinfo (server_name, type==
AUTH?PW_AI_AUTH:PW_AI_ACCT)) == NULL)
1225 case AUTH: optname =
"authserver";
break;
1226 case ACCT: optname =
"acctserver";
break;
1227 default: optname = NULL;
1230 if ( (optname != NULL) &&
1231 ((servers = radcli2_priv_conf_srv(rh, optname)) != NULL) )
1235 for (servernum = 0; servernum < servers->max; servernum++)
1237 if( (strcmp(server_name, servers->name[servernum]) == 0) &&
1238 (servers->secret[servernum] != NULL) )
1240 memset(secret,
'\0', MAX_SECRET_LENGTH);
1241 strlcpy(secret, servers->secret[servernum], MAX_SECRET_LENGTH);
1251 fservers = rc_conf_str_id(rh, OPT_SERVERS);
1252 if (fservers != NULL) {
1253 if ((clientfd = fopen (fservers,
"r")) == NULL)
1255 rc_log(LOG_ERR,
"rc_find_server: couldn't open file: %s: %s", strerror(errno), fservers);
1259 while (getline (&buffer, &bufsize, clientfd) != -1)
1264 if ((h = strtok_r(buffer,
" \t\n", &buffer_save)) == NULL)
1267 strlcpy (hostnm, h, AUTH_ID_LEN);
1269 if ((s = strtok_r (NULL,
" \t\n", &buffer_save)) == NULL)
1272 strlcpy (secret, s, MAX_SECRET_LENGTH);
1274 if (!strchr (hostnm,
'/'))
1276 tmpinfo = rc_getaddrinfo(hostnm, 0);
1279 result = find_match (*info, tmpinfo);
1286 freeaddrinfo(tmpinfo);
1292 strtok_r(hostnm,
"/", &hostnm_save);
1293 tmpinfo = rc_getaddrinfo(hostnm, 0);
1296 if (rc_is_myname(tmpinfo) == 0)
1298 if (find_match (*info, tmpinfo) == 0)
1306 if (find_match (*info, tmpinfo) == 0)
1312 freeaddrinfo(tmpinfo);
1336 memset(secret,
'\0', MAX_SECRET_LENGTH);
1340 memset (secret,
'\0', MAX_SECRET_LENGTH);
1341 rc_log(LOG_ERR,
"rc_find_server: couldn't find RADIUS server %s in %s",
1342 server_name, rc_conf_str_id(rh, OPT_SERVERS));
1350 freeaddrinfo(*info);
1355 freeaddrinfo(tmpinfo);
1367void radcli2_priv_config_free(rc_handle *rh)
1372 if (rh->config_options == NULL)
1375 for (i = 0; i < NUM_OPTIONS; i++) {
1376 if (rh->config_options[i].val == NULL)
1378 if (rh->config_options[i].type == RADCLI_OPT_TYPE_SRV) {
1379 serv = (SERVER *)rh->config_options[i].val;
1380 server_free_entries(serv, 0, serv->max);
1383 free(rh->config_options[i].val);
1386 free(rh->config_options);
1387 free(rh->first_dict_read);
1388 rh->config_options = NULL;
1389 rh->first_dict_read = NULL;
1392static int _initialized = 0;
1399rc_handle *radcli2_priv_new(
void)
1403 if (_initialized == 0) {
1404#if defined(HAVE_GNUTLS) && GNUTLS_VERSION_NUMBER < 0x030300
1406 ret = gnutls_global_init();
1409 "%s: error initializing gnutls: %s",
1410 __func__, gnutls_strerror(ret));
1417 rh = calloc(1,
sizeof(*rh));
1419 rc_log(LOG_CRIT,
"radcli2_priv_new: out of memory");
1424 pthread_mutex_init(&rh->reqreg_init_lock, NULL);
1432void radcli2_priv_destroy(rc_handle *rh)
1434 radcli2_priv_dict_free(rh);
1438 radcli2_priv_config_free(rh);
1442 if (rh->req_fd != -1 && rh->so.close_fd)
1443 rh->so.close_fd(rh->req_fd);
1444 if (rh->reqreg != NULL) {
1445 pthread_mutex_destroy(&rh->reqreg->lock);
1448 pthread_mutex_destroy(&rh->reqreg_init_lock);
1449 free(rh->tls_psk_identity);
1450 free(rh->tls_psk_key);
1453#if defined(HAVE_GNUTLS) && GNUTLS_VERSION_NUMBER < 0x030300
1455 if (_initialized == 0) {
1456 gnutls_global_deinit();
@ ACCT
Request for accounting server.
@ AUTH
Request for authentication server.
@ RC_SOCKET_UDP
Plain UDP socket.
@ RC_SOCKET_TCP
Plain TCP socket.
@ RC_SOCKET_DTLS
DTLS socket.
@ RC_SOCKET_TLS
TLS socket.