diff -aur radiusclient//include/freeradius-client.h /usr/src/radiusclient//include/freeradius-client.h --- radiusclient//include/freeradius-client.h 2010-06-15 12:22:51.000000000 +0300 +++ /usr/src/radiusclient//include/freeradius-client.h 2010-07-25 11:38:15.317901407 +0300 @@ -24,6 +24,8 @@ #endif #include +#include + /* * Include for C99 uintX_t defines is stdint.h on most systems. Solaris uses * inttypes.h instead. Comment out the stdint include if you get an error, @@ -103,6 +105,11 @@ char ifname[512]; }; +struct rad_hostent { + struct hostent hp; + char buf[1024]; +}; + typedef struct rc_conf rc_handle; #define AUTH_HDR_LEN 20 @@ -464,11 +471,11 @@ /* ip_util.c */ -struct hostent *rc_gethostbyname(const char *); -struct hostent *rc_gethostbyaddr(const char *, size_t, int); +struct hostent *rc_gethostbyname(const char *, struct rad_hostent *); +struct hostent *rc_gethostbyaddr(const char *, size_t, int, struct rad_hostent *); uint32_t rc_get_ipaddr(char *); int rc_good_ipaddr(char *); -const char *rc_ip_hostname(uint32_t); +const char *rc_ip_hostname(char *, size_t, uint32_t); unsigned short rc_getport(int); int rc_own_hostname(char *, int); uint32_t rc_own_ipaddress(rc_handle *); diff -aur radiusclient//lib/avpair.c /usr/src/radiusclient//lib/avpair.c --- radiusclient//lib/avpair.c 2010-06-15 12:22:52.000000000 +0300 +++ /usr/src/radiusclient//lib/avpair.c 2010-07-25 11:38:15.317901407 +0300 @@ -564,7 +564,7 @@ case PW_TYPE_DATE: timeval = time (0); - tm = localtime (&timeval); + localtime_r (&timeval, tm); tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; @@ -649,8 +649,10 @@ { DICT_VALUE *dval; char buffer[32]; + char ip[32]; struct in_addr inad; unsigned char *ptr; + struct tm *gmt; *name = *value = '\0'; @@ -677,7 +679,7 @@ sprintf (buffer, "\\%03o", *ptr); strncat(value, buffer, (size_t) lv); lv -= 4; - if (lv < 0) break; + if (lv <= 0) break; } else { @@ -703,15 +705,17 @@ break; case PW_TYPE_IPADDR: - inad.s_addr = htonl(pair->lvalue); - strncpy (value, inet_ntoa (inad), (size_t) lv-1); - break; + inad.s_addr = htonl(pair->lvalue); + inet_ntop(AF_INET,&inad,ip,sizeof(ip)); + strncpy (value, ip, (size_t) lv-1); + break; + case PW_TYPE_DATE: - strftime (buffer, sizeof (buffer), "%m/%d/%y %H:%M:%S", - gmtime ((time_t *) & pair->lvalue)); - strncpy(value, buffer, lv-1); - break; + gmtime_r ((time_t *) & pair->lvalue, gmt); + strftime (buffer, sizeof (buffer), "%m/%d/%y %H:%M:%S", gmt); + strncpy(value, buffer, lv-1); + break; default: rc_log(LOG_ERR, "rc_avpair_tostr: unknown attribute type %d", pair->type); diff -aur radiusclient//lib/buildreq.c /usr/src/radiusclient//lib/buildreq.c --- radiusclient//lib/buildreq.c 2010-02-04 12:27:09.000000000 +0200 +++ /usr/src/radiusclient//lib/buildreq.c 2010-07-25 11:38:15.317901407 +0300 @@ -44,8 +44,10 @@ unsigned char rc_get_id() { - srandom((unsigned int)(time(NULL)+getpid())); - return (unsigned char)(random() & UCHAR_MAX); +// srandom((unsigned int)(time(NULL)+getpid())); +// return (unsigned char)(random() & UCHAR_MAX); + static volatile unsigned char id=0; + return ++id; } /* diff -aur radiusclient//lib/config.c /usr/src/radiusclient//lib/config.c --- radiusclient//lib/config.c 2010-04-28 17:26:15.000000000 +0300 +++ /usr/src/radiusclient//lib/config.c 2010-07-25 11:38:15.317901407 +0300 @@ -94,7 +94,9 @@ char *p_save; char *q; char *s; - struct servent *svp; + struct servent servbuf, *svp; + char buffer[128]; + int ret; p_dupe = strdup(p); @@ -142,12 +144,12 @@ serv->port[serv->max] = atoi(q); } else { if (!strcmp(option->name,"authserver")) - if ((svp = getservbyname ("radius", "udp")) == NULL) + if ((ret = getservbyname_r ("radius", "udp", &servbuf, buffer, sizeof(buffer), &svp)) != 0) serv->port[serv->max] = PW_AUTH_UDP_PORT; else serv->port[serv->max] = ntohs ((unsigned int) svp->s_port); else if (!strcmp(option->name, "acctserver")) - if ((svp = getservbyname ("radacct", "udp")) == NULL) + if ((ret = getservbyname_r ("radacct", "udp", &servbuf, buffer, sizeof(buffer), &svp)) != 0) serv->port[serv->max] = PW_ACCT_UDP_PORT; else serv->port[serv->max] = ntohs ((unsigned int) svp->s_port); @@ -635,6 +637,8 @@ uint32_t addr; char **paddr; struct hostent *hp; + struct rad_hostent rhp; + if (rc_good_ipaddr (hostname) == 0) { @@ -645,7 +649,7 @@ return -1; } - if ((hp = rc_gethostbyname(hostname)) == NULL) + if ((hp = rc_gethostbyname(hostname, &rhp)) == NULL) { return -1; } @@ -708,18 +712,22 @@ uint32_t addr; char **paddr; struct hostent *hp; + struct rad_hostent rhp; int res; + if (rc_good_ipaddr(hostname) == 0) return rc_ipaddr_local(ntohl(inet_addr(hostname))); - if ((hp = rc_gethostbyname(hostname)) == NULL) + if ((hp = rc_gethostbyname(hostname, &rhp)) == NULL) { return -1; + } for (paddr = hp->h_addr_list; *paddr; paddr++) { addr = **(uint32_t **)paddr; res = rc_ipaddr_local(ntohl(addr)); - if (res == 0 || res == -1) + if (res == 0 || res == -1) { return res; + } } return 1; } @@ -895,8 +903,10 @@ continue; if (rh->config_options[i].type == OT_SRV) { serv = (SERVER *)rh->config_options[i].val; - for (j = 0; j < serv->max; j++) + for (j = 0; j < serv->max; j++) { free(serv->name[j]); + if(serv->secret[j]) free(serv->secret[j]); + } free(serv); } else { free(rh->config_options[i].val); diff -aur radiusclient//lib/ip_util.c /usr/src/radiusclient//lib/ip_util.c --- radiusclient//lib/ip_util.c 2010-03-17 20:57:01.000000000 +0200 +++ /usr/src/radiusclient//lib/ip_util.c 2010-07-26 16:46:44.118086539 +0300 @@ -18,18 +18,12 @@ #include #include -#define HOSTBUF_SIZE 1024 - #if !defined(SA_LEN) #define SA_LEN(sa) \ (((sa)->sa_family == AF_INET) ? \ sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) #endif - -static __thread size_t hostbuflen=HOSTBUF_SIZE; -static __thread char *tmphostbuf=NULL; - /* * Function: rc_gethostbyname * @@ -38,41 +32,38 @@ * Returns: NULL on failure, hostent pointer on success */ -struct hostent *rc_gethostbyname(const char *hostname) +struct hostent *rc_gethostbyname(const char *hostname, struct rad_hostent *hp) { - struct hostent *hp; + struct hostent *result; #ifdef GETHOSTBYNAME_R #if defined (GETHOSTBYNAMERSTYLE_SYSV) || defined (GETHOSTBYNAMERSTYLE_GNU) - struct hostent hostbuf; int res; int herr; - if(!tmphostbuf) tmphostbuf = malloc(hostbuflen); #endif #endif #ifdef GETHOSTBYNAME_R #if defined (GETHOSTBYNAMERSTYLE_GNU) - while ((res = gethostbyname_r(hostname, &hostbuf, tmphostbuf, hostbuflen, &hp, &herr)) == ERANGE) + while ((res = gethostbyname_r(hostname, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herr)) == ERANGE) { - /* Enlarge the buffer */ - hostbuflen *= 2; - tmphostbuf = realloc(tmphostbuf, hostbuflen); + rc_log(LOG_ERR,"gethostbyname_r error, tmphostbuf size is not enouth\n"); + return NULL; } if(res) return NULL; #elif defined (GETHOSTBYNAMERSTYLE_SYSV) - hp = gethostbyname_r(hostname, &hostbuf, tmphostbuf, hostbuflen, &herr); + &hp->hp = gethostbyname_r(hostname, &hp->hp, hp->buf, sizeof(hp->buf), &herr); #else - hp = gethostbyname(hostname); + &hp->hp = gethostbyname(hostname); #endif #else - hp = gethostbyname(hostname); + &hp->hp = gethostbyname(hostname); #endif - if (hp == NULL) { + if (&hp->hp == NULL) { return NULL; } - return hp; + return &hp->hp; } /* @@ -83,42 +74,38 @@ * Returns: NULL on failure, hostent pointer on success */ -struct hostent *rc_gethostbyaddr(const char *addr, size_t length, int format) +struct hostent *rc_gethostbyaddr(const char *addr, size_t length, int format, struct rad_hostent *hp) { - struct hostent *hp; + struct hostent *result; #ifdef GETHOSTBYADDR_R #if defined (GETHOSTBYADDRRSTYLE_SYSV) || defined (GETHOSTBYADDRRSTYLE_GNU) - struct hostent hostbuf; int res; int herr; - if(!tmphostbuf) tmphostbuf = malloc(hostbuflen); #endif #endif #ifdef GETHOSTBYADDR_R #if defined (GETHOSTBYADDRRSTYLE_GNU) - while ((res = gethostbyaddr_r(addr, length, format, &hostbuf, tmphostbuf, hostbuflen, - &hp, &herr)) == ERANGE) + while ((res = gethostbyaddr_r(addr, length, format, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herr)) == ERANGE) { - /* Enlarge the buffer */ - hostbuflen *= 2; - tmphostbuf = realloc(tmphostbuf, hostbuflen); + rc_log(LOG_ERR,"gethostbyaddr_r error, tmphostbuf size is not enouth\n"); + return NULL; } if(res) return NULL; #elif GETHOSTBYADDRSTYLE_SYSV - hp = gethostbyaddr_r(addr, length, format, &hostbuf, tmphostbuf, hostbuflen, &herr); + &hp->hp = gethostbyaddr_r(addr, length, format, &hp->hp, hp->buf, sizeof(hp->buf), &herr); #else - hp = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET); + &hp->hp = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET); #endif #else - hp = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET); + &hp->hp = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET); #endif - if (hp == NULL) { + if (&hp->hp == NULL) { return NULL; } - return hp; + return &hp->hp; } /* @@ -132,18 +119,21 @@ uint32_t rc_get_ipaddr (char *host) { - struct hostent *hp; + struct hostent *hp; + struct rad_hostent rhp; + uint32_t a; if (rc_good_ipaddr (host) == 0) { return ntohl(inet_addr (host)); } - else if ((hp = rc_gethostbyname(host)) == NULL) + else if ((hp = rc_gethostbyname(host, &rhp)) == NULL) { rc_log(LOG_ERR,"rc_get_ipaddr: couldn't resolve hostname: %s", host); return (uint32_t)0; } - return ntohl((*(uint32_t *) hp->h_addr)); + memcpy(&a, hp->h_addr, sizeof(uint32_t)); + return ntohl(a); } /* @@ -204,17 +194,50 @@ * */ -const char *rc_ip_hostname (uint32_t h_ipaddr) +char *ip_ntoa(char *buffer, uint32_t ipaddr) { - struct hostent *hp; - uint32_t n_ipaddr = htonl (h_ipaddr); + ipaddr = ntohl(ipaddr); - if ((hp = rc_gethostbyaddr ((char *) &n_ipaddr, sizeof (struct in_addr), - AF_INET)) == NULL) { - rc_log(LOG_ERR,"rc_ip_hostname: couldn't look up host by addr: %08lX", h_ipaddr); - } + sprintf(buffer, "%d.%d.%d.%d", + (ipaddr >> 24) & 0xff, + (ipaddr >> 16) & 0xff, + (ipaddr >> 8) & 0xff, + (ipaddr ) & 0xff); + return buffer; +} + +char *strNcpy(char *dest, const char *src, int n) +{ + char *p = dest; + + while ((n > 1) && (*src)) { + *(p++) = *(src++); + + n--; + } + *p = '\0'; + + return dest; +} + +const char *rc_ip_hostname (char *buf, size_t buflen, uint32_t h_ipaddr) +{ + struct hostent *hp; + struct rad_hostent rhp; + uint32_t n_ipaddr = htonl (h_ipaddr); + + if ((hp = rc_gethostbyaddr ((char *) &n_ipaddr, sizeof (struct in_addr), + AF_INET, &rhp)) == NULL) { + rc_log(LOG_ERR,"rc_ip_hostname: couldn't look up host by addr: %08lX", h_ipaddr); + } + if ((hp == NULL) || (hp->h_name==NULL) || + (strlen((char *)hp->h_name) >= buflen)) { + ip_ntoa(buf, h_ipaddr); + return buf; + } - return (hp == NULL) ? "unknown" : hp->h_name; + strNcpy(buf, (char *)hp->h_name, buflen); + return buf; } /* @@ -226,9 +249,11 @@ unsigned short rc_getport(int type) { - struct servent *svp; + struct servent servbuf, *svp; + int ret; + char buffer[128]; - if ((svp = getservbyname ((type==AUTH)?"radius":"radacct", "udp")) == NULL) + if ((ret = getservbyname_r ((type==AUTH)?"radius":"radacct", "udp", &servbuf, buffer, sizeof(buffer),&svp)) != 0) { return (type==AUTH) ? PW_AUTH_UDP_PORT : PW_ACCT_UDP_PORT; } else { diff -aur radiusclient//lib/sendserver.c /usr/src/radiusclient//lib/sendserver.c --- radiusclient//lib/sendserver.c 2010-06-15 12:22:52.000000000 +0300 +++ /usr/src/radiusclient//lib/sendserver.c 2010-07-25 11:38:15.322013503 +0300 @@ -301,10 +301,6 @@ auth->length = htons ((unsigned short) total_length); } - DEBUG(LOG_ERR, "DEBUG: local %s : 0, remote %s : %u\n", - inet_ntoa(sinlocal.sin_addr), - inet_ntoa(sinremote.sin_addr), data->svc_port); - for (;;) { sendto (sockfd, (char *) auth, (unsigned int) total_length, (int) 0, @@ -336,9 +332,10 @@ */ if (++retries >= retry_max) { + char buf[254]; rc_log(LOG_ERR, - "rc_send_server: no reply from RADIUS server %s:%u, %s", - rc_ip_hostname (auth_ipaddr), data->svc_port, inet_ntoa(sinremote.sin_addr)); + "rc_send_server: no reply from RADIUS server %s:%u", + rc_ip_hostname (buf, 254, auth_ipaddr), data->svc_port); close (sockfd); memset (secret, '\0', sizeof (secret)); return TIMEOUT_RC; @@ -568,10 +565,10 @@ return; } /* else fall through */ #endif - srand ((unsigned)time (0) + getppid() + getpid()); /* random enough :) */ + unsigned int seed=(unsigned)time (0) + getppid() + getpid(); /* random enough :) */ for (i = 0; i < AUTH_VECTOR_LEN;) { - randno = rand (); + randno = rand_r (&seed); memcpy ((char *) vector, (char *) &randno, sizeof (int)); vector += sizeof (int); i += sizeof (int);