Move server-specific code to tls_listen.c
[freeradius.git] / src / modules / rlm_eap / radeapclient.c
index d021714..0806f89 100644 (file)
@@ -51,10 +51,13 @@ static int filedone = 0;
 static int totalapp = 0;
 static int totaldeny = 0;
 static char filesecret[256];
-const char *radius_dir = RADDBDIR;
+char *radius_dir = NULL;
 const char *progname = "radeapclient";
 /* fr_randctx randctx; */
 
+#ifdef WITH_TLS
+#include <freeradius-devel/tls.h>
+#endif
 
 radlog_dest_t radlog_dest = RADLOG_STDERR;
 const char *radlog_dir = NULL;
@@ -83,6 +86,7 @@ static void NEVER_RETURNS usage(void)
        fprintf(stderr, "  -f file     Read packets from file, not stdin.\n");
        fprintf(stderr, "  -r retries  If timeout, retry sending the packet 'retries' times.\n");
        fprintf(stderr, "  -t timeout  Wait 'timeout' seconds before retrying (may be a floating point number).\n");
+       fprintf(stderr, "  -h          Print usage help information.\n");
        fprintf(stderr, "  -i id       Set request id to 'id'.  Values may be 0..255\n");
        fprintf(stderr, "  -S file     read secret from file, not command line.\n");
        fprintf(stderr, "  -q          Do not print anything out.\n");
@@ -144,6 +148,58 @@ static int getport(const char *name)
        return ntohs(svp->s_port);
 }
 
