158 lines
6.5 KiB
Plaintext
158 lines
6.5 KiB
Plaintext
PPP Client Support for Microsoft's CHAP-80
|
|
==========================================
|
|
|
|
Eric Rosenquist rosenqui@strataware.com
|
|
|
|
|
|
INTRODUCTION
|
|
|
|
Microsoft has introduced an extension to the Challenge/Handshake
|
|
Authentication Protocol (CHAP) which eliminates the need for them to have
|
|
access to cleartext passwords. The details of the Microsoft extensions can
|
|
be found in the document:
|
|
|
|
<ftp://ftp.microsoft.com/developr/rfc/chapexts.txt>
|
|
|
|
In short, MS-CHAP is identified as <auth chap 80> since the hex value of 80
|
|
is used to designate Microsoft's scheme. Standard PPP CHAP uses a value of
|
|
5. If you enable PPP debugging with the "debug" option and see something
|
|
like the following in your logs, the remote server is requesting MS-CHAP:
|
|
|
|
rcvd [LCP ConfReq id=0x2 <asyncmap 0x0> <auth chap 80> <magic 0x46a3>]
|
|
^^^^^^^^^^^^
|
|
|
|
The standard PPP implementation will indicate its lack of support for
|
|
MS-CHAP by NAKing it:
|
|
|
|
lcp_reqci: rcvd AUTHTYPE
|
|
(c223)
|
|
(NAK)
|
|
|
|
Windows NT Server systems are often configured to "Accept only Microsoft
|
|
Authentication" to enhance security. Up until now, that meant that you
|
|
couldn't use this version of PPPD to connect to such a system. I've
|
|
managed to get a client-only implementation of MS-CHAP working; it will
|
|
authenticate itself to another system using MS-CHAP, but if you're using
|
|
PPPD as a dial-in server, you won't be able to use MS-CHAP to authenticate
|
|
the clients. This would not be a lot of extra work given that the
|
|
framework is in place, but I didn't need it myself so I didn't implement
|
|
it.
|
|
|
|
|
|
BUILDING THE PPPD
|
|
|
|
MS-CHAP uses a combination of MD4 hashing and DES encryption for
|
|
authentication. You'll need to get Eric Young's DES library in order to
|
|
use my MS-CHAP extensions. You can find it in:
|
|
|
|
<ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/>
|
|
|
|
I used libdes-3.06, but hopefully anything newer than that will work also.
|
|
Get the library, build and test it on your system, and install it somewhere
|
|
(typically /usr/local/lib and /usr/local/include).
|
|
|
|
You should now be ready to (re)compile the PPPD. Go to the ppp-X.Y/pppd
|
|
directory and make sure the Makefile contains "-DUSE_MSCHAP" in the
|
|
COMPILE_FLAGS macro, and that the LIBS macro contains "-ldes". Depending
|
|
on your system and where the DES library was installed, you may also need
|
|
to alter the include and library paths used by your compiler.
|
|
|
|
Do a "make clean" and then a "make" to rebuild the PPPD. Assuming all goes
|
|
well, install the new PPPD and move on to the CONFIGURATION section.
|
|
|
|
|
|
CONFIGURATION
|
|
|
|
If you've never used PPPD with CHAP before, read the man page (type "man
|
|
pppd") and read the description in there. Basically, you need to edit the
|
|
"chap-secrets" file typically named /etc/ppp/chap-secrets. This should
|
|
contain the following two lines for each system with which you use CHAP
|
|
(with no leading blanks):
|
|
|
|
RemoteHost Account Secret
|
|
Account RemoteHost Secret
|
|
|
|
Note that you need both lines and that item 1 and 2 are swapped in the
|
|
second line. I'm not sure why you need it twice, but it works and I didn't
|
|
have time to look into it further. The "RemoteHost" is a somewhat
|
|
arbitrary name for the remote Windows NT system you're dialing. It doesn't
|
|
have to match the NT system's name, but it *does* have to match what you
|
|
use with the "remotename" parameter. The "Account" is the Windows NT
|
|
account name you have been told to use when dialing, and the "Secret" is
|
|
the password for that account. For example, if your service provider calls
|
|
their machine "DialupNT" and tells you your account and password are
|
|
"customer47" and "foobar", add the following to your chap-secrets file:
|
|
|
|
DialupNT customer47 foobar
|
|
customer47 DialupNT foobar
|
|
|
|
The only other thing you need to do for MS-CHAP (compared to normal CHAP)
|
|
is to always use the "remotename" option, either on the command line or in
|
|
your "options" file (see the pppd man page for details). In the case of
|
|
the above example, you would need to use the following command line:
|
|
|
|
pppd name customer47 remotename DialupNT <other options>
|
|
|
|
or add:
|
|
|
|
name customer47
|
|
remotename DialupNT
|
|
|
|
to your PPPD "options" file.
|
|
|
|
The "remotename" option is required for MS-CHAP since Microsoft PPP servers
|
|
don't send their system name in the CHAP challenge packet.
|
|
|
|
|
|
TROUBLESHOOTING
|
|
|
|
Assuming that everything else has been configured correctly for PPP and
|
|
CHAP, the MS-CHAP-specific problems you're likely to encounter are mostly
|
|
related to your Windows NT account and its settings. A Microsoft server
|
|
returns error codes in its CHAP response. The following are extracted from
|
|
Microsoft's "chapexts.txt" file referenced above:
|
|
|
|
646 ERROR_RESTRICTED_LOGON_HOURS
|
|
647 ERROR_ACCT_DISABLED
|
|
648 ERROR_PASSWD_EXPIRED
|
|
649 ERROR_NO_DIALIN_PERMISSION
|
|
691 ERROR_AUTHENTICATION_FAILURE
|
|
709 ERROR_CHANGING_PASSWORD
|
|
|
|
You'll see these in your pppd log as a line similar to:
|
|
|
|
Remote message: E=649 R=0
|
|
|
|
The "E=" is the error number from the table above, and the "R=" flag
|
|
indicates whether the error is transient and the client should retry. If
|
|
you consistently get error 691, then either you're using the wrong account
|
|
name/password, or the DES library or MD4 hashing (in md4.c) aren't working
|
|
properly. Verify your account name and password (use a Windows NT or
|
|
Windows 95 system to dial-in if you have one available). If that checks
|
|
out, test the DES library with the "destest" program included with the DES
|
|
library. If DES checks out, the md4.c routines are probably failing
|
|
(system byte ordering may be a problem) or my code is screwing up. I've
|
|
only got access to a Linux system, so you're on your own for anything else.
|
|
I can generate an MD4 test program if necessary in order to verify proper
|
|
MD4 operation.
|
|
|
|
|
|
STILL TO DO
|
|
|
|
A site using only MS-CHAP to authenticate has no need to store cleartext
|
|
passwords in the "chap-secrets" file. A utility that spits out the ASCII
|
|
hex MD4 hash of a given password would be nice, and would allow that hash
|
|
to be used in chap-secrets in place of the password. The code to do this
|
|
could quite easily be lifted from chap_ms.c (you have to convert the
|
|
password to Unicode before hashing it). The chap_ms.c file would also have
|
|
to be changed to recognize a password hash (16 binary bytes == 32 ASCII hex
|
|
characters) and skip the hashing stage.
|
|
|
|
A server implementation would allow MS-CHAP to be used with Windows NT and
|
|
Windows 95 clients for enhanced security. Some new command-line options
|
|
would be required, as would code to generate the Challenge packet and
|
|
verify the response. Most of the helper functions are in place, so this
|
|
shouldn't be too hard for someone to add.
|
|
|
|
|