and added files
[bcm963xx.git] / userapps / opensource / ipsec-tools / src / racoon / isakmp_xauth.c
1 /* $Id: isakmp_xauth.c,v 1.14 2004/11/30 00:46:09 manubsd Exp $ */
2
3 /*
4  * Copyright (C) 2004 Emmanuel Dreyfus
5  * All rights reserved.
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include "config.h"
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37 #include <sys/queue.h>
38
39 #include <netinet/in.h>
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <errno.h>
45 #include <pwd.h>
46 #if TIME_WITH_SYS_TIME
47 # include <sys/time.h>
48 # include <time.h>
49 #else
50 # if HAVE_SYS_TIME_H
51 #  include <sys/time.h>
52 # else
53 #  include <time.h>
54 # endif
55 #endif
56 #include <netdb.h>
57 #ifdef HAVE_UNISTD_H
58 #include <unistd.h>
59 #endif
60 #include <ctype.h>
61
62 #include "var.h"
63 #include "misc.h"
64 #include "vmbuf.h"
65 #include "plog.h"
66 #include "sockmisc.h"
67 #include "schedule.h"
68 #include "debug.h"
69
70 #include "crypto_openssl.h"
71 #include "isakmp_var.h"
72 #include "isakmp.h"
73 #include "evt.h"
74 #include "handler.h"
75 #include "throttle.h"
76 #include "remoteconf.h"
77 #include "isakmp_inf.h"
78 #include "isakmp_xauth.h"
79 #include "isakmp_unity.h"
80 #include "isakmp_cfg.h"
81 #include "strnames.h"
82 #include "ipsec_doi.h"
83 #include "remoteconf.h"
84 #include "localconf.h"
85
86 #ifdef HAVE_LIBRADIUS
87 #include <radlib.h>
88 #endif
89
90 void 
91 xauth_sendreq(iph1)
92         struct ph1handle *iph1;
93 {
94         vchar_t *buffer;
95         struct isakmp_pl_attr *attr;
96         struct isakmp_data *typeattr;
97         struct isakmp_data *usrattr;
98         struct isakmp_data *pwdattr;
99         struct xauth_state *xst = &iph1->mode_cfg->xauth;
100         size_t tlen;
101
102         /* Status checks */
103         if (iph1->status != PHASE1ST_ESTABLISHED) {
104                 plog(LLV_ERROR, LOCATION, NULL, 
105                     "Xauth request while phase 1 is not completed\n");
106                 return;
107         }
108
109         if (xst->status != XAUTHST_NOTYET) {
110                 plog(LLV_ERROR, LOCATION, NULL, 
111                     "Xauth request whith Xauth state %d\n", xst->status);
112                 return;
113         }
114
115         plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n");
116
117         tlen = sizeof(*attr) +
118                + sizeof(*typeattr) +
119                + sizeof(*usrattr) +
120                + sizeof(*pwdattr);
121         
122         if ((buffer = vmalloc(tlen)) == NULL) {
123                 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
124                 return;
125         }
126         
127         attr = (struct isakmp_pl_attr *)buffer->v;
128         memset(attr, 0, tlen);
129
130         attr->h.len = htons(tlen);
131         attr->type = ISAKMP_CFG_REQUEST;
132         attr->id = htons(eay_random());
133
134         typeattr = (struct isakmp_data *)(attr + 1);
135         typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV);
136         typeattr->lorv = htons(XAUTH_TYPE_GENERIC);
137
138         usrattr = (struct isakmp_data *)(typeattr + 1);
139         usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV);
140         usrattr->lorv = htons(0);
141
142         pwdattr = (struct isakmp_data *)(usrattr + 1);
143         pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV);
144         pwdattr->lorv = htons(0);
145
146         isakmp_cfg_send(iph1, buffer, 
147             ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
148         
149         vfree(buffer);
150
151         xst->status = XAUTHST_REQSENT;
152
153         return;
154 }
155
156 void 
157 xauth_attr_reply(iph1, attr, id)
158         struct ph1handle *iph1;
159         struct isakmp_data *attr;
160         int id;
161 {
162         char **outlet = NULL;
163         size_t alen = 0;
164         int type;
165         struct xauth_state *xst = &iph1->mode_cfg->xauth;
166
167         if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
168                 plog(LLV_ERROR, LOCATION, NULL, 
169                     "Xauth reply but peer did not declare "
170                     "itself as Xauth capable\n");
171                 return;
172         }
173
174         if (xst->status != XAUTHST_REQSENT) {
175                 plog(LLV_ERROR, LOCATION, NULL, 
176                     "Xauth reply while Xauth state is %d\n", xst->status);
177                 return;
178         }
179
180         type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
181         switch (type) {
182         case XAUTH_TYPE:
183                 switch (ntohs(attr->lorv)) {
184                 case XAUTH_TYPE_GENERIC:
185                         xst->authtype = XAUTH_TYPE_GENERIC;
186                         break;
187                 default:
188                         plog(LLV_WARNING, LOCATION, NULL, 
189                             "Unexpected authentication type %d\n", 
190                             ntohs(type));
191                         return;
192                 }
193                 break;
194
195         case XAUTH_USER_NAME:
196                 outlet = &xst->authdata.generic.usr;
197                 break;
198
199         case XAUTH_USER_PASSWORD:
200                 outlet = &xst->authdata.generic.pwd; 
201                 break;
202
203         default:
204                 plog(LLV_WARNING, LOCATION, NULL, 
205                     "ignored Xauth attribute %d\n", type);
206                 break;
207         }
208
209         if (outlet != NULL) {
210                 alen = ntohs(attr->lorv);
211
212                 if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
213                         plog(LLV_ERROR, LOCATION, NULL, 
214                             "Cannot allocate memory for Xauth Data\n");
215                         return;
216                 }
217
218                 memcpy(*outlet, attr + 1, alen);
219                 (*outlet)[alen] = '\0';
220                 outlet = NULL;
221         }
222
223         
224         if ((xst->authdata.generic.usr != NULL) &&
225            (xst->authdata.generic.pwd != NULL)) {
226                 int port;
227                 int res;
228                 char *usr = xst->authdata.generic.usr;
229                 char *pwd = xst->authdata.generic.pwd;
230                 time_t throttle_delay = 0;
231
232 #if 0   /* Real debug, don't do that at home */
233                 plog(LLV_DEBUG, LOCATION, NULL, 
234                     "Got username \"%s\", password \"%s\"\n", usr, pwd);
235 #endif
236                 strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
237                 iph1->mode_cfg->login[LOGINLEN] = '\0';
238
239                 res = -1;
240                 if ((port = isakmp_cfg_getport(iph1)) == -1) {
241                         plog(LLV_ERROR, LOCATION, NULL, 
242                             "Port pool depleted\n");
243                         goto skip_auth;
244                 }       
245
246                 switch (isakmp_cfg_config.authsource) {
247                 case ISAKMP_CFG_AUTH_SYSTEM:
248                         res = xauth_login_system(iph1, usr, pwd);
249                         break;
250 #ifdef HAVE_LIBRADIUS
251                 case ISAKMP_CFG_AUTH_RADIUS:
252                         res = xauth_login_radius(iph1, usr, pwd);
253                         break;
254 #endif
255                 default:
256                         plog(LLV_ERROR, LOCATION, NULL, 
257                             "Unexpected authentication source\n");
258                         res = -1;
259                         break;
260                 }
261
262                 /*
263                  * On failure, throttle the connexion for the remote host
264                  * in order to make password attacks more difficult.
265                  */
266                 throttle_delay = throttle_host(iph1->remote, res) - time(NULL);
267                 if (throttle_delay > 0) {
268                         char *str;
269
270                         str = saddrwop2str(iph1->remote);
271
272                         plog(LLV_ERROR, LOCATION, NULL, 
273                             "Throttling in action for %s: delay %lds\n",
274                             str, (unsigned long)throttle_delay);
275                         res = -1;
276                 } else {
277                         throttle_delay = 0;
278                 }
279
280 skip_auth:
281                 if (throttle_delay != 0) {
282                         struct xauth_reply_arg *xra;
283
284                         if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
285                                 plog(LLV_ERROR, LOCATION, NULL, 
286                                     "malloc failed, bypass throttling\n");
287                                 xauth_reply(iph1, port, id, res);
288                                 return;
289                         }
290
291                         /*
292                          * We need to store the ph1, but it might have
293                          * disapeared when xauth_reply is called, so
294                          * store the index instead.
295                          */
296                         xra->index = iph1->index;
297                         xra->port = port;
298                         xra->id = id;
299                         xra->res = res;
300                         sched_new(throttle_delay, xauth_reply_stub, xra);
301                 } else {
302                         xauth_reply(iph1, port, id, res);
303                 }
304         }
305
306         return;
307 }
308
309 void 
310 xauth_reply_stub(args)
311         void *args;
312 {
313         struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
314         struct ph1handle *iph1;
315
316         if ((iph1 = getph1byindex(&xra->index)) != NULL)
317                 xauth_reply(iph1, xra->port, xra->id, xra->res);
318         else
319                 plog(LLV_ERROR, LOCATION, NULL, 
320                     "Delayed Xauth reply: phase 1 no longer exists.\n"); 
321
322         racoon_free(xra);
323         return;
324 }
325
326 void 
327 xauth_reply(iph1, port, id, res)
328         struct ph1handle *iph1;
329         int port;
330         int id;
331 {
332         struct xauth_state *xst = &iph1->mode_cfg->xauth;
333         char *usr = xst->authdata.generic.usr;
334
335         if (res != 0) {
336                 if (port != -1)
337                         isakmp_cfg_putport(iph1, port);
338
339                 plog(LLV_INFO, LOCATION, NULL, 
340                     "login failed for user \"%s\"\n", usr);
341                 
342                 xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
343                 xst->status = XAUTHST_NOTYET;
344
345                 /* Delete Phase 1 SA */
346                 if (iph1->status == PHASE1ST_ESTABLISHED)
347                         isakmp_info_send_d1(iph1);
348                 remph1(iph1);
349                 delph1(iph1);
350
351                 return;
352         }
353
354         xst->status = XAUTHST_OK;
355         plog(LLV_INFO, LOCATION, NULL, 
356             "login succeeded for user \"%s\"\n", usr);
357
358         xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
359
360         return;
361 }
362
363 void
364 xauth_sendstatus(iph1, status, id)
365         struct ph1handle *iph1;
366         int status;
367         int id;
368 {
369         vchar_t *buffer;
370         struct isakmp_pl_attr *attr;
371         struct isakmp_data *stattr;
372         size_t tlen;
373
374         tlen = sizeof(*attr) +
375                + sizeof(*stattr); 
376         
377         if ((buffer = vmalloc(tlen)) == NULL) {
378                 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
379                 return;
380         }
381         
382         attr = (struct isakmp_pl_attr *)buffer->v;
383         memset(attr, 0, tlen);
384
385         attr->h.len = htons(tlen);
386         attr->type = ISAKMP_CFG_SET;
387         attr->id = htons(id);
388
389         stattr = (struct isakmp_data *)(attr + 1);
390         stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV);
391         stattr->lorv = htons(status);
392
393         isakmp_cfg_send(iph1, buffer, 
394             ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
395         
396         vfree(buffer);
397
398         return; 
399 }
400
401 #ifdef HAVE_LIBRADIUS
402 int
403 xauth_login_radius(iph1, usr, pwd)
404         struct ph1handle *iph1;
405         char *usr;
406         char *pwd;
407 {
408         static struct rad_handle *radius_state = NULL;
409         int res;
410         const void *data;
411         size_t len;
412         int type;
413
414         /* For first time use, initialize Radius */
415         if (radius_state == NULL) {
416                 if ((radius_state = rad_auth_open()) == NULL) {
417                         plog(LLV_ERROR, LOCATION, NULL, 
418                             "Cannot init librradius\n");
419                         return -1;
420                 }
421
422                 if (rad_config(radius_state, NULL) != 0) {
423                         plog(LLV_ERROR, LOCATION, NULL, 
424                             "Cannot open librarius config file: %s\n", 
425                             rad_strerror(radius_state));
426                         rad_close(radius_state);
427                         radius_state = NULL;
428                         return -1;
429                 }
430         }
431
432         if (rad_create_request(radius_state, RAD_ACCESS_REQUEST) != 0) {
433                 plog(LLV_ERROR, LOCATION, NULL, 
434                     "rad_create_request failed: %s\n", 
435                     rad_strerror(radius_state));
436                 return -1;
437         }
438         
439         if (rad_put_string(radius_state, RAD_USER_NAME, usr) != 0) {
440                 plog(LLV_ERROR, LOCATION, NULL, 
441                     "rad_put_string failed: %s\n", 
442                     rad_strerror(radius_state));
443                 return -1;
444         }
445
446         if (rad_put_string(radius_state, RAD_USER_PASSWORD, pwd) != 0) {
447                 plog(LLV_ERROR, LOCATION, NULL, 
448                     "rad_put_string failed: %s\n", 
449                     rad_strerror(radius_state));
450                 return -1;
451         }
452
453         if (isakmp_cfg_radius_common(radius_state, iph1->mode_cfg->port) != 0)
454                 return -1;
455
456         switch (res = rad_send_request(radius_state)) {
457         case RAD_ACCESS_ACCEPT:
458                 while ((type = rad_get_attr(radius_state, &data, &len)) != 0) {
459                         switch (type) {
460                         case RAD_FRAMED_IP_ADDRESS:
461                                 iph1->mode_cfg->addr4 = rad_cvt_addr(data);
462                                 iph1->mode_cfg->flags 
463                                     |= ISAKMP_CFG_ADDR4_RADIUS;
464                                 break;
465
466                         case RAD_FRAMED_IP_NETMASK:
467                                 iph1->mode_cfg->mask4 = rad_cvt_addr(data);
468                                 iph1->mode_cfg->flags 
469                                     |= ISAKMP_CFG_MASK4_RADIUS;
470                                 break;
471
472                         default:
473                                 plog(LLV_INFO, LOCATION, NULL,
474                                     "Unexpected attribute: %d\n", type);
475                                 break;
476                         }
477                 }
478
479                 return 0;
480                 break;
481
482         case RAD_ACCESS_REJECT:
483                 return -1;
484                 break;
485
486         case -1:
487                 plog(LLV_ERROR, LOCATION, NULL, 
488                     "rad_send_request failed: %s\n", 
489                     rad_strerror(radius_state));
490                 return -1;
491                 break;
492         default:
493                 plog(LLV_ERROR, LOCATION, NULL, 
494                     "rad_send_request returned %d\n", res);
495                 return -1;
496                 break;
497         }
498
499         return -1;
500 }
501 #endif
502
503 int
504 xauth_login_system(iph1, usr, pwd)
505         struct ph1handle *iph1;
506         char *usr;
507         char *pwd;
508 {
509         struct passwd *pw;
510         char *cryptpwd;
511
512         if ((pw = getpwnam(usr)) == NULL)
513                 return -1;
514
515         /* No root login. Ever. */
516         if (pw->pw_uid == 0)
517                 return -1;
518
519         if ((cryptpwd = crypt(pwd, pw->pw_passwd)) == NULL)
520                 return -1;
521
522         if (strcmp(cryptpwd, pw->pw_passwd) == 0)
523                 return 0;
524
525         return -1;
526 }
527
528 int 
529 xauth_check(iph1)
530         struct ph1handle *iph1;
531 {
532         struct xauth_state *xst = &iph1->mode_cfg->xauth;
533
534         /* If we don't use Xauth, then we pass */
535         switch (iph1->approval->authmethod) {
536         case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
537         case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
538         /* The following are not yet implemented */
539         case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
540         case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
541         case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
542         case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
543         case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
544                 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
545                         plog(LLV_ERROR, LOCATION, NULL,
546                             "Hybrid auth negotiated but peer did not "
547                             "announced as Xauth capable\n");
548                         return -1;
549                 }
550
551                 if (xst->status != XAUTHST_OK) {
552                         plog(LLV_ERROR, LOCATION, NULL,
553                             "Hybrid auth negotiated but peer did not "
554                             "succeed Xauth exchange\n");
555                         return -1;
556                 }
557
558                 return 0;
559                 break;
560         default:
561                 return 0;
562                 break;
563         }
564
565         return 0;
566 }
567
568 vchar_t *
569 isakmp_xauth_req(iph1, attr)
570         struct ph1handle *iph1;
571         struct isakmp_data *attr;
572 {
573         int type;
574         size_t dlen = 0;
575         int ashort = 0;
576         int value = 0;
577         vchar_t *buffer = NULL;
578         char *data;
579         vchar_t *usr = NULL;
580         vchar_t *pwd = NULL;
581         size_t skip = 0;
582         int freepwd = 0;
583
584         if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
585                 plog(LLV_ERROR, LOCATION, NULL, 
586                     "Xauth mode config request but peer "
587                     "did not declare itself as Xauth capable\n");
588                 return NULL;
589         }
590
591         type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
592
593         /* Sanity checks */
594         switch(type) {
595         case XAUTH_TYPE:
596                 if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
597                         plog(LLV_ERROR, LOCATION, NULL, 
598                             "Unexpected long XAUTH_TYPE attribute\n");
599                         return NULL;
600                 }
601                 if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
602                         plog(LLV_ERROR, LOCATION, NULL, 
603                             "Unsupported Xauth authentication %d\n", 
604                             ntohs(attr->lorv));
605                         return NULL;
606                 }
607                 ashort = 1;
608                 dlen = 0;
609                 value = XAUTH_TYPE_GENERIC;
610                 break;
611
612         case XAUTH_USER_NAME:
613                 if (iph1->rmconf->idvtype != IDTYPE_LOGIN) {
614                         plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
615                             "while identifier is not a login\n");
616                         return NULL;
617                 }
618
619                 if (iph1->rmconf->idv == NULL) {
620                         plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
621                             "with no login supplied\n");
622                         return NULL;
623                 }
624
625                 dlen = iph1->rmconf->idv->l;
626                 break;
627
628         case XAUTH_USER_PASSWORD:
629                 if (iph1->rmconf->idvtype != IDTYPE_LOGIN) 
630                         return NULL;
631
632                 if (iph1->rmconf->idv == NULL)
633                         return NULL;
634
635                 skip = sizeof(struct ipsecdoi_id_b);
636                 if ((usr = vmalloc(iph1->rmconf->idv->l + skip)) == NULL) {
637                         plog(LLV_ERROR, LOCATION, NULL, 
638                             "Cannot allocate memory\n");
639                         return NULL;
640                 }
641
642                 memset(usr->v, 0, skip);
643                 memcpy(usr->v + skip, 
644                     iph1->rmconf->idv->v, 
645                     iph1->rmconf->idv->l);
646
647                 if (iph1->rmconf->key) {
648                         /* A key given through racoonctl */
649                         pwd = iph1->rmconf->key;
650                 } else {
651                         if ((pwd = getpskbyname(usr)) == NULL) {
652                                 plog(LLV_ERROR, LOCATION, NULL, 
653                                     "No password was found for login %s\n", 
654                                     iph1->rmconf->idv->v);
655                                 vfree(usr);
656                                 return NULL;
657                         }
658                         /* We have to free it before returning */
659                         freepwd = 1;
660                 }
661                 vfree(usr);
662
663                 dlen = pwd->l;
664
665                 break;
666
667         default:
668                 plog(LLV_WARNING, LOCATION, NULL,
669                     "Ignored attribute %d\n", type);
670                 return NULL;
671                 break;
672         }
673
674         if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
675                 plog(LLV_ERROR, LOCATION, NULL,
676                     "Cannot allocate memory\n");
677                 goto out;
678         }
679
680         attr = (struct isakmp_data *)buffer->v;
681         if (ashort) {
682                 attr->type = htons(type | ISAKMP_GEN_TV);
683                 attr->lorv = htons(value);
684                 goto out;
685         }
686
687         attr->type = htons(type | ISAKMP_GEN_TLV);
688         attr->lorv = htons(dlen);
689         data = (char *)(attr + 1);
690
691         switch(type) {
692         case XAUTH_USER_NAME:
693                 memcpy(data, iph1->rmconf->idv->v, dlen);
694                 break;
695         case XAUTH_USER_PASSWORD:
696                 memcpy(data, pwd->v, dlen);
697                 break;
698         default:
699                 break;
700         }
701
702 out:
703         if (freepwd)
704                 vfree(pwd);
705
706         return buffer;
707 }
708
709 vchar_t *
710 isakmp_xauth_set(iph1, attr)
711         struct ph1handle *iph1;
712         struct isakmp_data *attr;
713 {
714         int type;
715         vchar_t *buffer = NULL;
716         char *data;
717
718         if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
719                 plog(LLV_ERROR, LOCATION, NULL, 
720                     "Xauth mode config set but peer "
721                     "did not declare itself as Xauth capable\n");
722                 return NULL;
723         }
724
725         type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
726
727         switch(type) {
728         case XAUTH_STATUS:
729                 /* If we got a failure, delete iph1 */
730                 if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
731                         plog(LLV_ERROR, LOCATION, NULL, 
732                             "Xauth authentication failed\n");
733
734                         EVT_PUSH(iph1->local, iph1->remote, 
735                             EVTT_XAUTH_FAILED, NULL);
736
737                         iph1->mode_cfg->flags &= ISAKMP_CFG_DELETE_PH1;
738                 } else {
739                         EVT_PUSH(iph1->local, 
740                             iph1->remote, EVTT_XAUTH_SUCCESS, NULL);
741                 }
742
743
744                 /* We acknowledge it */
745                 break;
746         default:
747                 plog(LLV_WARNING, LOCATION, NULL,
748                     "Ignored attribute %d\n", type);
749                 return NULL;
750                 break;
751         }
752
753         if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
754                 plog(LLV_ERROR, LOCATION, NULL,
755                     "Cannot allocate memory\n");
756                 return NULL;
757         }
758
759         attr = (struct isakmp_data *)buffer->v;
760         attr->type = htons(type | ISAKMP_GEN_TV);
761         attr->lorv = htons(0);
762
763         return buffer;
764 }
765
766
767 void 
768 xauth_rmstate(xst)
769         struct xauth_state *xst;
770 {
771         switch (xst->authtype) {
772         case XAUTH_TYPE_GENERIC:
773                 if (xst->authdata.generic.usr)
774                         racoon_free(xst->authdata.generic.usr);
775
776                 if (xst->authdata.generic.pwd)
777                         racoon_free(xst->authdata.generic.pwd);
778
779                 break;
780
781         case XAUTH_TYPE_CHAP:
782         case XAUTH_TYPE_OTP:
783         case XAUTH_TYPE_SKEY:
784                 plog(LLV_WARNING, LOCATION, NULL, 
785                     "Unsupported authtype %d\n", xst->authtype);
786                 break;
787
788         default:
789                 plog(LLV_WARNING, LOCATION, NULL, 
790                     "Unexpected authtype %d\n", xst->authtype);
791                 break;
792         }
793
794         return;
795 }