+#define R_RECV (0)
+#define R_SENT (1)
+static void debug_packet(RADIUS_PACKET *packet, int direction)
+{
+       VALUE_PAIR *vp;
+       char buffer[1024];
+       const char *received, *from;
+       const fr_ipaddr_t *ip;
+       int port;
+
+       if (!packet) return;
+
+       if (direction == 0) {
+               received = "Received";
+               from = "from";  /* what else? */
+               ip = &packet->src_ipaddr;
+               port = packet->src_port;
+
+       } else {
+               received = "Sending";
+               from = "to";    /* hah! */
+               ip = &packet->dst_ipaddr;
+               port = packet->dst_port;
+       }
+       
+       /*
+        *      Client-specific debugging re-prints the input
+        *      packet into the client log.
+        *
+        *      This really belongs in a utility library
+        */
+       if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
+               printf("%s %s packet %s host %s port %d, id=%d, length=%d\n",
+                      received, fr_packet_codes[packet->code], from,
+                      inet_ntop(ip->af, &ip->ipaddr, buffer, sizeof(buffer)),
+                      port, packet->id, (int) packet->data_len);
+       } else {
+               printf("%s packet %s host %s port %d code=%d, id=%d, length=%d\n",
+                      received, from,
+                      inet_ntop(ip->af, &ip->ipaddr, buffer, sizeof(buffer)),
+                      port,
+                      packet->code, packet->id, (int) packet->data_len);
+       }
+
+       for (vp = packet->vps; vp != NULL; vp = vp->next) {
+               vp_prints(buffer, sizeof(buffer), vp);
+               printf("\t%s\n", buffer);
+       }
+       fflush(stdout);
+}
+
+
 static int send_packet(RADIUS_PACKET *req, RADIUS_PACKET **rep)
 {
        int i;
@@ -152,6 +208,8 @@ static int send_packet(RADIUS_PACKET *req, RADIUS_PACKET **rep)
        for (i = 0; i < retries; i++) {
                fd_set          rdfdesc;
 
+               debug_packet(req, R_SENT);
+
                rad_send(req, NULL, secret);
 
                /* And wait for reply, timing out as necessary */
@@ -220,13 +278,11 @@ static int send_packet(RADIUS_PACKET *req, RADIUS_PACKET **rep)
 
        /* libradius debug already prints out the value pairs for us */
        if (!fr_debug_flag && do_output) {
-               printf("Received response ID %d, code %d, length = %d\n",
-                               (*rep)->id, (*rep)->code, (*rep)->data_len);
-               vp_printlist(stdout, (*rep)->vps);
+               debug_packet(*rep, R_RECV);
        }
        if((*rep)->code == PW_AUTHENTICATION_ACK) {
                totalapp++;
-       } else {
+       } else if ((*rep)->code == PW_AUTHENTICATION_REJECT) {
                totaldeny++;
        }
 
@@ -242,8 +298,8 @@ static void cleanresp(RADIUS_PACKET *resp)
         * maybe should just copy things we care about, or keep
         * a copy of the original input and start from there again?
         */
-       pairdelete(&resp->vps, PW_EAP_MESSAGE);
-       pairdelete(&resp->vps, ATTRIBUTE_EAP_BASE+PW_EAP_IDENTITY);
+       pairdelete(&resp->vps, PW_EAP_MESSAGE, 0);
+       pairdelete(&resp->vps, ATTRIBUTE_EAP_BASE+PW_EAP_IDENTITY, 0);
 
        last = &resp->vps;
        for(vp = *last; vp != NULL; vp = vpnext)
@@ -279,7 +335,7 @@ static int process_eap_start(RADIUS_PACKET *req,
        /* form new response clear of any EAP stuff */
        cleanresp(rep);
 
-       if((vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_VERSION_LIST)) == NULL) {
+       if((vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_VERSION_LIST, 0)) == NULL) {
                fprintf(stderr, "illegal start message has no VERSION_LIST\n");
                return 0;
        }
@@ -289,7 +345,7 @@ static int process_eap_start(RADIUS_PACKET *req,
        /* verify that the attribute length is big enough for a length field */
        if(vp->length < 4)
        {
-               fprintf(stderr, "start message has illegal VERSION_LIST. Too short: %d\n", vp->length);
+               fprintf(stderr, "start message has illegal VERSION_LIST. Too short: %u\n", (unsigned int) vp->length);
                return 0;
        }
 
@@ -299,7 +355,7 @@ static int process_eap_start(RADIUS_PACKET *req,
         */
        if((unsigned)vp->length <= (versioncount*2 + 2))
        {
-               fprintf(stderr, "start message is too short. Claimed %d versions does not fit in %d bytes\n", versioncount, vp->length);
+               fprintf(stderr, "start message is too short. Claimed %d versions does not fit in %u bytes\n", versioncount, (unsigned int) vp->length);
                return 0;
        }
 
@@ -338,9 +394,9 @@ static int process_eap_start(RADIUS_PACKET *req,
         * anyway we like, but it is illegal to have more than one
         * present.
         */
-       anyidreq_vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_ANY_ID_REQ);
-       fullauthidreq_vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_FULLAUTH_ID_REQ);
-       permanentidreq_vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_PERMANENT_ID_REQ);
+       anyidreq_vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_ANY_ID_REQ, 0);
+       fullauthidreq_vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_FULLAUTH_ID_REQ, 0);
+       permanentidreq_vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_PERMANENT_ID_REQ, 0);
 
        if(fullauthidreq_vp == NULL ||
           anyidreq_vp != NULL ||
@@ -355,13 +411,13 @@ static int process_eap_start(RADIUS_PACKET *req,
        /* okay, we have just any_id_req there, so fill in response */
 
        /* mark the subtype as being EAP-SIM/Response/Start */
-       newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);
+       newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, 0, PW_TYPE_INTEGER);
        newvp->vp_integer = eapsim_start;
        pairreplace(&(rep->vps), newvp);
 
        /* insert selected version into response. */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_SELECTED_VERSION,
-                          PW_TYPE_OCTETS);
+                          0, PW_TYPE_OCTETS);
        versions = (uint16_t *)newvp->vp_strvalue;
        versions[0] = htons(selectedversion);
        newvp->length = 2;
@@ -378,7 +434,7 @@ static int process_eap_start(RADIUS_PACKET *req,
                 * insert a nonce_mt that we make up.
                 */
                newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_NONCE_MT,
-                                  PW_TYPE_OCTETS);
+                                  0, PW_TYPE_OCTETS);
                newvp->vp_octets[0]=0;
                newvp->vp_octets[1]=0;
                newvp->length = 18;  /* 16 bytes of nonce + padding */
@@ -400,14 +456,14 @@ static int process_eap_start(RADIUS_PACKET *req,
                /*
                 * insert the identity here.
                 */
-               vp = pairfind(rep->vps, PW_USER_NAME);
+               vp = pairfind(rep->vps, PW_USER_NAME, 0);
                if(vp == NULL)
                {
                        fprintf(stderr, "eap-sim: We need to have a User-Name attribute!\n");
                        return 0;
                }
                newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_IDENTITY,
-                                  PW_TYPE_OCTETS);
+                                  0, PW_TYPE_OCTETS);
                idlen = strlen(vp->vp_strvalue);
                pidlen = (uint16_t *)newvp->vp_strvalue;
                *pidlen = htons(idlen);
