*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
- * Copyright 2000 The FreeRADIUS server project
+ * Copyright 2000,2006 The FreeRADIUS server project
* Copyright 2000 Alan DeKok <aland@ox.org>
*/
-static const char rcsid[] =
-"$Id$";
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
-#include "autoconf.h"
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/rad_assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <ctype.h>
-#include "radiusd.h"
-
-#include "rad_assert.h"
-
typedef struct xlat_t {
char module[MAX_STRING_LEN];
int length;
/*
* Define all xlat's in the structure.
*/
-static const char *internal_xlat[] = {"check",
- "request",
- "reply",
- "proxy-request",
- "proxy-reply",
- NULL};
+static const char * const internal_xlat[] = {"check",
+ "request",
+ "reply",
+ "proxy-request",
+ "proxy-reply",
+ NULL};
#if REQUEST_MAX_REGEX > 8
#error Please fix the following line
switch (type) {
case PW_TYPE_STRING :
- strNcpy(out,"_",outlen);
+ strlcpy(out,"_",outlen);
break;
case PW_TYPE_INTEGER :
- strNcpy(out,"0",outlen);
+ strlcpy(out,"0",outlen);
break;
case PW_TYPE_IPADDR :
- strNcpy(out,"?.?.?.?",outlen);
+ strlcpy(out,"?.?.?.?",outlen);
break;
case PW_TYPE_IPV6ADDR :
- strNcpy(out,":?:",outlen);
+ strlcpy(out,":?:",outlen);
break;
case PW_TYPE_DATE :
- strNcpy(out,"0",outlen);
+ strlcpy(out,"0",outlen);
break;
default :
- strNcpy(out,"unknown_type",outlen);
+ strlcpy(out,"unknown_type",outlen);
}
return strlen(out);
}
if (!p) return 0;
if (strlen(fmt) > sizeof(buffer)) return 0;
- strNcpy(buffer, fmt, p - fmt + 1);
+ strlcpy(buffer, fmt, p - fmt + 1);
da = dict_attrbyname(buffer);
if (!da) return 0;
/*
* %{Attribute-Name[*]} returns ALL of the
* the attributes, separated by a newline.
- */
+ */
if ((p[1] == '*') && (p[2] == ']')) {
int total = 0;
total += count + 1;
outlen -= (count + 1);
out += count;
-
+
*(out++) = '\n';
if (outlen == 0) break;
return total;
}
-
+
count = atoi(p + 1);
/*
if (packet) {
VALUE_PAIR localvp;
- localvp.strvalue[0] = 0;
+ localvp.vp_strvalue[0] = 0;
switch (da->attr) {
case PW_PACKET_TYPE:
{
DICT_VALUE *dval;
-
+
dval = dict_valbyattr(da->attr, packet->code);
if (dval) {
snprintf(out, outlen, "%s", dval->name);
return 0;
}
localvp.attribute = da->attr;
- localvp.lvalue = packet->src_ipaddr.ipaddr.ip4addr.s_addr;
+ localvp.vp_ipaddr = packet->src_ipaddr.ipaddr.ip4addr.s_addr;
break;
-
+
case PW_PACKET_DST_IP_ADDRESS:
if (packet->dst_ipaddr.af != AF_INET) {
return 0;
}
localvp.attribute = da->attr;
- localvp.lvalue = packet->dst_ipaddr.ipaddr.ip4addr.s_addr;
+ localvp.vp_ipaddr = packet->dst_ipaddr.ipaddr.ip4addr.s_addr;
break;
-
+
case PW_PACKET_SRC_PORT:
localvp.attribute = da->attr;
- localvp.lvalue = packet->src_port;
+ localvp.vp_integer = packet->src_port;
break;
-
+
case PW_PACKET_DST_PORT:
localvp.attribute = da->attr;
- localvp.lvalue = packet->dst_port;
+ localvp.vp_integer = packet->dst_port;
break;
case PW_PACKET_AUTHENTICATION_VECTOR:
localvp.attribute = da->attr;
- memcpy(localvp.strvalue, packet->vector,
+ memcpy(localvp.vp_strvalue, packet->vector,
sizeof(packet->vector));
localvp.length = sizeof(packet->vector);
break;
*/
case PW_REQUEST_PROCESSING_STAGE:
if (request->component) {
- strNcpy(out, request->component, outlen);
+ strlcpy(out, request->component, outlen);
} else {
- strNcpy(out, "server_core", outlen);
+ strlcpy(out, "server_core", outlen);
}
return strlen(out);
-
+
case PW_PACKET_SRC_IPV6_ADDRESS:
if (packet->src_ipaddr.af != AF_INET6) {
return 0;
}
localvp.attribute = da->attr;
- memcpy(localvp.strvalue,
- &packet->src_ipaddr.ipaddr.ip4addr.s_addr,
- sizeof(packet->src_ipaddr.ipaddr.ip4addr.s_addr));
+ memcpy(localvp.vp_strvalue,
+ &packet->src_ipaddr.ipaddr.ip6addr,
+ sizeof(packet->src_ipaddr.ipaddr.ip6addr));
break;
-
+
case PW_PACKET_DST_IPV6_ADDRESS:
if (packet->dst_ipaddr.af != AF_INET6) {
return 0;
}
localvp.attribute = da->attr;
- memcpy(localvp.strvalue,
- &packet->dst_ipaddr.ipaddr.ip4addr.s_addr,
- sizeof(packet->dst_ipaddr.ipaddr.ip4addr.s_addr));
+ memcpy(localvp.vp_strvalue,
+ &packet->dst_ipaddr.ipaddr.ip6addr,
+ sizeof(packet->dst_ipaddr.ipaddr.ip6addr));
break;
-
+
case PW_SERVER_IDENTITY:
- if (!request->listener->identity) return 0;
+ if (!request->listener || !request->listener->identity) return 0;
snprintf(out, outlen, "%s", request->listener->identity);
return strlen(out);
break;
-
+
default:
return 0; /* not found */
break;
*/
fmt = fmt; /* -Wunused */
func = func; /* -Wunused FIXME: do escaping? */
-
- regex = request_data_get(request, request,
+
+ regex = request_data_reference(request, request,
REQUEST_DATA_REGEX | *(int *)instance);
if (!regex) return 0;
* Copy UP TO "freespace" bytes, including
* a zero byte.
*/
- strNcpy(out, regex, outlen);
- free(regex); /* was strdup'd */
+ strlcpy(out, regex, outlen);
return strlen(out);
}
#endif /* HAVE_REGEX_H */
+
/*
* Compare two xlat_t structs, based ONLY on the module name.
*/
/*
* Look for dictionary attributes first.
*/
- if (dict_attrbyname(module) != NULL) {
+ if ((dict_attrbyname(module) != NULL) ||
+ (strchr(module, '[') != NULL)) {
static const xlat_t dict_xlat = {
"request",
7,
return &dict_xlat;
}
- strNcpy(my_xlat.module, module, sizeof(my_xlat.module));
+ strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
my_xlat.length = strlen(my_xlat.module);
return rbtree_finddata(xlat_root, &my_xlat);
/*
* If it already exists, replace the instance.
*/
- strNcpy(my_xlat.module, module, sizeof(my_xlat.module));
+ strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
my_xlat.length = strlen(my_xlat.module);
c = rbtree_finddata(xlat_root, &my_xlat);
if (c) {
memset(c, 0, sizeof(*c));
c->do_xlat = func;
- strNcpy(c->module, module, sizeof(c->module));
+ strlcpy(c->module, module, sizeof(c->module));
c->length = strlen(c->module);
c->instance = instance;
func = func; /* -Wunused */
- strNcpy(my_xlat.module, module, sizeof(my_xlat.module));
+ if (!module) return;
+
+ strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
my_xlat.length = strlen(my_xlat.module);
node = rbtree_find(xlat_root, &my_xlat);
* Decode an attribute name into a string.
*/
static void decode_attribute(const char **from, char **to, int freespace,
- int *open, REQUEST *request,
+ int *open_p, REQUEST *request,
RADIUS_ESCAPE_STRING func)
{
int do_length = 0;
const char *p;
char *q, *pa;
int found=0, retlen=0;
- int openbraces = *open;
+ int openbraces = *open_p;
const xlat_t *c;
+ int spaces = FALSE;
p = *from;
q = *to;
*/
} else if (*p == '}') {
openbraces--;
- rad_assert(openbraces == *open);
+ rad_assert(openbraces == *open_p);
p++;
xlat_string = xlat_name;
p += 2;
xlat_string = xlat_name;
goto do_xlat;
-
+
} else { /* module name, followed by per-module string */
int stop = 0;
- int delimitbrace = *open;
+ int delimitbrace = *open_p;
rad_assert(*p == ':');
p++; /* skip the ':' */
openbraces++;
p++;
}
-
+
xlat_string = rad_malloc(strlen(p) + 1); /* always returns */
free_xlat_string = TRUE;
pa = xlat_string;
-
+
/*
* Copy over the rest of the string, which is per-module
* data.
*/
while (*p && !stop) {
switch(*p) {
+
/*
* What the heck is this supposed
* to be doing?
*pa++ = *p++;
break;
+ case ':':
+ if (!spaces && p[1] == '-') {
+ p += 2;
+ stop = 1;
+ break;
+ }
+
/*
* This is pretty hokey... we
* should use the functions in
*pa++ = *p++;
}
break;
-
+
+ case ' ':
+ case '\t':
+ spaces = TRUE;
+ /* FALL-THROUGH */
+
default:
*pa++ = *p++;
break;
p += 2;
}
}
-
+
/*
* Look up almost everything in the new tree of xlat
* functions. This makes it a little quicker...
q += retlen;
- while((*p != '\0') && (openbraces > 0)) {
+ while((*p != '\0') && (openbraces > *open_p)) {
/*
* Handle escapes outside of the loop.
*/
p++; /* skip the character */
}
}
-
+
done:
if (free_xlat_string) free(xlat_string);
- *open = openbraces;
+ *open_p = openbraces;
*from = p;
*to = q;
}
*/
static int xlat_copy(char *out, int outlen, const char *in)
{
- int len = 0;
+ int freespace = outlen;
- while (*in) {
- /*
- * Truncate, if too much.
- */
- if (len >= outlen) {
- break;
- }
+ rad_assert(outlen > 0);
+ while ((*in) && (freespace > 1)) {
/*
* Copy data.
*
* FIXME: Do escaping of bad stuff!
*/
- *out = *in;
+ *(out++) = *(in++);
- out++;
- in++;
- len++;
+ freespace--;
}
-
*out = '\0';
- return len;
+
+ return (outlen - freespace); /* count does not include NUL */
}
/*
int radius_xlat(char *out, int outlen, const char *fmt,
REQUEST *request, RADIUS_ESCAPE_STRING func)
{
- int i, c,freespace;
+ int c, len, freespace;
const char *p;
char *q;
+ char *nl;
VALUE_PAIR *tmp;
struct tm *TM, s_TM;
char tmpdt[40]; /* For temporary storing of dates */
break;
case 'd': /* request day */
TM = localtime_r(&request->timestamp, &s_TM);
- strftime(tmpdt,sizeof(tmpdt),"%d",TM);
- strNcpy(q,tmpdt,freespace);
- q += strlen(q);
+ len = strftime(tmpdt, sizeof(tmpdt), "%d", TM);
+ if (len > 0) {
+ strlcpy(q, tmpdt, freespace);
+ q += strlen(q);
+ }
p++;
break;
case 'f': /* Framed IP address */
break;
case 'l': /* request timestamp */
snprintf(tmpdt, sizeof(tmpdt), "%lu",
- (unsigned long) request->timestamp);
- strNcpy(q,tmpdt,freespace);
+ (unsigned long) request->received.tv_sec);
+ strlcpy(q,tmpdt,freespace);
q += strlen(q);
p++;
break;
case 'm': /* request month */
TM = localtime_r(&request->timestamp, &s_TM);
- strftime(tmpdt,sizeof(tmpdt),"%m",TM);
- strNcpy(q,tmpdt,freespace);
- q += strlen(q);
+ len = strftime(tmpdt, sizeof(tmpdt), "%m", TM);
+ if (len > 0) {
+ strlcpy(q, tmpdt, freespace);
+ q += strlen(q);
+ }
p++;
break;
case 'n': /* NAS IP address */
p++;
break;
case 't': /* request timestamp */
- CTIME_R(&request->timestamp, q, freespace);
- q = strchr(q, '\n');
- if (q) {
- *q = '\0';
- } else {
- q += strlen(q);
- }
+ CTIME_R(&request->timestamp, tmpdt, sizeof(tmpdt));
+ nl = strchr(tmpdt, '\n');
+ if (nl) *nl = '\0';
+ strlcpy(q, tmpdt, freespace);
+ q += strlen(q);
p++;
break;
case 'u': /* User name */
p++;
break;
case 'A': /* radacct_dir */
- strNcpy(q,radacct_dir,freespace-1);
+ strlcpy(q,radacct_dir,freespace);
q += strlen(q);
p++;
break;
case 'C': /* ClientName */
- strNcpy(q,client_name(&request->packet->src_ipaddr),freespace-1);
+ strlcpy(q,client_name_old(&request->packet->src_ipaddr),freespace);
q += strlen(q);
p++;
break;
case 'D': /* request date */
TM = localtime_r(&request->timestamp, &s_TM);
- strftime(tmpdt,sizeof(tmpdt),"%Y%m%d",TM);
- strNcpy(q,tmpdt,freespace);
- q += strlen(q);
+ len = strftime(tmpdt, sizeof(tmpdt), "%Y%m%d", TM);
+ if (len > 0) {
+ strlcpy(q, tmpdt, freespace);
+ q += strlen(q);
+ }
p++;
break;
case 'H': /* request hour */
TM = localtime_r(&request->timestamp, &s_TM);
- strftime(tmpdt,sizeof(tmpdt),"%H",TM);
- strNcpy(q,tmpdt,freespace);
- q += strlen(q);
+ len = strftime(tmpdt, sizeof(tmpdt), "%H", TM);
+ if (len > 0) {
+ strlcpy(q, tmpdt, freespace);
+ q += strlen(q);
+ }
p++;
break;
case 'L': /* radlog_dir */
- strNcpy(q,radlog_dir,freespace-1);
+ strlcpy(q,radlog_dir,freespace);
q += strlen(q);
p++;
break;
p++;
break;
case 'R': /* radius_dir */
- strNcpy(q,radius_dir,freespace-1);
+ strlcpy(q,radius_dir,freespace);
q += strlen(q);
p++;
break;
case 'S': /* request timestamp in SQL format*/
TM = localtime_r(&request->timestamp, &s_TM);
- strftime(tmpdt,sizeof(tmpdt),"%Y-%m-%d %H:%M:%S",TM);
- strNcpy(q,tmpdt,freespace);
- q += strlen(q);
+ len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d %H:%M:%S", TM);
+ if (len > 0) {
+ strlcpy(q, tmpdt, freespace);
+ q += strlen(q);
+ }
p++;
break;
case 'T': /* request timestamp */
TM = localtime_r(&request->timestamp, &s_TM);
- strftime(tmpdt,sizeof(tmpdt),"%Y-%m-%d-%H.%M.%S.000000",TM);
- strNcpy(q,tmpdt,freespace);
- q += strlen(q);
+ len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d-%H.%M.%S.000000", TM);
+ if (len > 0) {
+ strlcpy(q, tmpdt, freespace);
+ q += strlen(q);
+ }
p++;
break;
case 'U': /* Stripped User name */
p++;
break;
case 'V': /* Request-Authenticator */
- if (request->packet->verified)
- strNcpy(q,"Verified",freespace-1);
- else
- strNcpy(q,"None",freespace-1);
+ strlcpy(q,"Verified",freespace);
q += strlen(q);
p++;
break;
case 'Y': /* request year */
TM = localtime_r(&request->timestamp, &s_TM);
- strftime(tmpdt,sizeof(tmpdt),"%Y",TM);
- strNcpy(q,tmpdt,freespace);
- q += strlen(q);
+ len = strftime(tmpdt, sizeof(tmpdt), "%Y", TM);
+ if (len > 0) {
+ strlcpy(q, tmpdt, freespace);
+ q += strlen(q);
+ }
p++;
break;
case 'Z': /* Full request pairs except password */
tmp = request->packet->vps;
while (tmp && (freespace > 3)) {
- if (tmp->attribute != PW_PASSWORD) {
+ if (tmp->attribute != PW_USER_PASSWORD) {
*q++ = '\t';
- i = vp_prints(q,freespace-2,tmp);
- q += i;
- freespace -= (i+2);
+ len = vp_prints(q, freespace - 2, tmp);
+ q += len;
+ freespace -= (len + 2);
*q++ = '\n';
}
tmp = tmp->next;