import from HEAD:
[freeradius.git] / src / modules / rlm_otp / otp_pwe.c
1 /*
2  * $Id$
3  *
4  *   This program is free software; you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program; if not, write to the Free Software
16  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  * Copyright 2001,2002  Google, Inc.
19  * Copyright 2005,2006 TRI-D Systems, Inc.
20  */
21
22 /*
23  * This file implements passcode (password) checking functions for each
24  * supported encoding (PAP, CHAP, etc.).  The current libradius interface
25  * is not sufficient for X9.9 use.
26  */
27
28 static const char rcsid[] = "$Id$";
29
30 /* avoid inclusion of these FR headers which conflict w/ OpenSSL */
31 #define _LRAD_MD4_H
32 #define _LRAD_SHA1_H
33 #include <rad_assert.h>
34 #include <autoconf.h>
35 #include <radiusd.h>
36
37 #include "extern.h"
38
39 #include <openssl/des.h>
40 #include <openssl/md4.h>
41 #include <openssl/md5.h>
42 #include <openssl/sha.h>
43
44 #include <string.h>
45
46 /* Attribute IDs for supported password encodings. */
47 int pwattr[8];
48
49
50 /* Initialize the pwattr array for supported password encodings. */
51 void
52 otp_pwe_init(void)
53 {
54   DICT_ATTR *da;
55
56   /*
57    * Setup known password types.  These are pairs.
58    * NB: Increase pwattr array size when adding a type.
59    *     It should be sized as (number of password types * 2)
60    * NB: Array indices must match otp_pwe_t! (see otp.h)
61    */
62   (void) memset(pwattr, 0, sizeof(pwattr));
63
64   /* PAP */
65   if ((da = dict_attrbyname("User-Password")) != NULL) {
66     pwattr[0] = da->attr;
67     pwattr[1] = da->attr;
68   }
69
70   /* CHAP */
71   if ((da = dict_attrbyname("CHAP-Challenge")) != NULL) {
72     pwattr[2] = da->attr;
73     if ((da = dict_attrbyname("CHAP-Password")) != NULL)
74       pwattr[3] = da->attr;
75     else
76       pwattr[2] = 0;
77   }
78
79 #if 0
80   /* MS-CHAP (recommended not to use) */
81   if ((da = dict_attrbyname("MS-CHAP-Challenge")) != NULL) {
82     pwattr[4] = da->attr;
83     if ((da = dict_attrbyname("MS-CHAP-Response")) != NULL)
84       pwattr[5] = da->attr;
85     else
86       pwattr[4] = 0;
87   }
88 #endif /* 0 */
89
90   /* MS-CHAPv2 */
91   if ((da = dict_attrbyname("MS-CHAP-Challenge")) != NULL) {
92     pwattr[6] = da->attr;
93     if ((da = dict_attrbyname("MS-CHAP2-Response")) != NULL)
94       pwattr[7] = da->attr;
95     else
96       pwattr[6] = 0;
97   }
98 }
99
100
101 /*
102  * Test for password presence in an Access-Request packet.
103  * Returns 0 for "no supported password present", or the
104  * password encoding type.
105  */
106 otp_pwe_t
107 otp_pwe_present(const REQUEST *request)
108 {
109   unsigned i;
110
111   for (i = 0; i < sizeof(pwattr); i += 2) {
112     if (pairfind(request->packet->vps, pwattr[i]) &&
113         pairfind(request->packet->vps, pwattr[i + 1])) {
114       DEBUG("rlm_otp: %s: password attributes %d, %d", __func__,
115              pwattr[i], pwattr[i + 1]);
116       return i + 1; /* Can't return 0 (indicates failure) */
117     }
118   }
119
120   DEBUG("rlm_otp: %s: no password attributes present", __func__);
121   return 0;
122 }