@@ -444,8 +500,8 @@ static int process_eap_challenge(RADIUS_PACKET *req,
        uint8_t calcmac[20];
 
        /* look for the AT_MAC and the challenge data */
-       mac   = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC);
-       randvp= pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_RAND);
+       mac   = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC, 0);
+       randvp= pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_RAND, 0);
        if(mac == NULL || randvp == NULL) {
                fprintf(stderr, "radeapclient: challenge message needs to contain RAND and MAC\n");
                return 0;
@@ -463,9 +519,9 @@ static int process_eap_challenge(RADIUS_PACKET *req,
          randcfg[1] = &randvp->vp_octets[2+EAPSIM_RAND_SIZE];
          randcfg[2] = &randvp->vp_octets[2+EAPSIM_RAND_SIZE*2];
 
-         randcfgvp[0] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND1);
-         randcfgvp[1] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND2);
-         randcfgvp[2] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND3);
+         randcfgvp[0] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND1, 0);
+         randcfgvp[1] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND2, 0);
+         randcfgvp[2] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND3, 0);
 
          if(randcfgvp[0] == NULL ||
             randcfgvp[1] == NULL ||
@@ -516,9 +572,9 @@ static int process_eap_challenge(RADIUS_PACKET *req,
         * Really, they should be calculated from the RAND!
         *
         */
-       sres1 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_SRES1);
-       sres2 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_SRES2);
-       sres3 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_SRES3);
+       sres1 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_SRES1, 0);
+       sres2 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_SRES2, 0);
+       sres3 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_SRES3, 0);
 
        if(sres1 == NULL ||
           sres2 == NULL ||
@@ -530,9 +586,9 @@ static int process_eap_challenge(RADIUS_PACKET *req,
        memcpy(eapsim_mk.sres[1], sres2->vp_strvalue, sizeof(eapsim_mk.sres[1]));
        memcpy(eapsim_mk.sres[2], sres3->vp_strvalue, sizeof(eapsim_mk.sres[2]));
 
-       Kc1 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC1);
-       Kc2 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC2);
-       Kc3 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC3);
+       Kc1 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC1, 0);
+       Kc2 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC2, 0);
+       Kc3 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC3, 0);
 
        if(Kc1 == NULL ||
           Kc2 == NULL ||
@@ -577,7 +633,7 @@ static int process_eap_challenge(RADIUS_PACKET *req,
        cleanresp(rep);
 
        /* mark the subtype as being EAP-SIM/Response/Start */
-       newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);
+       newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, 0, PW_TYPE_INTEGER);
        newvp->vp_integer = eapsim_challenge;
        pairreplace(&(rep->vps), newvp);
 
@@ -585,7 +641,7 @@ static int process_eap_challenge(RADIUS_PACKET *req,
         * fill the SIM_MAC with a field that will in fact get appended
         * to the packet before the MAC is calculated
         */
-       newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC,
+       newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC, 0,
                           PW_TYPE_OCTETS);
        memcpy(newvp->vp_strvalue+EAPSIM_SRES_SIZE*0, sres1->vp_strvalue, EAPSIM_SRES_SIZE);
        memcpy(newvp->vp_strvalue+EAPSIM_SRES_SIZE*1, sres2->vp_strvalue, EAPSIM_SRES_SIZE);
