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 #include "ident.h"
29 RCSID("$Id$")
30
31 /* avoid inclusion of these FR headers which conflict w/ OpenSSL */
32 #define _LRAD_MD4_H
33 #define _LRAD_SHA1_H
34 #include <rad_assert.h>
35 #include <autoconf.h>
36 #include <radiusd.h>
37
38 #include "extern.h"
39
40 #include <openssl/des.h>
41 #include <openssl/md4.h>
42 #include <openssl/md5.h>
43 #include <openssl/sha.h>
44
45 #include <string.h>
46
47 /* Attribute IDs for supported password encodings. */
48 int pwattr[8];
49
50
51 /* Initialize the pwattr array for supported password encodings. */
52 void
53 otp_pwe_init(void)
54 {
55   DICT_ATTR *da;
56
57   /*
58    * Setup known password types.  These are pairs.
59    * NB: Increase pwattr array size when adding a type.
60    *     It should be sized as (number of password types * 2)
61    * NB: Array indices must match otp_pwe_t! (see otp.h)
62    */
63   (void) memset(pwattr, 0, sizeof(pwattr));
64
65   /* PAP */
66   if ((da = dict_attrbyname("User-Password")) != NULL) {
67     pwattr[0] = da->attr;
68     pwattr[1] = da->attr;
69   }
70
71   /* CHAP */
72   if ((da = dict_attrbyname("CHAP-Challenge")) != NULL) {
73     pwattr[2] = da->attr;
74     if ((da = dict_attrbyname("CHAP-Password")) != NULL)
75       pwattr[3] = da->attr;
76     else
77       pwattr[2] = 0;
78   }
79
80 #if 0
81   /* MS-CHAP (recommended not to use) */
82   if ((da = dict_attrbyname("MS-CHAP-Challenge")) != NULL) {
83     pwattr[4] = da->attr;
84     if ((da = dict_attrbyname("MS-CHAP-Response")) != NULL)
85       pwattr[5] = da->attr;
86     else
87       pwattr[4] = 0;
88   }
89 #endif /* 0 */
90
91   /* MS-CHAPv2 */
92   if ((da = dict_attrbyname("MS-CHAP-Challenge")) != NULL) {
93     pwattr[6] = da->attr;
94     if ((da = dict_attrbyname("MS-CHAP2-Response")) != NULL)
95       pwattr[7] = da->attr;
96     else
97       pwattr[6] = 0;
98   }
99 }
100
101
102 /*
103  * Test for password presence in an Access-Request packet.
104  * Returns 0 for "no supported password present", or the
105  * password encoding type.
106  */
107 otp_pwe_t
108 otp_pwe_present(const REQUEST *request)
109 {
110   unsigned i;
111
112   for (i = 0; i < sizeof(pwattr); i += 2) {
113     if (pairfind(request->packet->vps, pwattr[i]) &&
114         pairfind(request->packet->vps, pwattr[i + 1])) {
115       DEBUG("rlm_otp: %s: password attributes %d, %d", __func__,
116              pwattr[i], pwattr[i + 1]);
117       return i + 1; /* Can't return 0 (indicates failure) */
118     }
119   }
120
121   DEBUG("rlm_otp: %s: no password attributes present", __func__);
122   return 0;
123 }