]> git.ozlabs.org Git - ppp.git/blob - README.MSCHAP80
prototypes always (remove __P)
[ppp.git] / README.MSCHAP80
1 PPP Client Support for Microsoft's CHAP-80
2 ==========================================
3
4 Eric Rosenquist          rosenqui@strataware.com
5 (updated by Paul Mackerras)
6
7 INTRODUCTION
8
9 Microsoft has introduced an extension to the Challenge/Handshake
10 Authentication Protocol (CHAP) which avoids storing cleartext
11 passwords on a server.  (Unfortunately, this is not as secure as it
12 sounds, because the encrypted password stored on a server can be used
13 by a bogus client to gain access to the server just as easily as if
14 the password were stored in cleartext.)  The details of the Microsoft
15 extensions can be found in the document:
16
17     <ftp://ftp.microsoft.com/developr/rfc/chapexts.txt>
18
19 In short, MS-CHAP is identified as <auth chap 80> since the hex value
20 of 80 is used to designate Microsoft's scheme.  Standard PPP CHAP uses
21 a value of 5.  If you enable PPP debugging with the "debug" option and
22 see something like the following in your logs, the remote server is
23 requesting MS-CHAP:
24
25   rcvd [LCP ConfReq id=0x2 <asyncmap 0x0> <auth chap 80> <magic 0x46a3>]
26                                            ^^^^^^^^^^^^
27
28 The standard pppd implementation will indicate its lack of support for
29 MS-CHAP by NAKing it:
30
31   sent [LCP ConfNak id=0x2 <auth chap 05>]
32
33 Windows NT Server systems are often configured to "Accept only
34 Microsoft Authentication" (this is intended to enhance security).  Up
35 until now, that meant that you couldn't use this version of PPPD to
36 connect to such a system.  I've managed to get a client-only
37 implementation of MS-CHAP working; it will authenticate itself to
38 another system using MS-CHAP, but if you're using PPPD as a dial-in
39 server, you won't be able to use MS-CHAP to authenticate the clients.
40 This would not be a lot of extra work given that the framework is in
41 place, but I didn't need it myself so I didn't implement it.
42
43
44 BUILDING THE PPPD
45
46 MS-CHAP uses a combination of MD4 hashing and DES encryption for
47 authentication.  You'll need to get Eric Young's libdes library in
48 order to use my MS-CHAP extensions.  You can find it in:
49
50 ftp://ftp.funet.fi/pub/crypt/mirrors/ftp.psy.uq.oz.au/DES/libdes-3.06.tar.gz
51
52 Australian residents can get libdes from Eric Young's site:
53
54 ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-3.06.tar.gz
55
56 It is also available on many other sites (ask Archie).
57
58 I used libdes-3.06, but hopefully anything newer than that will work
59 also.  Get the library, build and test it on your system, and install
60 it somewhere (typically /usr/local/lib and /usr/local/include).
61
62 You should now be ready to (re)compile the PPPD.  Go to the pppd
63 subdirectory and make sure the Makefile contains "-DCHAPMS" in the
64 CFLAGS or COMPILE_FLAGS macro, and that the LIBS macro (or LDADD for
65 BSD systems) contains "-ldes".  Depending on your system and where the
66 DES library was installed, you may also need to alter the include and
67 library paths used by your compiler.
68
69 Do a "make clean" and then a "make" to rebuild pppd.  Assuming all
70 goes well, install the new pppd and move on to the CONFIGURATION
71 section.
72
73
74 CONFIGURATION
75
76 If you've never used PPPD with CHAP before, read the man page (type
77 "man pppd") and read the description in there.  Basically, you need to
78 edit the "chap-secrets" file typically named /etc/ppp/chap-secrets.
79 This should contain the following two lines for each system with which
80 you use CHAP (with no leading blanks):
81
82     RemoteHost  Account     Secret
83     Account     RemoteHost  Secret
84
85 Note that you need both lines and that item 1 and 2 are swapped in the
86 second line.  I'm not sure why you need it twice, but it works and I didn't
87 have time to look into it further.  The "RemoteHost" is a somewhat
88 arbitrary name for the remote Windows NT system you're dialing.  It doesn't
89 have to match the NT system's name, but it *does* have to match what you
90 use with the "remotename" parameter.  The "Account" is the Windows NT
91 account name you have been told to use when dialing, and the "Secret" is
92 the password for that account.  For example, if your service provider calls
93 their machine "DialupNT" and tells you your account and password are
94 "customer47" and "foobar", add the following to your chap-secrets file:
95
96     DialupNT    customer47  foobar
97     customer47  DialupNT    foobar
98
99 The only other thing you need to do for MS-CHAP (compared to normal CHAP)
100 is to always use the "remotename" option, either on the command line or in
101 your "options" file (see the pppd man page for details).  In the case of
102 the above example, you would need to use the following command line:
103
104     pppd name customer47 remotename DialupNT <other options>
105
106 or add:
107
108     name customer47
109     remotename DialupNT
110
111 to your PPPD "options" file.
112
113 The "remotename" option is required for MS-CHAP since Microsoft PPP servers
114 don't send their system name in the CHAP challenge packet.
115
116
117 TROUBLESHOOTING
118
119 Assuming that everything else has been configured correctly for PPP and
120 CHAP, the MS-CHAP-specific problems you're likely to encounter are mostly
121 related to your Windows NT account and its settings.  A Microsoft server
122 returns error codes in its CHAP response.  The following are extracted from
123 Microsoft's "chapexts.txt" file referenced above:
124
125  646 ERROR_RESTRICTED_LOGON_HOURS
126  647 ERROR_ACCT_DISABLED
127  648 ERROR_PASSWD_EXPIRED
128  649 ERROR_NO_DIALIN_PERMISSION
129  691 ERROR_AUTHENTICATION_FAILURE
130  709 ERROR_CHANGING_PASSWORD
131
132 You'll see these in your pppd log as a line similar to:
133
134    Remote message: E=649 R=0
135
136 The "E=" is the error number from the table above, and the "R=" flag
137 indicates whether the error is transient and the client should retry.  If
138 you consistently get error 691, then either you're using the wrong account
139 name/password, or the DES library or MD4 hashing (in md4.c) aren't working
140 properly.  Verify your account name and password (use a Windows NT or
141 Windows 95 system to dial-in if you have one available).  If that checks
142 out, test the DES library with the "destest" program included with the DES
143 library.  If DES checks out, the md4.c routines are probably failing
144 (system byte ordering may be a problem) or my code is screwing up.  I've
145 only got access to a Linux system, so you're on your own for anything else.
146
147 If everything compiles cleanly, but fails at authentication time, then
148 it might be a case of the MD4 or DES code screwing up.  The following
149 small program can be used to test the MS-CHAP code to see if it
150 produces a known response:
151
152 -----------------
153 #include <stdio.h>
154
155 #include "pppd.h"
156 #include "chap.h"
157 #include "chap_ms.h"
158
159 int main(argc, argv)
160     int     argc;
161     char    *argv[0];
162 {
163     u_char          challenge[8];
164     int             challengeInt[sizeof(challenge)];
165     chap_state      cstate;
166     int             i;
167
168     if (argc != 3) {
169         fprintf(stderr, "Usage: %s <16-hexchar challenge> <password>\n",
170         argv[0]); exit(1);
171     }
172
173     sscanf(argv[1], "%2x%2x%2x%2x%2x%2x%2x%2x",
174            challengeInt + 0, challengeInt + 1, challengeInt + 2,
175            challengeInt + 3, challengeInt + 4, challengeInt + 5,
176            challengeInt + 6, challengeInt + 7);
177
178     for (i = 0; i < sizeof(challenge); i++)
179         challenge[i] = (u_char)challengeInt[i];
180
181     ChapMS(&cstate, challenge, sizeof(challenge), argv[2], strlen(argv[2]));
182     printf("Response length is %d, response is:", cstate.resp_length);
183
184     for (i = 0; i < cstate.resp_length; i++) {
185         if (i % 8 == 0)
186             putchar('\n');
187         printf("%02X ", (unsigned int)cstate.response[i]);
188     }
189
190     putchar('\n');
191
192     exit(0);
193 }
194 -------------
195
196 This needs to link against chap_ms.o, md4.o, and the DES library.  When 
197 you run it with the command line:
198
199  $ testchap 00000000000000000000000000000000 hello
200
201 it should output the following:
202
203  Response length is 49, response is:
204  00 00 00 00 00 00 00 00
205  00 00 00 00 00 00 00 00
206  00 00 00 00 00 00 00 00
207  F4 D9 9D AF 82 64 DC 3C
208  53 F9 BC 92 14 B5 5D 9E
209  78 C4 21 48 9D B7 A8 B4
210  01
211
212 if not, then either the DES library is not working, the MD4 code isn't 
213 working, or there are some problems with the port of the code in 
214 chap_ms.c.
215
216
217 STILL TO DO
218
219 A site using only MS-CHAP to authenticate has no need to store cleartext
220 passwords in the "chap-secrets" file.  A utility that spits out the ASCII
221 hex MD4 hash of a given password would be nice, and would allow that hash
222 to be used in chap-secrets in place of the password.  The code to do this
223 could quite easily be lifted from chap_ms.c (you have to convert the
224 password to Unicode before hashing it).  The chap_ms.c file would also have
225 to be changed to recognize a password hash (16 binary bytes == 32 ASCII hex
226 characters) and skip the hashing stage.
227
228 A server implementation would allow MS-CHAP to be used with Windows NT and
229 Windows 95 clients for enhanced security.  Some new command-line options
230 would be required, as would code to generate the Challenge packet and
231 verify the response.  Most of the helper functions are in place, so this
232 shouldn't be too hard for someone to add.