Delete trailing whitespace.
[freeradius.git] / src / main / xlat.c
index 3e40c10..f2528ed 100644 (file)
  *
  *   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;
@@ -49,12 +43,12 @@ static rbtree_t *xlat_root = NULL;
 /*
  *     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
@@ -77,22 +71,22 @@ static int valuepair2str(char * out,int outlen,VALUE_PAIR * pair,
 
        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);
 }
@@ -151,7 +145,7 @@ static int xlat_packet(void *instance, REQUEST *request,
                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;
@@ -175,7 +169,7 @@ static int xlat_packet(void *instance, REQUEST *request,
                /*
                 *      %{Attribute-Name[*]} returns ALL of the
                 *      the attributes, separated by a newline.
-                */             
+                */
                if ((p[1] == '*') && (p[2] == ']')) {
                        int total = 0;
 
@@ -187,7 +181,7 @@ static int xlat_packet(void *instance, REQUEST *request,
                                total += count + 1;
                                outlen -= (count + 1);
                                out += count;
-                               
+
                                *(out++) = '\n';
 
                                if (outlen == 0) break;
@@ -195,7 +189,7 @@ static int xlat_packet(void *instance, REQUEST *request,
 
                        return total;
                }
-               
+
                count = atoi(p + 1);
 
                /*
@@ -238,13 +232,13 @@ static int xlat_packet(void *instance, REQUEST *request,
                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);
@@ -261,30 +255,30 @@ static int xlat_packet(void *instance, REQUEST *request,
                                        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;
@@ -294,39 +288,39 @@ static int xlat_packet(void *instance, REQUEST *request,
                                 */
                        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;
@@ -367,8 +361,8 @@ static int xlat_regex(void *instance, REQUEST *request,
         */
        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;
 
@@ -376,12 +370,12 @@ static int xlat_regex(void *instance, REQUEST *request,
         *      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.
  */
@@ -407,7 +401,8 @@ static const xlat_t *xlat_find(const char *module)
        /*
         *      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,
@@ -419,7 +414,7 @@ static const xlat_t *xlat_find(const char *module)
                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);
@@ -485,7 +480,7 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance)
        /*
         *      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) {
@@ -506,7 +501,7 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance)
        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;
 
@@ -528,7 +523,9 @@ void xlat_unregister(const char *module, RAD_XLAT_FUNC func)
 
        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);
@@ -551,7 +548,7 @@ void xlat_free(void)
  *     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;
@@ -561,8 +558,9 @@ static void decode_attribute(const char **from, char **to, int freespace,
        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;
@@ -609,7 +607,7 @@ static void decode_attribute(const char **from, char **to, int freespace,
                 */
        } else if (*p == '}') {
                openbraces--;
-               rad_assert(openbraces == *open);
+               rad_assert(openbraces == *open_p);
 
                p++;
                xlat_string = xlat_name;
@@ -619,10 +617,10 @@ static void decode_attribute(const char **from, char **to, int freespace,
                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 ':' */
@@ -637,17 +635,18 @@ static void decode_attribute(const char **from, char **to, int freespace,
                        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?
@@ -657,6 +656,13 @@ static void decode_attribute(const char **from, char **to, int freespace,
                                *pa++ = *p++;
                                break;
 
+                       case ':':
+                               if (!spaces && p[1] == '-') {
+                                       p += 2;
+                                       stop = 1;
+                                       break;
+                               }
+
                                /*
                                 *      This is pretty hokey...  we
                                 *      should use the functions in
@@ -676,7 +682,12 @@ static void decode_attribute(const char **from, char **to, int freespace,
                                        *pa++ = *p++;
                                }
                                break;
-                               
+
+                       case ' ':
+                       case '\t':
+                               spaces = TRUE;
+                               /* FALL-THROUGH */
+
                        default:
                                *pa++ = *p++;
                                break;
@@ -694,7 +705,7 @@ static void decode_attribute(const char **from, char **to, int freespace,
                                p += 2;
                        }
                }
-               
+
                /*
                 *      Look up almost everything in the new tree of xlat
                 *      functions.  This makes it a little quicker...
@@ -730,7 +741,7 @@ static void decode_attribute(const char **from, char **to, int freespace,
 
                q += retlen;
 
-               while((*p != '\0') && (openbraces > 0)) {
+               while((*p != '\0') && (openbraces > *open_p)) {
                        /*
                         *      Handle escapes outside of the loop.
                         */
@@ -759,11 +770,11 @@ static void decode_attribute(const char **from, char **to, int freespace,
                        p++;    /* skip the character */
                }
        }
-       
+
        done:
        if (free_xlat_string) free(xlat_string);
 
-       *open = openbraces;
+       *open_p = openbraces;
        *from = p;
        *to = q;
 }
@@ -775,30 +786,23 @@ static void decode_attribute(const char **from, char **to, int freespace,
  */
 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 */
 }
 
 /*
@@ -809,9 +813,10 @@ static int xlat_copy(char *out, int outlen, const char *in)
 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 */
@@ -914,9 +919,11 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                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 */
@@ -929,16 +936,18 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                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 */
@@ -954,13 +963,11 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                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 */
@@ -968,31 +975,35 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                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;
@@ -1001,22 +1012,26 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                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 */
@@ -1024,28 +1039,27 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                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;