@@ -593,7 +649,7 @@ static int process_eap_challenge(RADIUS_PACKET *req,
        newvp->length = EAPSIM_SRES_SIZE*3;
        pairreplace(&(rep->vps), newvp);
 
-       newvp = paircreate(ATTRIBUTE_EAP_SIM_KEY, PW_TYPE_OCTETS);
+       newvp = paircreate(ATTRIBUTE_EAP_SIM_KEY, 0, PW_TYPE_OCTETS);
        memcpy(newvp->vp_strvalue,    eapsim_mk.K_aut, EAPSIM_AUTH_SIZE);
        newvp->length = EAPSIM_AUTH_SIZE;
        pairreplace(&(rep->vps), newvp);
@@ -615,12 +671,12 @@ static int respond_eap_sim(RADIUS_PACKET *req,
        VALUE_PAIR *vp, *statevp, *radstate, *eapid;
        char statenamebuf[32], subtypenamebuf[32];
 
-       if ((radstate = paircopy2(req->vps, PW_STATE)) == NULL)
+       if ((radstate = paircopy2(req->vps, PW_STATE, 0)) == NULL)
        {
                return 0;
        }
 
-       if ((eapid = paircopy2(req->vps, ATTRIBUTE_EAP_ID)) == NULL)
+       if ((eapid = paircopy2(req->vps, ATTRIBUTE_EAP_ID, 0)) == NULL)
        {
                return 0;
        }
@@ -629,10 +685,10 @@ static int respond_eap_sim(RADIUS_PACKET *req,
         * outselves to be in EAP-SIM-Start state if there is none.
         */
 
-       if((statevp = pairfind(resp->vps, ATTRIBUTE_EAP_SIM_STATE)) == NULL)
+       if((statevp = pairfind(resp->vps, ATTRIBUTE_EAP_SIM_STATE, 0)) == NULL)
        {
                /* must be initial request */
-               statevp = paircreate(ATTRIBUTE_EAP_SIM_STATE, PW_TYPE_INTEGER);
+               statevp = paircreate(ATTRIBUTE_EAP_SIM_STATE, 0, PW_TYPE_INTEGER);
                statevp->vp_integer = eapsim_client_init;
                pairreplace(&(resp->vps), statevp);
        }
@@ -643,10 +699,7 @@ static int respond_eap_sim(RADIUS_PACKET *req,
         */
        unmap_eapsim_types(req);
 
-       printf("<+++ EAP-sim decoded packet:\n");
-       vp_printlist(stdout, req->vps);
-
-       if((vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_SUBTYPE)) == NULL)
+       if((vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_SUBTYPE, 0)) == NULL)
        {
                return 0;
        }
@@ -727,20 +780,20 @@ static int respond_eap_md5(RADIUS_PACKET *req,
 
        cleanresp(rep);
 
-       if ((state = paircopy2(req->vps, PW_STATE)) == NULL)
+       if ((state = paircopy2(req->vps, PW_STATE, 0)) == NULL)
        {
                fprintf(stderr, "radeapclient: no state attribute found\n");
                return 0;
        }
 
-       if ((id = paircopy2(req->vps, ATTRIBUTE_EAP_ID)) == NULL)
+       if ((id = paircopy2(req->vps, ATTRIBUTE_EAP_ID, 0)) == NULL)
        {
                fprintf(stderr, "radeapclient: no EAP-ID attribute found\n");
                return 0;
        }
        identifier = id->vp_integer;
 
-       if ((vp = pairfind(req->vps, ATTRIBUTE_EAP_BASE+PW_EAP_MD5)) == NULL)
+       if ((vp = pairfind(req->vps, ATTRIBUTE_EAP_BASE+PW_EAP_MD5, 0)) == NULL)
        {
                fprintf(stderr, "radeapclient: no EAP-MD5 attribute found\n");
                return 0;
@@ -755,8 +808,8 @@ static int respond_eap_md5(RADIUS_PACKET *req,
        /* sanitize items */
        if(valuesize > vp->length)
        {
-               fprintf(stderr, "radeapclient: md5 valuesize if too big (%d > %d)\n",
-                       valuesize, vp->length);
+               fprintf(stderr, "radeapclient: md5 valuesize if too big (%u > %u)\n",
+                       (unsigned int) valuesize, (unsigned int) vp->length);
                return 0;
        }
 
@@ -770,7 +823,7 @@ static int respond_eap_md5(RADIUS_PACKET *req,
        fr_MD5Update(&context, value, valuesize);
        fr_MD5Final(response, &context);
 
-       vp = paircreate(ATTRIBUTE_EAP_BASE+PW_EAP_MD5, PW_TYPE_OCTETS);
+       vp = paircreate(ATTRIBUTE_EAP_BASE+PW_EAP_MD5, 0, PW_TYPE_OCTETS);
        vp->vp_octets[0]=16;
        memcpy(&vp->vp_strvalue[1], response, 16);
        vp->length = 17;
@@ -796,15 +849,15 @@ static int sendrecv_eap(RADIUS_PACKET *rep)
        /*
         *      Keep a copy of the the User-Password attribute.
         */
-       if ((vp = pairfind(rep->vps, PW_CLEARTEXT_PASSWORD)) != NULL) {
+       if ((vp = pairfind(rep->vps, PW_CLEARTEXT_PASSWORD, 0)) != NULL) {
                strlcpy(password, (char *)vp->vp_strvalue, sizeof(vp->vp_strvalue));
 
-       } else  if ((vp = pairfind(rep->vps, PW_USER_PASSWORD)) != NULL) {
+       } else  if ((vp = pairfind(rep->vps, PW_USER_PASSWORD, 0)) != NULL) {
                strlcpy(password, (char *)vp->vp_strvalue, sizeof(vp->vp_strvalue));
                /*
                 *      Otherwise keep a copy of the CHAP-Password attribute.
                 */
-       } else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD)) != NULL) {
+       } else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD, 0)) != NULL) {
                strlcpy(password, (char *)vp->vp_strvalue, sizeof(vp->vp_strvalue));
        } else {
                *password = '\0';
@@ -813,9 +866,6 @@ static int sendrecv_eap(RADIUS_PACKET *rep)
  again:
        rep->id++;
 
-       printf("\n+++> About to send encoded packet:\n");
-       vp_printlist(stdout, rep->vps);
-
        /*
         * if there are EAP types, encode them into an EAP-Message
         *
@@ -864,15 +914,15 @@ static int sendrecv_eap(RADIUS_PACKET *rep)
                        sizeof(rep->vector));
 
        if (*password != '\0') {
-               if ((vp = pairfind(rep->vps, PW_CLEARTEXT_PASSWORD)) != NULL) {
+               if ((vp = pairfind(rep->vps, PW_CLEARTEXT_PASSWORD, 0)) != NULL) {
                        strlcpy((char *)vp->vp_strvalue, password, sizeof(vp->vp_strvalue));
                        vp->length = strlen(password);
 
-               } else if ((vp = pairfind(rep->vps, PW_USER_PASSWORD)) != NULL) {
+               } else if ((vp = pairfind(rep->vps, PW_USER_PASSWORD, 0)) != NULL) {
                        strlcpy((char *)vp->vp_strvalue, password, sizeof(vp->vp_strvalue));
                        vp->length = strlen(password);
 
-               } else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD)) != NULL) {
+               } else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD, 0)) != NULL) {
                        strlcpy((char *)vp->vp_strvalue, password, sizeof(vp->vp_strvalue));
                        vp->length = strlen(password);
 
@@ -887,8 +937,7 @@ static int sendrecv_eap(RADIUS_PACKET *rep)
        /* okay got back the packet, go and decode the EAP-Message. */
        unmap_eap_types(req);
 
-       printf("<+++ EAP decoded packet:\n");
-       vp_printlist(stdout, req->vps);
+       debug_packet(req, R_RECV);
 
        /* now look for the code type. */
        for (vp = req->vps; vp != NULL; vp = vpnext) {
@@ -944,7 +993,7 @@ int main(int argc, char **argv)
                        count = atoi(optarg);
                        break;
                case 'd':
-                       radius_dir = optarg;
+                       radius_dir = strdup(optarg);
                        break;
                case 'f':
                        filename = optarg;
@@ -1032,6 +1081,8 @@ int main(int argc, char **argv)
                usage();
        }
 
+       if (!radius_dir) radius_dir = strdup(RADDBDIR);
+
        if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {
                fr_perror("radclient");
                return 1;
@@ -1147,6 +1198,7 @@ int main(int argc, char **argv)
                sendrecv_eap(req);
        }
 
+       free(radius_dir);
        if(do_summary) {
                printf("\n\t   Total approved auths:  %d\n", totalapp);
                printf("\t     Total denied auths:  %d\n", totaldeny);
@@ -1173,14 +1225,14 @@ static void map_eap_types(RADIUS_PACKET *req)
        EAP_PACKET ep;
        int eap_type;
 
-       vp = pairfind(req->vps, ATTRIBUTE_EAP_ID);
+       vp = pairfind(req->vps, ATTRIBUTE_EAP_ID, 0);
        if(vp == NULL) {
                id = ((int)getpid() & 0xff);
        } else {
                id = vp->vp_integer;
        }
 
-       vp = pairfind(req->vps, ATTRIBUTE_EAP_CODE);
+       vp = pairfind(req->vps, ATTRIBUTE_EAP_CODE, 0);
        if(vp == NULL) {
                eapcode = PW_EAP_REQUEST;
        } else {
@@ -1222,7 +1274,7 @@ static void map_eap_types(RADIUS_PACKET *req)
                 */
 
                /* nuke any existing EAP-Messages */
-               pairdelete(&req->vps, PW_EAP_MESSAGE);
+               pairdelete(&req->vps, PW_EAP_MESSAGE, 0);
 
                memset(&ep, 0, sizeof(ep));
                ep.code = eapcode;
@@ -1253,11 +1305,11 @@ static void unmap_eap_types(RADIUS_PACKET *rep)
        if(e == NULL) return;
 
        /* create EAP-ID and EAP-CODE attributes to start */
-       eap1 = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);
+       eap1 = paircreate(ATTRIBUTE_EAP_ID, 0, PW_TYPE_INTEGER);
        eap1->vp_integer = e->id;
        pairadd(&(rep->vps), eap1);
 
-       eap1 = paircreate(ATTRIBUTE_EAP_CODE, PW_TYPE_INTEGER);
+       eap1 = paircreate(ATTRIBUTE_EAP_CODE, 0, PW_TYPE_INTEGER);
        eap1->vp_integer = e->code;
        pairadd(&(rep->vps), eap1);
 
@@ -1283,6 +1335,7 @@ static void unmap_eap_types(RADIUS_PACKET *rep)
                /* verify the length is big enough to hold type */
                if(len < 5)
                {
+                       free(e);
                        return;
                }
 
@@ -1295,13 +1348,14 @@ static void unmap_eap_types(RADIUS_PACKET *rep)
                        len = MAX_STRING_LEN;
                }
 
-               eap1 = paircreate(type, PW_TYPE_OCTETS);
+               eap1 = paircreate(type, 0, PW_TYPE_OCTETS);
                memcpy(eap1->vp_strvalue, &e->data[1], len);
                eap1->length = len;
                pairadd(&(rep->vps), eap1);
                break;
        }
 
+       free(e);
        return;
 }
 
