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