@@ -1324,7 +1378,7 @@ static int unmap_eapsim_types(RADIUS_PACKET *r)
 {
        VALUE_PAIR             *esvp;
 
-       esvp = pairfind(r->vps, ATTRIBUTE_EAP_BASE+PW_EAP_SIM);
+       esvp = pairfind(r->vps, ATTRIBUTE_EAP_BASE+PW_EAP_SIM, 0);
        if (esvp == NULL) {
                radlog(L_ERR, "eap: EAP-Sim attribute not found");
                return 0;
@@ -1390,13 +1444,18 @@ main(int argc, char *argv[])
                        break;
                }
 
-               printf("\nRead:\n");
-               vp_printlist(stdout, req->vps);
+               if (fr_debug_flag > 1) {
+                       printf("\nRead:\n");
+                       vp_printlist(stdout, req->vps);
+               }
 
                map_eapsim_types(req);
                map_eap_types(req);
-               printf("Mapped to:\n");
-               vp_printlist(stdout, req->vps);
+
+               if (fr_debug_flag > 1) {
+                       printf("Mapped to:\n");
+                       vp_printlist(stdout, req->vps);
+               }
 
                /* find the EAP-Message, copy it to req2 */
                vp = paircopy2(req->vps, PW_EAP_MESSAGE);
@@ -1409,13 +1468,15 @@ main(int argc, char *argv[])
                unmap_eap_types(req2);
                unmap_eapsim_types(req2);
 
-               printf("Unmapped to:\n");
-               vp_printlist(stdout, req2->vps);
+               if (fr_debug_flag > 1) {
+                       printf("Unmapped to:\n");
+                       vp_printlist(stdout, req2->vps);
+               }
 
                vp = pairfind(req2->vps,
-                             ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC);
-               vpkey   = pairfind(req->vps, ATTRIBUTE_EAP_SIM_KEY);
-               vpextra = pairfind(req->vps, ATTRIBUTE_EAP_SIM_EXTRA);
+                             ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC, 0);
+               vpkey   = pairfind(req->vps, ATTRIBUTE_EAP_SIM_KEY, 0);
+               vpextra = pairfind(req->vps, ATTRIBUTE_EAP_SIM_EXTRA, 0);
 
                if(vp != NULL && vpkey != NULL && vpextra!=NULL) {
                        uint8_t calcmac[16];