initial check in
This commit is contained in:
parent
4c3ccfc893
commit
8f5ca2eb2b
|
@ -0,0 +1,92 @@
|
|||
#
|
||||
# pppd makefile for Linux
|
||||
# $Id: Makefile,v 1.1 1997/03/07 16:01:00 hipp Exp $
|
||||
#
|
||||
|
||||
# These are set from the main Makefile
|
||||
# BINDIR = /sbin/
|
||||
# MANDIR = /usr/man/
|
||||
|
||||
|
||||
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
|
||||
ipxcp.c auth.c options.c sys-linux.c cbcp.c
|
||||
HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h \
|
||||
ipxcp.h cbcp.h
|
||||
MANPAGES = pppd.8
|
||||
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
|
||||
auth.o options.o sys-linux.o cbcp.o ipxcp.o
|
||||
|
||||
all: ipppd
|
||||
|
||||
#
|
||||
# include dependancies if present and backup if as a header file
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
HEADERS := $(HEADERS) .depend
|
||||
endif
|
||||
|
||||
# CC = gcc
|
||||
DEBUG_FLAGS = -DDEBUGALL
|
||||
# USE_MSCHAP = 1
|
||||
# HAS_SHADOW = 1
|
||||
|
||||
COMPILE_FLAGS = -D_linux_=1 -DHAVE_PATHS_H -Wall -Dlint # -DDEBUGALL
|
||||
COPTS = -O2 -fomit-frame-pointer -m486 # -g
|
||||
VER = 2.2.0
|
||||
LIBS = -lbsd
|
||||
|
||||
CFLAGS= $(COPTS) $(DEBUG_FLAGS) $(COMPILE_FLAGS)
|
||||
SOURCE= RELNOTES Makefile.linux $(PPPDSRCS) $(HEADERS) $(MANPAGES)
|
||||
|
||||
ifdef USE_MSCHAP
|
||||
PPPDSRCS += md4.c chap_ms.c
|
||||
PPPDOBJS += md4.o chap_ms.o
|
||||
HEADERS += md4.h ms_chap.h
|
||||
CFLAGS += -DUSE_MSCHAP
|
||||
LIBS += -ldes
|
||||
endif
|
||||
|
||||
|
||||
ifdef USE_MS_DNS
|
||||
CFLAGS += -DUSE_MS_DNS=1
|
||||
endif
|
||||
|
||||
ifdef HAS_SHADOW
|
||||
CFLAGS += -DHAS_SHADOW
|
||||
LIBS += -lcrypt
|
||||
PPPDOBJS += isexpired.o
|
||||
PPPDSRCS += isexpired.c
|
||||
endif
|
||||
|
||||
install: ipppd
|
||||
mkdir -p $(BINDIR) $(MANDIR)
|
||||
install -s -c -m 555 -o root ipppd $(BINDIR)/ipppd
|
||||
install -c -m 555 -o root ipppd.8 $(MANDIR)/man8
|
||||
|
||||
ipppd: $(PPPDOBJS)
|
||||
$(CC) $(CFLAGS) -o ipppd $(PPPDOBJS) $(LIBS)
|
||||
|
||||
pppd.tar: $(SOURCE)
|
||||
tar -cvf pppd.tar $(SOURCE)
|
||||
|
||||
pppd.tar.gz: pppd.tar
|
||||
gzip pppd.tar
|
||||
|
||||
clean:
|
||||
rm -f $(PPPDOBJS) ipppd *~ #* core
|
||||
|
||||
depend:
|
||||
$(CPP) -M $(CFLAGS) $(PPPDSRCS) >.depend
|
||||
#
|
||||
# These disable warnings because some people complain about the
|
||||
# warnings which do not cause harm.
|
||||
#
|
||||
main.o: main.c
|
||||
$(CC) $(CFLAGS) -o main.o -c main.c
|
||||
|
||||
auth.o: auth.c
|
||||
$(CC) $(CFLAGS) -o auth.o -c auth.c
|
||||
|
||||
options.o: options.c
|
||||
$(CC) $(CFLAGS) -o options.o -c options.c
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
#
|
||||
# pppd makefile for Linux
|
||||
# $Id: Makefile.linux,v 1.1 1997/03/07 16:01:01 hipp Exp $
|
||||
#
|
||||
|
||||
# These are set from the main Makefile
|
||||
# BINDIR = /sbin/
|
||||
# MANDIR = /usr/man/
|
||||
|
||||
|
||||
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
|
||||
ipxcp.c auth.c options.c sys-linux.c cbcp.c
|
||||
HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h \
|
||||
ipxcp.h cbcp.h
|
||||
MANPAGES = pppd.8
|
||||
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
|
||||
auth.o options.o sys-linux.o cbcp.o ipxcp.o
|
||||
|
||||
all: ipppd
|
||||
|
||||
#
|
||||
# include dependancies if present and backup if as a header file
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
HEADERS := $(HEADERS) .depend
|
||||
endif
|
||||
|
||||
# CC = gcc
|
||||
DEBUG_FLAGS = -DDEBUGALL
|
||||
# USE_MSCHAP = 1
|
||||
# HAS_SHADOW = 1
|
||||
|
||||
COMPILE_FLAGS = -D_linux_=1 -DHAVE_PATHS_H -Wall -Dlint # -DDEBUGALL
|
||||
COPTS = -O2 -fomit-frame-pointer -m486 # -g
|
||||
VER = 2.2.0
|
||||
LIBS = -lbsd
|
||||
|
||||
CFLAGS= $(COPTS) $(DEBUG_FLAGS) $(COMPILE_FLAGS)
|
||||
SOURCE= RELNOTES Makefile.linux $(PPPDSRCS) $(HEADERS) $(MANPAGES)
|
||||
|
||||
ifdef USE_MSCHAP
|
||||
PPPDSRCS += md4.c chap_ms.c
|
||||
PPPDOBJS += md4.o chap_ms.o
|
||||
HEADERS += md4.h ms_chap.h
|
||||
CFLAGS += -DUSE_MSCHAP
|
||||
LIBS += -ldes
|
||||
endif
|
||||
|
||||
|
||||
ifdef USE_MS_DNS
|
||||
CFLAGS += -DUSE_MS_DNS=1
|
||||
endif
|
||||
|
||||
ifdef HAS_SHADOW
|
||||
CFLAGS += -DHAS_SHADOW
|
||||
LIBS += -lcrypt
|
||||
PPPDOBJS += isexpired.o
|
||||
PPPDSRCS += isexpired.c
|
||||
endif
|
||||
|
||||
install: ipppd
|
||||
mkdir -p $(BINDIR) $(MANDIR)
|
||||
install -s -c -m 555 -o root ipppd $(BINDIR)/ipppd
|
||||
install -c -m 555 -o root ipppd.8 $(MANDIR)/man8
|
||||
|
||||
ipppd: $(PPPDOBJS)
|
||||
$(CC) $(CFLAGS) -o ipppd $(PPPDOBJS) $(LIBS)
|
||||
|
||||
pppd.tar: $(SOURCE)
|
||||
tar -cvf pppd.tar $(SOURCE)
|
||||
|
||||
pppd.tar.gz: pppd.tar
|
||||
gzip pppd.tar
|
||||
|
||||
clean:
|
||||
rm -f $(PPPDOBJS) ipppd *~ #* core
|
||||
|
||||
depend:
|
||||
$(CPP) -M $(CFLAGS) $(PPPDSRCS) >.depend
|
||||
#
|
||||
# These disable warnings because some people complain about the
|
||||
# warnings which do not cause harm.
|
||||
#
|
||||
main.o: main.c
|
||||
$(CC) $(CFLAGS) -o main.o -c main.c
|
||||
|
||||
auth.o: auth.c
|
||||
$(CC) $(CFLAGS) -o auth.o -c auth.c
|
||||
|
||||
options.o: options.c
|
||||
$(CC) $(CFLAGS) -o options.o -c options.c
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
ipppd, based on pppd 2.2.0g with a few changes from 2.3
|
||||
============================================================
|
||||
copyright (c) 1995,1996,1997 of all changes by Michael Hipp
|
||||
|
||||
|
||||
ATTENTION .. NEW NEW NEW NEW NEW
|
||||
********************************
|
||||
|
||||
You need at least the 2.0.29 base patch because of a
|
||||
new ioctl!!
|
||||
|
||||
changed default pathname for options to:
|
||||
/etc/ppp/ioptions
|
||||
pidfilename changed to:
|
||||
ipppd.pid
|
||||
removed checking of ~/.ppprc file ('options from user' feature)
|
||||
|
||||
------------------------------------------------------------
|
||||
|
||||
I added a few new options:
|
||||
- 'useifip' will get (if not set to 0.0.0.0) the IP address
|
||||
for the negotiation from the attached network-interface.
|
||||
(also: ipppd will try to negotiate 'pointopoint' IP as remote IP)
|
||||
interface address -> local IP
|
||||
pointopoint address -> remote IP
|
||||
- '+mp' enables MPPP negotiation
|
||||
- 'useifmtu': a not so important option .. better use
|
||||
the 'mtu' option ..
|
||||
- from the ppp-2.3 package I took the 'noccp' option.
|
||||
(-ccp is the same). Necessary for a few
|
||||
netblazers on the remote side.
|
||||
- 'usefirstip' gets the remote address from the first entry in
|
||||
the auth file (if there is an IP address entry). This address
|
||||
should be a full IP address not an address from a masked area.
|
||||
Ipppd calls 'gethostbyname()' and negotiates the result.
|
||||
IP from auth file will overwrite the remote address gotten
|
||||
from the interface.
|
||||
'usefirstip' is UNTESTED!
|
||||
- 'callback type[,message]' enables the callback feature
|
||||
also UNTESTED!
|
||||
e.g: 'callback 0' -> simple callback (info via auth. etc.)
|
||||
'callback 3,12346' -> us E.164 (tel) number 123456 for callback
|
||||
- IPX and MS_DNS are now compiled into the binary without additional option
|
||||
Applied Hartwig Felgers MS-DNS (re)patch for this
|
||||
|
||||
The ipppd can handle multiple devices. This is necessary to
|
||||
link several connections together to one bundle.
|
||||
Also, you only start the ipppd once. It now opens the devices
|
||||
and waits for connections.
|
||||
If you (or the remote side) closes the connection the ipppd
|
||||
reopens the device automatically. (the device .. not the link
|
||||
to the remote)
|
||||
So you shouldn't kill the ipppd to close a link. Instead, trigger
|
||||
a hangup on the netdevice layer.
|
||||
(with isdn4linux: isdnctrl hangup <device>')
|
||||
|
||||
I applied the mschap80 patches (see README.mschap80), but this
|
||||
is untested.
|
||||
I also started to apply the CBCP patches .. not yet finished.
|
||||
May not work!
|
||||
|
||||
I disabled the facility to configure the daemon via
|
||||
the /dev/ppp/ioptions.<devname> file. It's not necessary.
|
||||
Use the 'file' option or the command line for individual
|
||||
configuration.
|
||||
|
||||
Better don't set the permissions of the programm to
|
||||
'setuid to root on execution'. Call the daemon as root instead.
|
||||
No common user must call the daemon!
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
1. Corrections for shadow support. This means that the isexpired routine
|
||||
has been removed, the references to pw_crypt have been changed to use
|
||||
crypt, etc.
|
||||
|
||||
You must, repeat, MUST, have the libcrypt library if you now wish to use
|
||||
shadow passwords. The library is available with the crypt library.
|
||||
|
||||
2. The corrections for the IPXCP routing code.
|
||||
|
||||
3. The addition of a /etc/ppp/auth-up and /etc/ppp/auth-down program. This
|
||||
is used to aid implementations which rely upon the in-band authentication
|
||||
protocols.
|
||||
|
||||
5. The corrections which broken implementations of authentication
|
||||
protocol to cause pppd to loop. I am only aware of the Tumpet winsock
|
||||
stack which caused this condition.
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Introduction.
|
||||
*************
|
||||
|
||||
The Point-to-Point Protocol (PPP) provides a standard way to transmit
|
||||
datagrams over a serial link, as well as a standard way for the
|
||||
machines at either end of the link (the `peers') to negotiate various
|
||||
optional characteristics of the link. Using PPP, a serial link can be
|
||||
used to transmit Internet Protocol (IP) datagrams, allowing TCP/IP
|
||||
connections between the peers. PPP is defined in several RFC (Request
|
||||
For Comments) documents, in particular RFCs 1661, 1662, 1332 and 1334.
|
||||
Other RFCs describe standard ways to transmit datagrams from other
|
||||
network protocols (e.g., DECnet, OSI, Appletalk), but this package
|
||||
only supports IP.
|
||||
|
||||
|
||||
This implementation consists of two parts:
|
||||
|
||||
- kernel code, which implements an interface between the isdn4linux
|
||||
subsystem and the networking code. The interface also forwards
|
||||
control frames to the ippp-device
|
||||
|
||||
- The PPP daemon (ipppd), which negotiates with the peer to establish
|
||||
the link and configures the ippp network interface. Ipppd includes
|
||||
support for authentication, so you can control which other systems
|
||||
may make a PPP connection and what IP addresses they may use.
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,847 @@
|
|||
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.
|
||||
|
||||
|
||||
These are the differences to the origial 2.2.0f distribution package. You
|
||||
must use the patch utility to apply these patches before the code may be
|
||||
built.
|
||||
|
||||
diff --unified --recursive --new-file ppp-2.2.0f.orig/pppd/Makefile.linux ppp-2.2.0f/pppd/Makefile.linux
|
||||
--- ppp-2.2.0f.orig/pppd/Makefile.linux Fri Apr 12 06:27:12 1996
|
||||
+++ ppp-2.2.0f/pppd/Makefile.linux Fri Apr 12 06:25:01 1996
|
||||
@@ -4,8 +4,8 @@
|
||||
#
|
||||
|
||||
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
|
||||
- ipxcp.c auth.c options.c sys-linux.c
|
||||
-HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h \
|
||||
+ ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c
|
||||
+HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h chap_ms.h md4.h \
|
||||
ipxcp.h
|
||||
MANPAGES = pppd.8
|
||||
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
|
||||
@@ -29,6 +29,13 @@
|
||||
|
||||
CFLAGS= $(COPTS) $(DEBUG_FLAGS) $(COMPILE_FLAGS)
|
||||
SOURCE= RELNOTES Makefile.linux $(PPPDSRCS) $(HEADERS) $(MANPAGES)
|
||||
+
|
||||
+ifdef USE_MSCHAP
|
||||
+PPPDSRCS += md4.c chap_ms.c
|
||||
+PPPDOBJS += md4.o chap_ms.o
|
||||
+CFLAGS += -DUSE_MSCHAP
|
||||
+LIBS += -ldes
|
||||
+endif
|
||||
|
||||
ifdef USE_MS_DNS
|
||||
CFLAGS += -DUSE_MS_DNS=1
|
||||
diff --unified --recursive --new-file ppp-2.2.0f.orig/pppd/chap.c ppp-2.2.0f/pppd/chap.c
|
||||
--- ppp-2.2.0f.orig/pppd/chap.c Fri Apr 12 06:10:30 1996
|
||||
+++ ppp-2.2.0f/pppd/chap.c Fri Apr 12 06:25:01 1996
|
||||
@@ -34,6 +34,9 @@
|
||||
|
||||
#include "pppd.h"
|
||||
#include "chap.h"
|
||||
+#ifdef USE_MSCHAP
|
||||
+#include "chap_ms.h"
|
||||
+#endif /* USE_MSCHAP */
|
||||
#include "md5.h"
|
||||
|
||||
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
|
||||
@@ -370,8 +373,17 @@
|
||||
BCOPY(inp, rhostname, len);
|
||||
rhostname[len] = '\000';
|
||||
|
||||
- CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field: %s",
|
||||
- rhostname));
|
||||
+ CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field: '%s'",
|
||||
+ rhostname));
|
||||
+
|
||||
+#ifdef USE_MSCHAP
|
||||
+ /* Microsoft doesn't send their name back in the PPP packet */
|
||||
+ if (!rhostname[0] && cstate->resp_type == CHAP_MICROSOFT) {
|
||||
+ extern char remote_name[];
|
||||
+ strcpy(rhostname, remote_name);
|
||||
+ CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name", rhostname));
|
||||
+ }
|
||||
+#endif /* USE_MSCHAP */
|
||||
|
||||
/* get secret for authenticating ourselves with the specified host */
|
||||
if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
|
||||
@@ -391,7 +403,7 @@
|
||||
/* generate MD based on negotiated type */
|
||||
switch (cstate->resp_type) {
|
||||
|
||||
- case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
|
||||
+ case CHAP_DIGEST_MD5:
|
||||
MD5Init(&mdContext);
|
||||
MD5Update(&mdContext, &cstate->resp_id, 1);
|
||||
MD5Update(&mdContext, secret, secret_len);
|
||||
@@ -400,6 +412,12 @@
|
||||
BCOPY(mdContext.digest, cstate->response, MD5_SIGNATURE_SIZE);
|
||||
cstate->resp_length = MD5_SIGNATURE_SIZE;
|
||||
break;
|
||||
+
|
||||
+#ifdef USE_MSCHAP
|
||||
+ case CHAP_MICROSOFT:
|
||||
+ ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
|
||||
+ break;
|
||||
+#endif /* USE_MSCHAP */
|
||||
|
||||
default:
|
||||
CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->resp_type));
|
||||
diff --unified --recursive --new-file ppp-2.2.0f.orig/pppd/chap.h ppp-2.2.0f/pppd/chap.h
|
||||
--- ppp-2.2.0f.orig/pppd/chap.h Fri Apr 12 06:10:30 1996
|
||||
+++ ppp-2.2.0f/pppd/chap.h Fri Apr 12 06:25:01 1996
|
||||
@@ -39,9 +39,10 @@
|
||||
/*
|
||||
* Challenge lengths (for challenges we send) and other limits.
|
||||
*/
|
||||
+
|
||||
#define MIN_CHALLENGE_LENGTH 32
|
||||
#define MAX_CHALLENGE_LENGTH 64
|
||||
-#define MAX_RESPONSE_LENGTH 16 /* sufficient for MD5 */
|
||||
+#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 and MSCHAP */
|
||||
|
||||
/*
|
||||
* Each interface is described by a chap structure.
|
||||
diff --unified --recursive --new-file ppp-2.2.0f.orig/pppd/chap_ms.c ppp-2.2.0f/pppd/chap_ms.c
|
||||
--- ppp-2.2.0f.orig/pppd/chap_ms.c Wed Dec 31 16:00:00 1969
|
||||
+++ ppp-2.2.0f/pppd/chap_ms.c Fri Apr 12 06:25:02 1996
|
||||
@@ -0,0 +1,179 @@
|
||||
+/*
|
||||
+ * chap_ms.c - Microsoft MS-CHAP compatible implementation.
|
||||
+ *
|
||||
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||
+ * http://www.strataware.com/
|
||||
+ *
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms are permitted
|
||||
+ * provided that the above copyright notice and this paragraph are
|
||||
+ * duplicated in all such forms and that any documentation,
|
||||
+ * advertising materials, and other materials related to such
|
||||
+ * distribution and use acknowledge that the software was developed
|
||||
+ * by Eric Rosenquist. The name of the author may not be used to
|
||||
+ * endorse or promote products derived from this software without
|
||||
+ * specific prior written permission.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
+ */
|
||||
+
|
||||
+#ifdef USE_MSCHAP
|
||||
+#ifndef lint
|
||||
+static char rcsid[] = "$Id: README.mschap80.ORIG,v 1.1 1997/03/07 16:01:05 hipp Exp $";
|
||||
+#endif
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/time.h>
|
||||
+#include <syslog.h>
|
||||
+
|
||||
+#include "pppd.h"
|
||||
+#include "chap.h"
|
||||
+#include "chap_ms.h"
|
||||
+#include "md4.h"
|
||||
+
|
||||
+#include <des.h>
|
||||
+
|
||||
+typedef struct {
|
||||
+ u_char LANManResp[24];
|
||||
+ u_char NTResp[24];
|
||||
+ u_char UseNT; /* If 1, ignore the LANMan response field */
|
||||
+} MS_ChapResponse;
|
||||
+#define MS_CHAP_RESPONSE_LEN 49 /* Don't rely on sizeof(MS_ChapResponse) in case of struct padding */
|
||||
+
|
||||
+
|
||||
+static void DesEncrypt __P((u_char *, u_char *, u_char *));
|
||||
+static void MakeKey __P((u_char *, u_char *));
|
||||
+
|
||||
+static void
|
||||
+ChallengeResponse(challenge, pwHash, response)
|
||||
+ u_char *challenge; /* IN 8 octets */
|
||||
+ u_char *pwHash; /* IN 16 octets */
|
||||
+ u_char *response; /* OUT 24 octets */
|
||||
+{
|
||||
+ char ZPasswordHash[21];
|
||||
+
|
||||
+ BZERO(ZPasswordHash, sizeof(ZPasswordHash));
|
||||
+ BCOPY(pwHash, ZPasswordHash, 16);
|
||||
+
|
||||
+#if 0
|
||||
+ log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash");
|
||||
+#endif
|
||||
+
|
||||
+ DesEncrypt(challenge, ZPasswordHash + 0, response + 0);
|
||||
+ DesEncrypt(challenge, ZPasswordHash + 7, response + 8);
|
||||
+ DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
|
||||
+
|
||||
+#if 0
|
||||
+ log_packet(response, 24, "ChallengeResponse - response");
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+DesEncrypt(clear, key, cipher)
|
||||
+ u_char *clear; /* IN 8 octets */
|
||||
+ u_char *key; /* IN 7 octets */
|
||||
+ u_char *cipher; /* OUT 8 octets */
|
||||
+{
|
||||
+ des_cblock des_key;
|
||||
+ des_key_schedule key_schedule;
|
||||
+
|
||||
+ MakeKey(key, des_key);
|
||||
+
|
||||
+ des_set_key(&des_key, key_schedule);
|
||||
+
|
||||
+#if 0
|
||||
+ CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
+ clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
|
||||
+#endif
|
||||
+
|
||||
+ des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
|
||||
+
|
||||
+#if 0
|
||||
+ CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
+ cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static u_char Get7Bits(input, startBit)
|
||||
+ u_char *input;
|
||||
+ int startBit;
|
||||
+{
|
||||
+ register unsigned int word;
|
||||
+
|
||||
+ word = (unsigned)input[startBit / 8] << 8;
|
||||
+ word |= (unsigned)input[startBit / 8 + 1];
|
||||
+
|
||||
+ word >>= 15 - (startBit % 8 + 7);
|
||||
+
|
||||
+ return word & 0xFE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void MakeKey(key, des_key)
|
||||
+ u_char *key; /* IN 56 bit DES key missing parity bits */
|
||||
+ u_char *des_key; /* OUT 64 bit DES key with parity bits added */
|
||||
+{
|
||||
+ des_key[0] = Get7Bits(key, 0);
|
||||
+ des_key[1] = Get7Bits(key, 7);
|
||||
+ des_key[2] = Get7Bits(key, 14);
|
||||
+ des_key[3] = Get7Bits(key, 21);
|
||||
+ des_key[4] = Get7Bits(key, 28);
|
||||
+ des_key[5] = Get7Bits(key, 35);
|
||||
+ des_key[6] = Get7Bits(key, 42);
|
||||
+ des_key[7] = Get7Bits(key, 49);
|
||||
+
|
||||
+ des_set_odd_parity((des_cblock *)des_key);
|
||||
+
|
||||
+#if 0
|
||||
+ CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X",
|
||||
+ key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
|
||||
+ CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
+ des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
|
||||
+#endif
|
||||
+}
|
||||
+#endif /* USE_MSCHAP */
|
||||
+
|
||||
+void
|
||||
+ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len)
|
||||
+ chap_state *cstate;
|
||||
+ char *rchallenge;
|
||||
+ int rchallenge_len;
|
||||
+ char *secret;
|
||||
+ int secret_len;
|
||||
+{
|
||||
+#ifdef USE_MSCHAP
|
||||
+ int i;
|
||||
+ MDstruct md4Context;
|
||||
+ MS_ChapResponse response;
|
||||
+ u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
+
|
||||
+#if 0
|
||||
+ CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret));
|
||||
+#endif
|
||||
+
|
||||
+ BZERO(&response, sizeof(response));
|
||||
+
|
||||
+ /* Initialize the Unicode version of the secret (== password). */
|
||||
+ /* This implicitly supports 8-bit ISO8859/1 characters. */
|
||||
+ BZERO(unicodePassword, sizeof(unicodePassword));
|
||||
+ for (i = 0; i < secret_len; i++)
|
||||
+ unicodePassword[i * 2] = (u_char)secret[i];
|
||||
+
|
||||
+ MDbegin(&md4Context);
|
||||
+ MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */
|
||||
+ MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */
|
||||
+
|
||||
+ ChallengeResponse(rchallenge, (char *)md4Context.buffer, response.NTResp);
|
||||
+
|
||||
+ response.UseNT = 1;
|
||||
+
|
||||
+ BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
|
||||
+ cstate->resp_length = MS_CHAP_RESPONSE_LEN;
|
||||
+#endif /* USE_MSCHAP */
|
||||
+}
|
||||
diff --unified --recursive --new-file ppp-2.2.0f.orig/pppd/chap_ms.h ppp-2.2.0f/pppd/chap_ms.h
|
||||
--- ppp-2.2.0f.orig/pppd/chap_ms.h Wed Dec 31 16:00:00 1969
|
||||
+++ ppp-2.2.0f/pppd/chap_ms.h Fri Apr 12 06:25:02 1996
|
||||
@@ -0,0 +1,32 @@
|
||||
+/*
|
||||
+ * chap.h - Cryptographic Handshake Authentication Protocol definitions.
|
||||
+ *
|
||||
+ * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||
+ * http://www.strataware.com/
|
||||
+ *
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms are permitted
|
||||
+ * provided that the above copyright notice and this paragraph are
|
||||
+ * duplicated in all such forms and that any documentation,
|
||||
+ * advertising materials, and other materials related to such
|
||||
+ * distribution and use acknowledge that the software was developed
|
||||
+ * by Eric Rosenquist. The name of the author may not be used to
|
||||
+ * endorse or promote products derived from this software without
|
||||
+ * specific prior written permission.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
+ *
|
||||
+ * $Id: README.mschap80.ORIG,v 1.1 1997/03/07 16:01:05 hipp Exp $
|
||||
+ */
|
||||
+
|
||||
+#ifndef __CHAPMS_INCLUDE__
|
||||
+
|
||||
+#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */
|
||||
+
|
||||
+void ChapMS __P((chap_state *, char *, int, char *, int));
|
||||
+
|
||||
+#define __CHAPMS_INCLUDE__
|
||||
+#endif /* __CHAPMS_INCLUDE__ */
|
||||
diff --unified --recursive --new-file ppp-2.2.0f.orig/pppd/lcp.c ppp-2.2.0f/pppd/lcp.c
|
||||
--- ppp-2.2.0f.orig/pppd/lcp.c Fri Apr 12 06:10:31 1996
|
||||
+++ ppp-2.2.0f/pppd/lcp.c Fri Apr 12 06:25:02 1996
|
||||
@@ -1263,7 +1263,11 @@
|
||||
break;
|
||||
}
|
||||
GETCHAR(cichar, p); /* get digest type*/
|
||||
+#ifndef USE_MSCHAP
|
||||
if (cichar != ao->chap_mdtype) {
|
||||
+#else
|
||||
+ if (cichar != ao->chap_mdtype && cichar != CHAP_MICROSOFT) {
|
||||
+#endif /* USE_MSCHAP */
|
||||
orc = CONFNAK;
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
diff --unified --recursive --new-file ppp-2.2.0f.orig/pppd/md4.c ppp-2.2.0f/pppd/md4.c
|
||||
--- ppp-2.2.0f.orig/pppd/md4.c Wed Dec 31 16:00:00 1969
|
||||
+++ ppp-2.2.0f/pppd/md4.c Fri Apr 12 06:10:31 1996
|
||||
@@ -0,0 +1,295 @@
|
||||
+/*
|
||||
+** ********************************************************************
|
||||
+** md4.c -- Implementation of MD4 Message Digest Algorithm **
|
||||
+** Updated: 2/16/90 by Ronald L. Rivest **
|
||||
+** (C) 1990 RSA Data Security, Inc. **
|
||||
+** ********************************************************************
|
||||
+*/
|
||||
+
|
||||
+/*
|
||||
+** To use MD4:
|
||||
+** -- Include md4.h in your program
|
||||
+** -- Declare an MDstruct MD to hold the state of the digest
|
||||
+** computation.
|
||||
+** -- Initialize MD using MDbegin(&MD)
|
||||
+** -- For each full block (64 bytes) X you wish to process, call
|
||||
+** MDupdate(&MD,X,512)
|
||||
+** (512 is the number of bits in a full block.)
|
||||
+** -- For the last block (less than 64 bytes) you wish to process,
|
||||
+** MDupdate(&MD,X,n)
|
||||
+** where n is the number of bits in the partial block. A partial
|
||||
+** block terminates the computation, so every MD computation
|
||||
+** should terminate by processing a partial block, even if it
|
||||
+** has n = 0.
|
||||
+** -- The message digest is available in MD.buffer[0] ...
|
||||
+** MD.buffer[3]. (Least-significant byte of each word
|
||||
+** should be output first.)
|
||||
+** -- You can print out the digest using MDprint(&MD)
|
||||
+*/
|
||||
+
|
||||
+/* Implementation notes:
|
||||
+** This implementation assumes that ints are 32-bit quantities.
|
||||
+** If the machine stores the least-significant byte of an int in the
|
||||
+** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
|
||||
+** should be set to TRUE. Otherwise (e.g., SUNS), LOWBYTEFIRST
|
||||
+** should be set to FALSE. Note that on machines with LOWBYTEFIRST
|
||||
+** FALSE the routine MDupdate modifies has a side-effect on its input
|
||||
+** array (the order of bytes in each word are reversed). If this is
|
||||
+** undesired a call to MDreverse(X) can reverse the bytes of X back
|
||||
+** into order after each call to MDupdate.
|
||||
+**
|
||||
+** NOTE: LOWBYTEFIRST removed by Eric Rosenquist in favour of run-time
|
||||
+** detection to simplify build process.
|
||||
+*/
|
||||
+
|
||||
+#define TRUE 1
|
||||
+#define FALSE 0
|
||||
+
|
||||
+/* Compile-time includes
|
||||
+*/
|
||||
+#include <stdio.h>
|
||||
+#include "md4.h"
|
||||
+#include "pppd.h"
|
||||
+
|
||||
+/* Compile-time declarations of MD4 "magic constants".
|
||||
+*/
|
||||
+#define I0 0x67452301 /* Initial values for MD buffer */
|
||||
+#define I1 0xefcdab89
|
||||
+#define I2 0x98badcfe
|
||||
+#define I3 0x10325476
|
||||
+#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
|
||||
+#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
|
||||
+/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
|
||||
+** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
|
||||
+** Table 2, page 660.
|
||||
+*/
|
||||
+
|
||||
+#define fs1 3 /* round 1 shift amounts */
|
||||
+#define fs2 7
|
||||
+#define fs3 11
|
||||
+#define fs4 19
|
||||
+#define gs1 3 /* round 2 shift amounts */
|
||||
+#define gs2 5
|
||||
+#define gs3 9
|
||||
+#define gs4 13
|
||||
+#define hs1 3 /* round 3 shift amounts */
|
||||
+#define hs2 9
|
||||
+#define hs3 11
|
||||
+#define hs4 15
|
||||
+
|
||||
+/* Compile-time macro declarations for MD4.
|
||||
+** Note: The "rot" operator uses the variable "tmp".
|
||||
+** It assumes tmp is declared as unsigned int, so that the >>
|
||||
+** operator will shift in zeros rather than extending the sign bit.
|
||||
+*/
|
||||
+#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
|
||||
+#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
|
||||
+#define h(X,Y,Z) (X^Y^Z)
|
||||
+#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
|
||||
+#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
|
||||
+#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
|
||||
+#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
|
||||
+
|
||||
+/* MDprint(MDp)
|
||||
+** Print message digest buffer MDp as 32 hexadecimal digits.
|
||||
+** Order is from low-order byte of buffer[0] to high-order byte of
|
||||
+** buffer[3].
|
||||
+** Each byte is printed with high-order hexadecimal digit first.
|
||||
+** This is a user-callable routine.
|
||||
+*/
|
||||
+void
|
||||
+MDprint(MDp)
|
||||
+MDptr MDp;
|
||||
+{ int i,j;
|
||||
+for (i=0;i<4;i++)
|
||||
+ for (j=0;j<32;j=j+8)
|
||||
+ printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
|
||||
+}
|
||||
+
|
||||
+/* MDbegin(MDp)
|
||||
+** Initialize message digest buffer MDp.
|
||||
+** This is a user-callable routine.
|
||||
+*/
|
||||
+void
|
||||
+MDbegin(MDp)
|
||||
+MDptr MDp;
|
||||
+{ int i;
|
||||
+MDp->buffer[0] = I0;
|
||||
+MDp->buffer[1] = I1;
|
||||
+MDp->buffer[2] = I2;
|
||||
+MDp->buffer[3] = I3;
|
||||
+for (i=0;i<8;i++) MDp->count[i] = 0;
|
||||
+MDp->done = 0;
|
||||
+}
|
||||
+
|
||||
+/* MDreverse(X)
|
||||
+** Reverse the byte-ordering of every int in X.
|
||||
+** Assumes X is an array of 16 ints.
|
||||
+** The macro revx reverses the byte-ordering of the next word of X.
|
||||
+*/
|
||||
+#define revx { t = (*X << 16) | (*X >> 16); \
|
||||
+ *X++ = ((t & 0xFF00FF00) >> 8) | ((t & 0x00FF00FF) << 8); }
|
||||
+MDreverse(X)
|
||||
+unsigned int *X;
|
||||
+{ register unsigned int t;
|
||||
+revx; revx; revx; revx; revx; revx; revx; revx;
|
||||
+revx; revx; revx; revx; revx; revx; revx; revx;
|
||||
+}
|
||||
+
|
||||
+/* MDblock(MDp,X)
|
||||
+** Update message digest buffer MDp->buffer using 16-word data block X.
|
||||
+** Assumes all 16 words of X are full of data.
|
||||
+** Does not update MDp->count.
|
||||
+** This routine is not user-callable.
|
||||
+*/
|
||||
+static void
|
||||
+MDblock(MDp,X)
|
||||
+MDptr MDp;
|
||||
+unsigned int *X;
|
||||
+{
|
||||
+register unsigned int tmp, A, B, C, D;
|
||||
+static int low_byte_first = -1;
|
||||
+
|
||||
+if (low_byte_first == -1) {
|
||||
+ low_byte_first = (htons((unsigned short int)1) != 1);
|
||||
+}
|
||||
+
|
||||
+if (low_byte_first == 0) {
|
||||
+ MDreverse(X);
|
||||
+}
|
||||
+
|
||||
+A = MDp->buffer[0];
|
||||
+B = MDp->buffer[1];
|
||||
+C = MDp->buffer[2];
|
||||
+D = MDp->buffer[3];
|
||||
+/* Update the message digest buffer */
|
||||
+ff(A , B , C , D , 0 , fs1); /* Round 1 */
|
||||
+ff(D , A , B , C , 1 , fs2);
|
||||
+ff(C , D , A , B , 2 , fs3);
|
||||
+ff(B , C , D , A , 3 , fs4);
|
||||
+ff(A , B , C , D , 4 , fs1);
|
||||
+ff(D , A , B , C , 5 , fs2);
|
||||
+ff(C , D , A , B , 6 , fs3);
|
||||
+ff(B , C , D , A , 7 , fs4);
|
||||
+ff(A , B , C , D , 8 , fs1);
|
||||
+ff(D , A , B , C , 9 , fs2);
|
||||
+ff(C , D , A , B , 10 , fs3);
|
||||
+ff(B , C , D , A , 11 , fs4);
|
||||
+ff(A , B , C , D , 12 , fs1);
|
||||
+ff(D , A , B , C , 13 , fs2);
|
||||
+ff(C , D , A , B , 14 , fs3);
|
||||
+ff(B , C , D , A , 15 , fs4);
|
||||
+gg(A , B , C , D , 0 , gs1); /* Round 2 */
|
||||
+gg(D , A , B , C , 4 , gs2);
|
||||
+gg(C , D , A , B , 8 , gs3);
|
||||
+gg(B , C , D , A , 12 , gs4);
|
||||
+gg(A , B , C , D , 1 , gs1);
|
||||
+gg(D , A , B , C , 5 , gs2);
|
||||
+gg(C , D , A , B , 9 , gs3);
|
||||
+gg(B , C , D , A , 13 , gs4);
|
||||
+gg(A , B , C , D , 2 , gs1);
|
||||
+gg(D , A , B , C , 6 , gs2);
|
||||
+gg(C , D , A , B , 10 , gs3);
|
||||
+gg(B , C , D , A , 14 , gs4);
|
||||
+gg(A , B , C , D , 3 , gs1);
|
||||
+gg(D , A , B , C , 7 , gs2);
|
||||
+gg(C , D , A , B , 11 , gs3);
|
||||
+gg(B , C , D , A , 15 , gs4);
|
||||
+hh(A , B , C , D , 0 , hs1); /* Round 3 */
|
||||
+hh(D , A , B , C , 8 , hs2);
|
||||
+hh(C , D , A , B , 4 , hs3);
|
||||
+hh(B , C , D , A , 12 , hs4);
|
||||
+hh(A , B , C , D , 2 , hs1);
|
||||
+hh(D , A , B , C , 10 , hs2);
|
||||
+hh(C , D , A , B , 6 , hs3);
|
||||
+hh(B , C , D , A , 14 , hs4);
|
||||
+hh(A , B , C , D , 1 , hs1);
|
||||
+hh(D , A , B , C , 9 , hs2);
|
||||
+hh(C , D , A , B , 5 , hs3);
|
||||
+hh(B , C , D , A , 13 , hs4);
|
||||
+hh(A , B , C , D , 3 , hs1);
|
||||
+hh(D , A , B , C , 11 , hs2);
|
||||
+hh(C , D , A , B , 7 , hs3);
|
||||
+hh(B , C , D , A , 15 , hs4);
|
||||
+MDp->buffer[0] += A;
|
||||
+MDp->buffer[1] += B;
|
||||
+MDp->buffer[2] += C;
|
||||
+MDp->buffer[3] += D;
|
||||
+}
|
||||
+
|
||||
+/* MDupdate(MDp,X,count)
|
||||
+** Input: MDp -- an MDptr
|
||||
+** X -- a pointer to an array of unsigned characters.
|
||||
+** count -- the number of bits of X to use.
|
||||
+** (if not a multiple of 8, uses high bits of last byte.)
|
||||
+** Update MDp using the number of bits of X given by count.
|
||||
+** This is the basic input routine for an MD4 user.
|
||||
+** The routine completes the MD computation when count < 512, so
|
||||
+** every MD computation should end with one call to MDupdate with a
|
||||
+** count less than 512. A call with count 0 will be ignored if the
|
||||
+** MD has already been terminated (done != 0), so an extra call with
|
||||
+** count 0 can be given as a "courtesy close" to force termination
|
||||
+** if desired.
|
||||
+*/
|
||||
+void
|
||||
+MDupdate(MDp,X,count)
|
||||
+MDptr MDp;
|
||||
+unsigned char *X;
|
||||
+unsigned int count;
|
||||
+{ unsigned int i, tmp, bit, byte, mask;
|
||||
+unsigned char XX[64];
|
||||
+unsigned char *p;
|
||||
+/* return with no error if this is a courtesy close with count
|
||||
+** zero and MDp->done is true.
|
||||
+*/
|
||||
+if (count == 0 && MDp->done) return;
|
||||
+/* check to see if MD is already done and report error */
|
||||
+if (MDp->done)
|
||||
+ { printf("\nError: MDupdate MD already done."); return; }
|
||||
+/* Add count to MDp->count */
|
||||
+tmp = count;
|
||||
+p = MDp->count;
|
||||
+while (tmp)
|
||||
+ { tmp += *p;
|
||||
+ *p++ = tmp;
|
||||
+ tmp = tmp >> 8;
|
||||
+ }
|
||||
+/* Process data */
|
||||
+if (count == 512)
|
||||
+ { /* Full block of data to handle */
|
||||
+ MDblock(MDp,(unsigned int *)X);
|
||||
+ }
|
||||
+else if (count > 512) /* Check for count too large */
|
||||
+ { printf("\nError: MDupdate called with illegal count value %d."
|
||||
+ ,count);
|
||||
+ return;
|
||||
+ }
|
||||
+else /* partial block -- must be last block so finish up */
|
||||
+ { /* Find out how many bytes and residual bits there are */
|
||||
+ byte = count >> 3;
|
||||
+ bit = count & 7;
|
||||
+ /* Copy X into XX since we need to modify it */
|
||||
+ for (i=0;i<=byte;i++) XX[i] = X[i];
|
||||
+ for (i=byte+1;i<64;i++) XX[i] = 0;
|
||||
+ /* Add padding '1' bit and low-order zeros in last byte */
|
||||
+ mask = 1 << (7 - bit);
|
||||
+ XX[byte] = (XX[byte] | mask) & ~( mask - 1);
|
||||
+ /* If room for bit count, finish up with this block */
|
||||
+ if (byte <= 55)
|
||||
+ { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
+ MDblock(MDp,(unsigned int *)XX);
|
||||
+ }
|
||||
+ else /* need to do two blocks to finish up */
|
||||
+ { MDblock(MDp,(unsigned int *)XX);
|
||||
+ for (i=0;i<56;i++) XX[i] = 0;
|
||||
+ for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
+ MDblock(MDp,(unsigned int *)XX);
|
||||
+ }
|
||||
+ /* Set flag saying we're done with MD computation */
|
||||
+ MDp->done = 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+** End of md4.c
|
||||
+****************************(cut)***********************************/
|
||||
diff --unified --recursive --new-file ppp-2.2.0f.orig/pppd/md4.h ppp-2.2.0f/pppd/md4.h
|
||||
--- ppp-2.2.0f.orig/pppd/md4.h Wed Dec 31 16:00:00 1969
|
||||
+++ ppp-2.2.0f/pppd/md4.h Fri Apr 12 06:10:31 1996
|
||||
@@ -0,0 +1,51 @@
|
||||
+/*
|
||||
+** ********************************************************************
|
||||
+** md4.h -- Header file for implementation of **
|
||||
+** MD4 Message Digest Algorithm **
|
||||
+** Updated: 2/13/90 by Ronald L. Rivest **
|
||||
+** (C) 1990 RSA Data Security, Inc. **
|
||||
+** ********************************************************************
|
||||
+*/
|
||||
+
|
||||
+/* MDstruct is the data structure for a message digest computation.
|
||||
+*/
|
||||
+typedef struct {
|
||||
+unsigned int buffer[4]; /* Holds 4-word result of MD computation */
|
||||
+unsigned char count[8]; /* Number of bits processed so far */
|
||||
+unsigned int done; /* Nonzero means MD computation finished */
|
||||
+} MDstruct, *MDptr;
|
||||
+
|
||||
+/* MDbegin(MD)
|
||||
+** Input: MD -- an MDptr
|
||||
+** Initialize the MDstruct prepatory to doing a message digest
|
||||
+** computation.
|
||||
+*/
|
||||
+extern void MDbegin();
|
||||
+
|
||||
+/* MDupdate(MD,X,count)
|
||||
+** Input: MD -- an MDptr
|
||||
+** X -- a pointer to an array of unsigned characters.
|
||||
+** count -- the number of bits of X to use (an unsigned int).
|
||||
+** Updates MD using the first "count" bits of X.
|
||||
+** The array pointed to by X is not modified.
|
||||
+** If count is not a multiple of 8, MDupdate uses high bits of
|
||||
+** last byte.
|
||||
+** This is the basic input routine for a user.
|
||||
+** The routine terminates the MD computation when count < 512, so
|
||||
+** every MD computation should end with one call to MDupdate with a
|
||||
+** count less than 512. Zero is OK for a count.
|
||||
+*/
|
||||
+extern void MDupdate();
|
||||
+
|
||||
+/* MDprint(MD)
|
||||
+** Input: MD -- an MDptr
|
||||
+** Prints message digest buffer MD as 32 hexadecimal digits.
|
||||
+** Order is from low-order byte of buffer[0] to high-order byte
|
||||
+** of buffer[3].
|
||||
+** Each byte is printed with high-order hexadecimal digit first.
|
||||
+*/
|
||||
+extern void MDprint();
|
||||
+
|
||||
+/*
|
||||
+** End of md4.h
|
||||
+****************************(cut)***********************************/
|
|
@ -0,0 +1,17 @@
|
|||
TODO to support full MP handling with multiple connections.
|
||||
----
|
||||
|
||||
some of the following values must be changed to fields:
|
||||
(put them into the link structures)
|
||||
xmit_accm
|
||||
(kill_link, is global)
|
||||
lcp_echos_pending
|
||||
lcp_echo_fails
|
||||
lcp_echo_number
|
||||
lcp_echo_interval
|
||||
idle_time_limit
|
||||
lcp_echo_timer_running
|
||||
hungup
|
||||
(baud_rate isn't necessary)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* cbcp - Call Back Configuration Protocol.
|
||||
*
|
||||
* Copyright (c) 1995 Pedro Roque Marques
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Pedro Roque Marques. The name of the author may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#define PPP_CBCP 0xc029 /* Callback Control Protocol */
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: cbcp.c,v 1.1 1997/03/07 16:01:09 hipp Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "cbcp.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ipcp.h"
|
||||
|
||||
|
||||
/*
|
||||
* Protocol entry points.
|
||||
*/
|
||||
static void cbcp_init __P((int unit));
|
||||
static void cbcp_open __P((int unit));
|
||||
static void cbcp_close __P((int unit,char *));
|
||||
static void cbcp_lowerup __P((int unit));
|
||||
static void cbcp_lowerdown __P((int unit));
|
||||
static void cbcp_input __P((int unit, u_char *pkt, int len));
|
||||
static void cbcp_protrej __P((int unit));
|
||||
static int cbcp_printpkt __P((u_char *pkt, int len,
|
||||
void (*printer) __P((void *, char *, ...)),
|
||||
void *arg));
|
||||
|
||||
struct protent cbcp_protent = {
|
||||
PPP_CBCP,
|
||||
cbcp_init,
|
||||
cbcp_input,
|
||||
cbcp_protrej,
|
||||
cbcp_lowerup,
|
||||
cbcp_lowerdown,
|
||||
cbcp_open,
|
||||
cbcp_close,
|
||||
cbcp_printpkt,
|
||||
NULL,
|
||||
0,
|
||||
"CBCP",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
cbcp_state cbcp[NUM_PPP];
|
||||
|
||||
/* internal prototypes */
|
||||
|
||||
void cbcp_recvreq(cbcp_state *us, char *pckt, int len);
|
||||
void cbcp_resp(cbcp_state *us);
|
||||
void cbcp_up(cbcp_state *us);
|
||||
void cbcp_recvack(cbcp_state *us, char *pckt, int len);
|
||||
void cbcp_send(cbcp_state *us, u_char code, u_char *buf, int len);
|
||||
|
||||
/* init state */
|
||||
static void cbcp_init(int cbcp_unit)
|
||||
{
|
||||
cbcp_state *us;
|
||||
|
||||
us = &cbcp[cbcp_unit];
|
||||
memset(us, 0, sizeof(cbcp_state));
|
||||
us->us_unit = -1;
|
||||
us->us_type |= (1 << CB_CONF_NO);
|
||||
us->us_type |= (1 << CB_CONF_USER);
|
||||
}
|
||||
|
||||
/* lower layer is up */
|
||||
static void cbcp_lowerup(int cbcp_unit)
|
||||
{
|
||||
#if 0
|
||||
cbcp_state *us = &cbcp[cbcp_unit];
|
||||
#endif
|
||||
syslog(LOG_DEBUG, "cbcp_lowerup");
|
||||
}
|
||||
|
||||
static void cbcp_lowerdown(int cbcp_unit)
|
||||
{
|
||||
syslog(LOG_DEBUG, "cbcp_lowerdown");
|
||||
}
|
||||
|
||||
static void cbcp_open(int cbcp_unit)
|
||||
{
|
||||
syslog(LOG_DEBUG, "cbcp_open");
|
||||
}
|
||||
|
||||
static void cbcp_close(int cbcp_unit,char *reason)
|
||||
{
|
||||
syslog(LOG_DEBUG, "cbcp_close: %s",reason);
|
||||
}
|
||||
|
||||
/* process an incomming packet */
|
||||
static void cbcp_input(int cbcp_unit, u_char *inpacket, int pktlen)
|
||||
{
|
||||
u_char *inp;
|
||||
u_char code, id;
|
||||
u_short len;
|
||||
|
||||
cbcp_state *us = &cbcp[cbcp_unit];
|
||||
|
||||
inp = inpacket;
|
||||
|
||||
if (pktlen < CBCP_MINLEN) {
|
||||
syslog(LOG_ERR, "CBCP packet is too small");
|
||||
return;
|
||||
}
|
||||
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
|
||||
#if 0
|
||||
if (len > pktlen) {
|
||||
syslog(LOG_ERR, "CBCP packet: invalid length");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
len -= CBCP_MINLEN;
|
||||
|
||||
switch(code) {
|
||||
case CBCP_REQ:
|
||||
us->us_id = id;
|
||||
cbcp_recvreq(us, inp, len);
|
||||
break;
|
||||
|
||||
case CBCP_RESP:
|
||||
syslog(LOG_DEBUG, "CBCP_RESP received");
|
||||
break;
|
||||
|
||||
case CBCP_ACK:
|
||||
if (id != us->us_id)
|
||||
syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d",
|
||||
us->us_id, id);
|
||||
|
||||
cbcp_recvack(us, inp, len);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* protocol was rejected by foe */
|
||||
static void cbcp_protrej(int cbcp_unit)
|
||||
{
|
||||
}
|
||||
|
||||
char *cbcp_codenames[] = {"Request", "Response", "Ack"};
|
||||
|
||||
char *cbcp_optionnames[] = { "NoCallback",
|
||||
"UserDefined",
|
||||
"AdminDefined",
|
||||
"List"};
|
||||
/* pretty print a packet */
|
||||
static int cbcp_printpkt(u_char *p, int plen,
|
||||
void (*printer) __P((void *, char *, ...)),
|
||||
void *arg)
|
||||
{
|
||||
int code, opt, id, len, olen, delay;
|
||||
u_char *pstart;
|
||||
|
||||
if (plen < HEADERLEN)
|
||||
return 0;
|
||||
pstart = p;
|
||||
GETCHAR(code, p);
|
||||
GETCHAR(id, p);
|
||||
GETSHORT(len, p);
|
||||
if (len < HEADERLEN || len > plen)
|
||||
return 0;
|
||||
|
||||
if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *))
|
||||
printer(arg, " %s", cbcp_codenames[code-1]);
|
||||
else
|
||||
printer(arg, " code=0x%x", code);
|
||||
|
||||
printer(arg, " id=0x%x", id);
|
||||
len -= HEADERLEN;
|
||||
|
||||
switch (code) {
|
||||
case CBCP_REQ:
|
||||
case CBCP_RESP:
|
||||
case CBCP_ACK:
|
||||
while(len >= 2) {
|
||||
GETCHAR(opt, p);
|
||||
GETCHAR(olen, p);
|
||||
|
||||
if (olen < 2 || olen > len) {
|
||||
break;
|
||||
}
|
||||
|
||||
printer(arg, " <");
|
||||
len -= olen;
|
||||
|
||||
if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *))
|
||||
printer(arg, " %s", cbcp_optionnames[opt-1]);
|
||||
else
|
||||
printer(arg, " option=0x%x", opt);
|
||||
|
||||
if (olen > 2) {
|
||||
GETCHAR(delay, p);
|
||||
printer(arg, " delay = %d", delay);
|
||||
}
|
||||
|
||||
if (olen > 3) {
|
||||
int addrt;
|
||||
char str[256];
|
||||
|
||||
GETCHAR(addrt, p);
|
||||
memcpy(str, p, olen - 4);
|
||||
str[olen - 4] = 0;
|
||||
printer(arg, " number = %s", str);
|
||||
}
|
||||
printer(arg, ">");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (; len > 0; --len) {
|
||||
GETCHAR(code, p);
|
||||
printer(arg, " %.2x", code);
|
||||
}
|
||||
|
||||
return p - pstart;
|
||||
}
|
||||
|
||||
/* received CBCP request */
|
||||
|
||||
void cbcp_recvreq(cbcp_state *us, char *pckt, int pcktlen)
|
||||
{
|
||||
u_char type, opt_len, delay, addr_type;
|
||||
char address[256];
|
||||
int len = pcktlen;
|
||||
|
||||
address[0] = 0;
|
||||
|
||||
while (len) {
|
||||
syslog(LOG_DEBUG, "length: %d", len);
|
||||
|
||||
GETCHAR(type, pckt);
|
||||
GETCHAR(opt_len, pckt);
|
||||
|
||||
if (opt_len > 2)
|
||||
GETCHAR(delay, pckt);
|
||||
|
||||
us->us_allowed |= (1 << type);
|
||||
|
||||
switch(type) {
|
||||
case CB_CONF_NO:
|
||||
syslog(LOG_DEBUG, "no callback allowed");
|
||||
break;
|
||||
|
||||
case CB_CONF_USER:
|
||||
syslog(LOG_DEBUG, "user callback allowed");
|
||||
if (opt_len > 4) {
|
||||
GETCHAR(addr_type, pckt);
|
||||
memcpy(address, pckt, opt_len - 4);
|
||||
address[opt_len - 4] = 0;
|
||||
if (address[0])
|
||||
syslog(LOG_DEBUG, "address: %s", address);
|
||||
}
|
||||
break;
|
||||
|
||||
case CB_CONF_ADMIN:
|
||||
syslog(LOG_DEBUG, "user admin defined allowed");
|
||||
break;
|
||||
|
||||
case CB_CONF_LIST:
|
||||
break;
|
||||
}
|
||||
len -= opt_len;
|
||||
}
|
||||
|
||||
cbcp_resp(us);
|
||||
}
|
||||
|
||||
void cbcp_resp(cbcp_state *us)
|
||||
{
|
||||
u_char cb_type;
|
||||
u_char buf[256];
|
||||
u_char *bufp = buf;
|
||||
int len = 0;
|
||||
struct cbcp *cbcp;
|
||||
|
||||
cb_type = us->us_allowed & us->us_type;
|
||||
syslog(LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type);
|
||||
cbcp = &lcp_wantoptions[ lns[us->us_unit].lcp_unit ].cbcp;
|
||||
|
||||
#if 0
|
||||
if (!cb_type)
|
||||
lcp_down( lns[us->us_unit].lcp_unit );
|
||||
#endif
|
||||
|
||||
if (cb_type & ( 1 << CB_CONF_USER ) ) {
|
||||
syslog(LOG_DEBUG, "cbcp_resp CONF_USER");
|
||||
PUTCHAR(CB_CONF_USER, bufp);
|
||||
len = 3 + 1 + strlen(cbcp->message) + 1;
|
||||
PUTCHAR(len , bufp);
|
||||
PUTCHAR(5, bufp); /* delay */
|
||||
PUTCHAR(1, bufp);
|
||||
#if 0
|
||||
BCOPY(strlen(cbcp->message), bufp, strlen(cbcp->message) + 1);
|
||||
#endif
|
||||
cbcp_send(us, CBCP_RESP, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
|
||||
PUTCHAR(CB_CONF_ADMIN, bufp);
|
||||
len = 3;
|
||||
PUTCHAR(len , bufp);
|
||||
PUTCHAR(0, bufp);
|
||||
cbcp_send(us, CBCP_RESP, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cb_type & ( 1 << CB_CONF_NO ) ) {
|
||||
syslog(LOG_DEBUG, "cbcp_resp CONF_NO");
|
||||
PUTCHAR(CB_CONF_NO, bufp);
|
||||
len = 3;
|
||||
PUTCHAR(len , bufp);
|
||||
PUTCHAR(0, bufp);
|
||||
cbcp_send(us, CBCP_RESP, buf, len);
|
||||
#if 0
|
||||
/*
|
||||
* what should we do here ... check this! */
|
||||
*/
|
||||
ipcp_open( lns[us->us_unit].ipcp_unit );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cbcp_send(cbcp_state *us, u_char code, u_char *buf, int len)
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
outp = outpacket_buf;
|
||||
|
||||
outlen = 4 + len;
|
||||
|
||||
MAKEHEADER(outp, PPP_CBCP);
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(us->us_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
|
||||
if (len)
|
||||
BCOPY(buf, outp, len);
|
||||
|
||||
output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
}
|
||||
|
||||
void cbcp_recvack(cbcp_state *us, char *pckt, int len)
|
||||
{
|
||||
u_char type, delay, addr_type;
|
||||
int opt_len;
|
||||
char address[256];
|
||||
|
||||
if (len) {
|
||||
GETCHAR(type, pckt);
|
||||
GETCHAR(opt_len, pckt);
|
||||
|
||||
if (opt_len > 2)
|
||||
GETCHAR(delay, pckt);
|
||||
|
||||
if (opt_len > 4) {
|
||||
GETCHAR(addr_type, pckt);
|
||||
memcpy(address, pckt, opt_len - 4);
|
||||
address[opt_len - 4] = 0;
|
||||
if (address[0])
|
||||
syslog(LOG_DEBUG, "peer will call: %s", address);
|
||||
}
|
||||
}
|
||||
|
||||
cbcp_up(us);
|
||||
}
|
||||
|
||||
/* ok peer will do callback */
|
||||
void cbcp_up(cbcp_state *us)
|
||||
{
|
||||
int linkunit = us->us_unit;
|
||||
lcp_close( lns[linkunit].lcp_unit ,"callback initiated sucessfully");
|
||||
lns[linkunit].phase = PHASE_TERMINATE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef CBCP_H
|
||||
#define CBCP_H
|
||||
|
||||
typedef struct cbcp_state {
|
||||
int us_unit; /* Interface unit number */
|
||||
u_char us_id; /* Current id */
|
||||
int us_type;
|
||||
int us_allowed;
|
||||
} cbcp_state;
|
||||
|
||||
extern struct protent cbcp_protent;
|
||||
|
||||
extern cbcp_state cbcp[];
|
||||
|
||||
#define CBCP_MINLEN 4
|
||||
|
||||
#define CBCP_REQ 1
|
||||
#define CBCP_RESP 2
|
||||
#define CBCP_ACK 3
|
||||
|
||||
#define CB_CONF_NO 1
|
||||
#define CB_CONF_USER 2
|
||||
#define CB_CONF_ADMIN 3
|
||||
#define CB_CONF_LIST 4
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* ccp.h - Definitions for PPP Compression Control Protocol.
|
||||
*
|
||||
* Copyright (c) 1994 The Australian National University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, provided that the above copyright
|
||||
* notice appears in all copies. This software is provided without any
|
||||
* warranty, express or implied. The Australian National University
|
||||
* makes no representations about the suitability of this software for
|
||||
* any purpose.
|
||||
*
|
||||
* IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
|
||||
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
|
||||
* THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
|
||||
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
||||
* OR MODIFICATIONS.
|
||||
*
|
||||
* $Id: ccp.h,v 1.1 1997/03/07 16:01:11 hipp Exp $
|
||||
*/
|
||||
|
||||
typedef struct ccp_options {
|
||||
u_int bsd_compress: 1; /* do BSD Compress? */
|
||||
u_int deflate: 1; /* do Deflate? */
|
||||
u_int predictor_1: 1; /* do Predictor-1? */
|
||||
u_int predictor_2: 1; /* do Predictor-2? */
|
||||
u_short bsd_bits; /* # bits/code for BSD Compress */
|
||||
u_short deflate_size; /* lg(window size) for Deflate */
|
||||
short method; /* code for chosen compression method */
|
||||
} ccp_options;
|
||||
|
||||
extern fsm ccp_fsm[];
|
||||
extern ccp_options ccp_wantoptions[];
|
||||
extern ccp_options ccp_gotoptions[];
|
||||
extern ccp_options ccp_allowoptions[];
|
||||
extern ccp_options ccp_hisoptions[];
|
||||
|
||||
extern struct protent ccp_protent;
|
||||
|
|
@ -0,0 +1,843 @@
|
|||
/*
|
||||
* chap.c - Crytographic Handshake Authentication Protocol.
|
||||
*
|
||||
* Copyright (c) 1991 Gregory M. Christy.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Gregory M. Christy. The name of the author may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: chap.c,v 1.1 1997/03/07 16:01:12 hipp Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "fsm.h"
|
||||
#include "pppd.h"
|
||||
#include "chap.h"
|
||||
#ifdef USE_MSCHAP
|
||||
#include "chap_ms.h"
|
||||
#endif /* USE_MSCHAP */
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
* Protocol entry points.
|
||||
*/
|
||||
static void ChapInit __P((int));
|
||||
static void ChapLowerUp __P((int));
|
||||
static void ChapLowerDown __P((int));
|
||||
static void ChapInput __P((int, u_char *, int));
|
||||
static void ChapProtocolReject __P((int));
|
||||
static int ChapPrintPkt __P((u_char *, int,
|
||||
void (*) __P((void *, char *, ...)), void *));
|
||||
|
||||
struct protent chap_protent = {
|
||||
PPP_CHAP,
|
||||
ChapInit,
|
||||
ChapInput,
|
||||
ChapProtocolReject,
|
||||
ChapLowerUp,
|
||||
ChapLowerDown,
|
||||
NULL,
|
||||
NULL,
|
||||
ChapPrintPkt,
|
||||
NULL,
|
||||
1,
|
||||
"CHAP",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
|
||||
|
||||
static void ChapChallengeTimeout __P((caddr_t));
|
||||
static void ChapResponseTimeout __P((caddr_t));
|
||||
static void ChapReceiveChallenge __P((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveResponse __P((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveSuccess __P((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveFailure __P((chap_state *, u_char *, int, int));
|
||||
static void ChapSendStatus __P((chap_state *, int));
|
||||
static void ChapSendChallenge __P((chap_state *));
|
||||
static void ChapSendResponse __P((chap_state *));
|
||||
static void ChapGenChallenge __P((chap_state *));
|
||||
|
||||
extern double drand48 __P((void));
|
||||
extern void srand48 __P((long));
|
||||
|
||||
/*
|
||||
* ChapInit - Initialize a CHAP unit.
|
||||
*/
|
||||
void
|
||||
ChapInit(unit)
|
||||
int unit;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
BZERO(cstate, sizeof(*cstate));
|
||||
cstate->unit = unit;
|
||||
cstate->clientstate = CHAPCS_INITIAL;
|
||||
cstate->serverstate = CHAPSS_INITIAL;
|
||||
cstate->timeouttime = CHAP_DEFTIMEOUT;
|
||||
cstate->max_transmits = CHAP_DEFTRANSMITS;
|
||||
/* random number generator is initialized in magic_init */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapAuthWithPeer - Authenticate us with our peer (start client).
|
||||
*
|
||||
*/
|
||||
void
|
||||
ChapAuthWithPeer(unit, our_name, digest)
|
||||
int unit;
|
||||
char *our_name;
|
||||
int digest;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
cstate->resp_name = our_name;
|
||||
cstate->resp_type = digest;
|
||||
|
||||
if (cstate->clientstate == CHAPCS_INITIAL ||
|
||||
cstate->clientstate == CHAPCS_PENDING) {
|
||||
/* lower layer isn't up - wait until later */
|
||||
cstate->clientstate = CHAPCS_PENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We get here as a result of LCP coming up.
|
||||
* So even if CHAP was open before, we will
|
||||
* have to re-authenticate ourselves.
|
||||
*/
|
||||
cstate->clientstate = CHAPCS_LISTEN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapAuthPeer - Authenticate our peer (start server).
|
||||
*/
|
||||
void
|
||||
ChapAuthPeer(unit, our_name, digest)
|
||||
int unit;
|
||||
char *our_name;
|
||||
int digest;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
cstate->chal_name = our_name;
|
||||
cstate->chal_type = digest;
|
||||
|
||||
if (cstate->serverstate == CHAPSS_INITIAL ||
|
||||
cstate->serverstate == CHAPSS_PENDING) {
|
||||
/* lower layer isn't up - wait until later */
|
||||
cstate->serverstate = CHAPSS_PENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
ChapGenChallenge(cstate);
|
||||
ChapSendChallenge(cstate); /* crank it up dude! */
|
||||
cstate->serverstate = CHAPSS_INITIAL_CHAL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapChallengeTimeout - Timeout expired on sending challenge.
|
||||
*/
|
||||
static void
|
||||
ChapChallengeTimeout(arg)
|
||||
caddr_t arg;
|
||||
{
|
||||
chap_state *cstate = (chap_state *) arg;
|
||||
|
||||
/* if we aren't sending challenges, don't worry. then again we */
|
||||
/* probably shouldn't be here either */
|
||||
if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
|
||||
cstate->serverstate != CHAPSS_RECHALLENGE)
|
||||
return;
|
||||
|
||||
if (cstate->chal_transmits >= cstate->max_transmits) {
|
||||
/* give up on peer */
|
||||
syslog(LOG_ERR, "Peer failed to respond to CHAP challenge");
|
||||
cstate->serverstate = CHAPSS_BADAUTH;
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
return;
|
||||
}
|
||||
|
||||
ChapSendChallenge(cstate); /* Re-send challenge */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapResponseTimeout - Timeout expired on sending response.
|
||||
*/
|
||||
static void
|
||||
ChapResponseTimeout(arg)
|
||||
caddr_t arg;
|
||||
{
|
||||
chap_state *cstate = (chap_state *) arg;
|
||||
|
||||
/* if we aren't sending a response, don't worry. */
|
||||
if (cstate->clientstate != CHAPCS_RESPONSE)
|
||||
return;
|
||||
|
||||
ChapSendResponse(cstate); /* re-send response */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapRechallenge - Time to challenge the peer again.
|
||||
*/
|
||||
static void
|
||||
ChapRechallenge(arg)
|
||||
caddr_t arg;
|
||||
{
|
||||
chap_state *cstate = (chap_state *) arg;
|
||||
|
||||
/* if we aren't sending a response, don't worry. */
|
||||
if (cstate->serverstate != CHAPSS_OPEN)
|
||||
return;
|
||||
|
||||
ChapGenChallenge(cstate);
|
||||
ChapSendChallenge(cstate);
|
||||
cstate->serverstate = CHAPSS_RECHALLENGE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapLowerUp - The lower layer is up.
|
||||
*
|
||||
* Start up if we have pending requests.
|
||||
*/
|
||||
void
|
||||
ChapLowerUp(unit)
|
||||
int unit;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
if (cstate->clientstate == CHAPCS_INITIAL)
|
||||
cstate->clientstate = CHAPCS_CLOSED;
|
||||
else if (cstate->clientstate == CHAPCS_PENDING)
|
||||
cstate->clientstate = CHAPCS_LISTEN;
|
||||
|
||||
if (cstate->serverstate == CHAPSS_INITIAL)
|
||||
cstate->serverstate = CHAPSS_CLOSED;
|
||||
else if (cstate->serverstate == CHAPSS_PENDING) {
|
||||
ChapGenChallenge(cstate);
|
||||
ChapSendChallenge(cstate);
|
||||
cstate->serverstate = CHAPSS_INITIAL_CHAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapLowerDown - The lower layer is down.
|
||||
*
|
||||
* Cancel all timeouts.
|
||||
*/
|
||||
void
|
||||
ChapLowerDown(unit)
|
||||
int unit;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
/* Timeout(s) pending? Cancel if so. */
|
||||
if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
|
||||
cstate->serverstate == CHAPSS_RECHALLENGE)
|
||||
UNTIMEOUT(ChapChallengeTimeout, (caddr_t) cstate);
|
||||
else if (cstate->serverstate == CHAPSS_OPEN
|
||||
&& cstate->chal_interval != 0)
|
||||
UNTIMEOUT(ChapRechallenge, (caddr_t) cstate);
|
||||
if (cstate->clientstate == CHAPCS_RESPONSE)
|
||||
UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate);
|
||||
|
||||
cstate->clientstate = CHAPCS_INITIAL;
|
||||
cstate->serverstate = CHAPSS_INITIAL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapProtocolReject - Peer doesn't grok CHAP.
|
||||
*/
|
||||
void ChapProtocolReject(int linkunit)
|
||||
{
|
||||
int unit = lns[linkunit].chap_unit;
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
if (cstate->serverstate != CHAPSS_INITIAL &&
|
||||
cstate->serverstate != CHAPSS_CLOSED)
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
if (cstate->clientstate != CHAPCS_INITIAL &&
|
||||
cstate->clientstate != CHAPCS_CLOSED)
|
||||
auth_withpeer_fail(cstate->unit, PPP_CHAP);
|
||||
ChapLowerDown(unit); /* shutdown chap */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapInput - Input CHAP packet.
|
||||
*/
|
||||
void ChapInput(int linkunit,u_char *inpacket,int packet_len)
|
||||
{
|
||||
int unit = lns[linkunit].chap_unit;
|
||||
chap_state *cstate = &chap[unit];
|
||||
u_char *inp;
|
||||
u_char code, id;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Parse header (code, id and length).
|
||||
* If packet too short, drop it.
|
||||
*/
|
||||
inp = inpacket;
|
||||
if (packet_len < CHAP_HEADERLEN) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < CHAP_HEADERLEN) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length."));
|
||||
return;
|
||||
}
|
||||
if (len > packet_len) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
len -= CHAP_HEADERLEN;
|
||||
|
||||
/*
|
||||
* Action depends on code (as in fact it usually does :-).
|
||||
*/
|
||||
switch (code) {
|
||||
case CHAP_CHALLENGE:
|
||||
ChapReceiveChallenge(cstate, inp, id, len);
|
||||
break;
|
||||
|
||||
case CHAP_RESPONSE:
|
||||
ChapReceiveResponse(cstate, inp, id, len);
|
||||
break;
|
||||
|
||||
case CHAP_FAILURE:
|
||||
ChapReceiveFailure(cstate, inp, id, len);
|
||||
break;
|
||||
|
||||
case CHAP_SUCCESS:
|
||||
ChapReceiveSuccess(cstate, inp, id, len);
|
||||
break;
|
||||
|
||||
default: /* Need code reject? */
|
||||
syslog(LOG_WARNING, "Unknown CHAP code (%d) received.", code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapReceiveChallenge - Receive Challenge and send Response.
|
||||
*/
|
||||
static void
|
||||
ChapReceiveChallenge(cstate, inp, id, len)
|
||||
chap_state *cstate;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
int rchallenge_len;
|
||||
u_char *rchallenge;
|
||||
int secret_len;
|
||||
char secret[MAXSECRETLEN];
|
||||
char rhostname[256];
|
||||
MD5_CTX mdContext;
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.", id));
|
||||
if (cstate->clientstate == CHAPCS_CLOSED ||
|
||||
cstate->clientstate == CHAPCS_PENDING) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < 2) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
|
||||
GETCHAR(rchallenge_len, inp);
|
||||
len -= sizeof (u_char) + rchallenge_len; /* now name field length */
|
||||
if (len < 0) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
rchallenge = inp;
|
||||
INCPTR(rchallenge_len, inp);
|
||||
|
||||
if (len >= sizeof(rhostname))
|
||||
len = sizeof(rhostname) - 1;
|
||||
BCOPY(inp, rhostname, len);
|
||||
rhostname[len] = '\000';
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field: '%s'",
|
||||
rhostname));
|
||||
|
||||
#ifdef USE_MSCHAP
|
||||
/* Microsoft doesn't send their name back in the PPP packet */
|
||||
if (!rhostname[0] && cstate->resp_type == CHAP_MICROSOFT) {
|
||||
extern char remote_name[];
|
||||
strcpy(rhostname, remote_name);
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name", rhostname));
|
||||
}
|
||||
#endif /* USE_MSCHAP */
|
||||
|
||||
/* get secret for authenticating ourselves with the specified host */
|
||||
if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
|
||||
secret, &secret_len, 0)) {
|
||||
secret_len = 0; /* assume null secret if can't find one */
|
||||
syslog(LOG_WARNING, "No CHAP secret found for authenticating us to %s",
|
||||
rhostname);
|
||||
}
|
||||
|
||||
/* cancel response send timeout if necessary */
|
||||
if (cstate->clientstate == CHAPCS_RESPONSE)
|
||||
UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate);
|
||||
|
||||
cstate->resp_id = id;
|
||||
cstate->resp_transmits = 0;
|
||||
|
||||
/* generate MD based on negotiated type */
|
||||
switch (cstate->resp_type) {
|
||||
|
||||
case CHAP_DIGEST_MD5:
|
||||
MD5Init(&mdContext);
|
||||
MD5Update(&mdContext, &cstate->resp_id, 1);
|
||||
MD5Update(&mdContext, secret, secret_len);
|
||||
MD5Update(&mdContext, rchallenge, rchallenge_len);
|
||||
MD5Final(&mdContext);
|
||||
BCOPY(mdContext.digest, cstate->response, MD5_SIGNATURE_SIZE);
|
||||
cstate->resp_length = MD5_SIGNATURE_SIZE;
|
||||
break;
|
||||
#ifdef USE_MSCHAP
|
||||
case CHAP_MICROSOFT:
|
||||
ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
|
||||
break;
|
||||
#endif /* USE_MSCHAP */
|
||||
|
||||
default:
|
||||
CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->resp_type));
|
||||
return;
|
||||
}
|
||||
|
||||
ChapSendResponse(cstate);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapReceiveResponse - Receive and process response.
|
||||
*/
|
||||
static void
|
||||
ChapReceiveResponse(cstate, inp, id, len)
|
||||
chap_state *cstate;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
u_char *remmd, remmd_len;
|
||||
int secret_len, old_state;
|
||||
int code;
|
||||
char rhostname[256];
|
||||
MD5_CTX mdContext;
|
||||
char secret[MAXSECRETLEN];
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.", id));
|
||||
|
||||
if (cstate->serverstate == CHAPSS_CLOSED ||
|
||||
cstate->serverstate == CHAPSS_PENDING) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d",
|
||||
cstate->serverstate));
|
||||
return;
|
||||
}
|
||||
|
||||
if (id != cstate->chal_id)
|
||||
return; /* doesn't match ID of last challenge */
|
||||
|
||||
/*
|
||||
* If we have received a duplicate or bogus Response,
|
||||
* we have to send the same answer (Success/Failure)
|
||||
* as we did for the first Response we saw.
|
||||
*/
|
||||
if (cstate->serverstate == CHAPSS_OPEN) {
|
||||
ChapSendStatus(cstate, CHAP_SUCCESS);
|
||||
return;
|
||||
}
|
||||
if (cstate->serverstate == CHAPSS_BADAUTH) {
|
||||
ChapSendStatus(cstate, CHAP_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < 2) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(remmd_len, inp); /* get length of MD */
|
||||
remmd = inp; /* get pointer to MD */
|
||||
INCPTR(remmd_len, inp);
|
||||
|
||||
len -= sizeof (u_char) + remmd_len;
|
||||
if (len < 0) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
|
||||
UNTIMEOUT(ChapChallengeTimeout, (caddr_t) cstate);
|
||||
|
||||
if (len >= sizeof(rhostname))
|
||||
len = sizeof(rhostname) - 1;
|
||||
BCOPY(inp, rhostname, len);
|
||||
rhostname[len] = '\000';
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s",
|
||||
rhostname));
|
||||
|
||||
/*
|
||||
* Get secret for authenticating them with us,
|
||||
* do the hash ourselves, and compare the result.
|
||||
*/
|
||||
code = CHAP_FAILURE;
|
||||
if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
|
||||
secret, &secret_len, 1)) {
|
||||
syslog(LOG_WARNING, "No CHAP secret found for authenticating %s",
|
||||
rhostname);
|
||||
} else {
|
||||
|
||||
/* generate MD based on negotiated type */
|
||||
switch (cstate->chal_type) {
|
||||
|
||||
case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
|
||||
if (remmd_len != MD5_SIGNATURE_SIZE)
|
||||
break; /* it's not even the right length */
|
||||
MD5Init(&mdContext);
|
||||
MD5Update(&mdContext, &cstate->chal_id, 1);
|
||||
MD5Update(&mdContext, secret, secret_len);
|
||||
MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
|
||||
MD5Final(&mdContext);
|
||||
|
||||
/* compare local and remote MDs and send the appropriate status */
|
||||
if (memcmp (mdContext.digest, remmd, MD5_SIGNATURE_SIZE) == 0)
|
||||
code = CHAP_SUCCESS; /* they are the same! */
|
||||
break;
|
||||
|
||||
default:
|
||||
CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->chal_type));
|
||||
}
|
||||
}
|
||||
|
||||
ChapSendStatus(cstate, code);
|
||||
|
||||
if (code == CHAP_SUCCESS) {
|
||||
old_state = cstate->serverstate;
|
||||
cstate->serverstate = CHAPSS_OPEN;
|
||||
if (old_state == CHAPSS_INITIAL_CHAL) {
|
||||
auth_peer_success(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
if (cstate->chal_interval != 0)
|
||||
TIMEOUT(ChapRechallenge, (caddr_t) cstate, cstate->chal_interval);
|
||||
|
||||
} else {
|
||||
syslog(LOG_ERR, "CHAP peer authentication failed");
|
||||
cstate->serverstate = CHAPSS_BADAUTH;
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ChapReceiveSuccess - Receive Success
|
||||
*/
|
||||
static void
|
||||
ChapReceiveSuccess(cstate, inp, id, len)
|
||||
chap_state *cstate;
|
||||
u_char *inp;
|
||||
u_char id;
|
||||
int len;
|
||||
{
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.", id));
|
||||
|
||||
if (cstate->clientstate == CHAPCS_OPEN)
|
||||
/* presumably an answer to a duplicate response */
|
||||
return;
|
||||
|
||||
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
||||
/* don't know what this is */
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate);
|
||||
|
||||
/*
|
||||
* Print message.
|
||||
*/
|
||||
if (len > 0)
|
||||
PRINTMSG(inp, len);
|
||||
|
||||
cstate->clientstate = CHAPCS_OPEN;
|
||||
|
||||
auth_withpeer_success(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapReceiveFailure - Receive failure.
|
||||
*/
|
||||
static void
|
||||
ChapReceiveFailure(cstate, inp, id, len)
|
||||
chap_state *cstate;
|
||||
u_char *inp;
|
||||
u_char id;
|
||||
int len;
|
||||
{
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.", id));
|
||||
|
||||
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
||||
/* don't know what this is */
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate);
|
||||
|
||||
/*
|
||||
* Print message.
|
||||
*/
|
||||
if (len > 0)
|
||||
PRINTMSG(inp, len);
|
||||
|
||||
syslog(LOG_ERR, "CHAP authentication failed");
|
||||
auth_withpeer_fail(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapSendChallenge - Send an Authenticate challenge.
|
||||
*/
|
||||
static void
|
||||
ChapSendChallenge(cstate)
|
||||
chap_state *cstate;
|
||||
{
|
||||
u_char *outp;
|
||||
int chal_len, name_len;
|
||||
int outlen;
|
||||
|
||||
chal_len = cstate->chal_len;
|
||||
name_len = strlen(cstate->chal_name);
|
||||
outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */
|
||||
|
||||
PUTCHAR(CHAP_CHALLENGE, outp);
|
||||
PUTCHAR(cstate->chal_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
|
||||
PUTCHAR(chal_len, outp); /* put length of challenge */
|
||||
BCOPY(cstate->challenge, outp, chal_len);
|
||||
INCPTR(chal_len, outp);
|
||||
|
||||
BCOPY(cstate->chal_name, outp, name_len); /* append hostname */
|
||||
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.", cstate->chal_id));
|
||||
|
||||
TIMEOUT(ChapChallengeTimeout, (caddr_t) cstate, cstate->timeouttime);
|
||||
++cstate->chal_transmits;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapSendStatus - Send a status response (ack or nak).
|
||||
*/
|
||||
static void
|
||||
ChapSendStatus(cstate, code)
|
||||
chap_state *cstate;
|
||||
int code;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen, msglen;
|
||||
char msg[256];
|
||||
|
||||
if (code == CHAP_SUCCESS)
|
||||
sprintf(msg, "Welcome to %s.", hostname);
|
||||
else
|
||||
sprintf(msg, "I don't like you. Go 'way.");
|
||||
msglen = strlen(msg);
|
||||
|
||||
outlen = CHAP_HEADERLEN + msglen;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(cstate->chal_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
BCOPY(msg, outp, msglen);
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.", code,
|
||||
cstate->chal_id));
|
||||
}
|
||||
|
||||
/*
|
||||
* ChapGenChallenge is used to generate a pseudo-random challenge string of
|
||||
* a pseudo-random length between min_len and max_len. The challenge
|
||||
* string and its length are stored in *cstate, and various other fields of
|
||||
* *cstate are initialized.
|
||||
*/
|
||||
|
||||
static void
|
||||
ChapGenChallenge(cstate)
|
||||
chap_state *cstate;
|
||||
{
|
||||
int chal_len;
|
||||
u_char *ptr = cstate->challenge;
|
||||
unsigned int i;
|
||||
|
||||
/* pick a random challenge length between MIN_CHALLENGE_LENGTH and
|
||||
MAX_CHALLENGE_LENGTH */
|
||||
chal_len = (unsigned) ((drand48() *
|
||||
(MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
|
||||
MIN_CHALLENGE_LENGTH);
|
||||
cstate->chal_len = chal_len;
|
||||
cstate->chal_id = ++cstate->id;
|
||||
cstate->chal_transmits = 0;
|
||||
|
||||
/* generate a random string */
|
||||
for (i = 0; i < chal_len; i++ )
|
||||
*ptr++ = (char) (drand48() * 0xff);
|
||||
}
|
||||
|
||||
/*
|
||||
* ChapSendResponse - send a response packet with values as specified
|
||||
* in *cstate.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ChapSendResponse(cstate)
|
||||
chap_state *cstate;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen, md_len, name_len;
|
||||
|
||||
md_len = cstate->resp_length;
|
||||
name_len = strlen(cstate->resp_name);
|
||||
outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP);
|
||||
|
||||
PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */
|
||||
PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
|
||||
PUTSHORT(outlen, outp); /* packet length */
|
||||
|
||||
PUTCHAR(md_len, outp); /* length of MD */
|
||||
BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */
|
||||
INCPTR(md_len, outp);
|
||||
|
||||
BCOPY(cstate->resp_name, outp, name_len); /* append our name */
|
||||
|
||||
/* send the packet */
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
cstate->clientstate = CHAPCS_RESPONSE;
|
||||
TIMEOUT(ChapResponseTimeout, (caddr_t) cstate, cstate->timeouttime);
|
||||
++cstate->resp_transmits;
|
||||
}
|
||||
|
||||
/*
|
||||
* ChapPrintPkt - print the contents of a CHAP packet.
|
||||
*/
|
||||
char *ChapCodenames[] = {
|
||||
"Challenge", "Response", "Success", "Failure"
|
||||
};
|
||||
|
||||
int
|
||||
ChapPrintPkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
int code, id, len;
|
||||
int clen, nlen;
|
||||
u_char x;
|
||||
|
||||
if (plen < CHAP_HEADERLEN)
|
||||
return 0;
|
||||
GETCHAR(code, p);
|
||||
GETCHAR(id, p);
|
||||
GETSHORT(len, p);
|
||||
if (len < CHAP_HEADERLEN || len > plen)
|
||||
return 0;
|
||||
|
||||
if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))
|
||||
printer(arg, " %s", ChapCodenames[code-1]);
|
||||
else
|
||||
printer(arg, " code=0x%x", code);
|
||||
printer(arg, " id=0x%x", id);
|
||||
len -= CHAP_HEADERLEN;
|
||||
switch (code) {
|
||||
case CHAP_CHALLENGE:
|
||||
case CHAP_RESPONSE:
|
||||
if (len < 1)
|
||||
break;
|
||||
clen = p[0];
|
||||
if (len < clen + 1)
|
||||
break;
|
||||
++p;
|
||||
nlen = len - clen - 1;
|
||||
printer(arg, " <");
|
||||
for (; clen > 0; --clen) {
|
||||
GETCHAR(x, p);
|
||||
printer(arg, "%.2x", x);
|
||||
}
|
||||
printer(arg, ">, name = ");
|
||||
print_string((char *)p, nlen, printer, arg);
|
||||
break;
|
||||
case CHAP_FAILURE:
|
||||
case CHAP_SUCCESS:
|
||||
printer(arg, " ");
|
||||
print_string((char *)p, len, printer, arg);
|
||||
break;
|
||||
default:
|
||||
for (clen = len; clen > 0; --clen) {
|
||||
GETCHAR(x, p);
|
||||
printer(arg, " %.2x", x);
|
||||
}
|
||||
}
|
||||
|
||||
return len + CHAP_HEADERLEN;
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* chap.h - Cryptographic Handshake Authentication Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1991 Gregory M. Christy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the author.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap.h,v 1.1 1997/03/07 16:01:13 hipp Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CHAP_INCLUDE__
|
||||
|
||||
/* Code + ID + length */
|
||||
#define CHAP_HEADERLEN 4
|
||||
|
||||
/*
|
||||
* CHAP codes.
|
||||
*/
|
||||
|
||||
#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */
|
||||
#define CHAP_MICROSOFT 0x80 /* Use vendor specific:Microsoft */
|
||||
#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */
|
||||
|
||||
#define CHAP_CHALLENGE 1
|
||||
#define CHAP_RESPONSE 2
|
||||
#define CHAP_SUCCESS 3
|
||||
#define CHAP_FAILURE 4
|
||||
|
||||
/*
|
||||
* Challenge lengths (for challenges we send) and other limits.
|
||||
*/
|
||||
#define MIN_CHALLENGE_LENGTH 32
|
||||
#define MAX_CHALLENGE_LENGTH 64
|
||||
#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 and MSCHAP */
|
||||
|
||||
/*
|
||||
* Each interface is described by a chap structure.
|
||||
*/
|
||||
|
||||
typedef struct chap_state {
|
||||
int unit; /* Interface unit number */
|
||||
int clientstate; /* Client state */
|
||||
int serverstate; /* Server state */
|
||||
u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */
|
||||
u_char chal_len; /* challenge length */
|
||||
u_char chal_id; /* ID of last challenge */
|
||||
u_char chal_type; /* hash algorithm for challenges */
|
||||
u_char id; /* Current id */
|
||||
char *chal_name; /* Our name to use with challenge */
|
||||
int chal_interval; /* Time until we challenge peer again */
|
||||
int timeouttime; /* Timeout time in seconds */
|
||||
int max_transmits; /* Maximum # of challenge transmissions */
|
||||
int chal_transmits; /* Number of transmissions of challenge */
|
||||
int resp_transmits; /* Number of transmissions of response */
|
||||
u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */
|
||||
u_char resp_length; /* length of response */
|
||||
u_char resp_id; /* ID for response messages */
|
||||
u_char resp_type; /* hash algorithm for responses */
|
||||
char *resp_name; /* Our name to send with response */
|
||||
} chap_state;
|
||||
|
||||
|
||||
/*
|
||||
* Client (peer) states.
|
||||
*/
|
||||
#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */
|
||||
#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */
|
||||
#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */
|
||||
#define CHAPCS_LISTEN 3 /* Listening for a challenge */
|
||||
#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */
|
||||
#define CHAPCS_OPEN 5 /* We've received Success */
|
||||
|
||||
/*
|
||||
* Server (authenticator) states.
|
||||
*/
|
||||
#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */
|
||||
#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */
|
||||
#define CHAPSS_PENDING 2 /* Auth peer when lower up */
|
||||
#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */
|
||||
#define CHAPSS_OPEN 4 /* We've sent a Success msg */
|
||||
#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */
|
||||
#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */
|
||||
|
||||
/*
|
||||
* Timeouts.
|
||||
*/
|
||||
#define CHAP_DEFTIMEOUT 3 /* Timeout time in seconds */
|
||||
#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */
|
||||
|
||||
extern chap_state chap[];
|
||||
extern struct protent chap_protent;
|
||||
|
||||
void ChapAuthWithPeer __P((int, char *, int));
|
||||
void ChapAuthPeer __P((int, char *, int));
|
||||
|
||||
#define __CHAP_INCLUDE__
|
||||
#endif /* __CHAP_INCLUDE__ */
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* chap_ms.c - Microsoft MS-CHAP compatible implementation.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||
* http://www.strataware.com/
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Eric Rosenquist. The name of the author may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifdef USE_MSCHAP
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: chap_ms.c,v 1.1 1997/03/07 16:01:14 hipp Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "chap.h"
|
||||
#include "chap_ms.h"
|
||||
#include "md4.h"
|
||||
|
||||
#include <des.h>
|
||||
|
||||
typedef struct {
|
||||
u_char LANManResp[24];
|
||||
u_char NTResp[24];
|
||||
u_char UseNT; /* If 1, ignore the LANMan response field */
|
||||
} MS_ChapResponse;
|
||||
#define MS_CHAP_RESPONSE_LEN 49 /* Don't rely on sizeof(MS_ChapResponse) in case of struct padding */
|
||||
|
||||
|
||||
static void DesEncrypt __P((u_char *, u_char *, u_char *));
|
||||
static void MakeKey __P((u_char *, u_char *));
|
||||
|
||||
static void
|
||||
ChallengeResponse(challenge, pwHash, response)
|
||||
u_char *challenge; /* IN 8 octets */
|
||||
u_char *pwHash; /* IN 16 octets */
|
||||
u_char *response; /* OUT 24 octets */
|
||||
{
|
||||
char ZPasswordHash[21];
|
||||
|
||||
BZERO(ZPasswordHash, sizeof(ZPasswordHash));
|
||||
BCOPY(pwHash, ZPasswordHash, 16);
|
||||
|
||||
#if 0
|
||||
log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash");
|
||||
#endif
|
||||
|
||||
DesEncrypt(challenge, ZPasswordHash + 0, response + 0);
|
||||
DesEncrypt(challenge, ZPasswordHash + 7, response + 8);
|
||||
DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
|
||||
|
||||
#if 0
|
||||
log_packet(response, 24, "ChallengeResponse - response");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DesEncrypt(clear, key, cipher)
|
||||
u_char *clear; /* IN 8 octets */
|
||||
u_char *key; /* IN 7 octets */
|
||||
u_char *cipher; /* OUT 8 octets */
|
||||
{
|
||||
des_cblock des_key;
|
||||
des_key_schedule key_schedule;
|
||||
|
||||
MakeKey(key, des_key);
|
||||
|
||||
des_set_key(&des_key, key_schedule);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
|
||||
#endif
|
||||
|
||||
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static u_char Get7Bits(input, startBit)
|
||||
u_char *input;
|
||||
int startBit;
|
||||
{
|
||||
register unsigned int word;
|
||||
|
||||
word = (unsigned)input[startBit / 8] << 8;
|
||||
word |= (unsigned)input[startBit / 8 + 1];
|
||||
|
||||
word >>= 15 - (startBit % 8 + 7);
|
||||
|
||||
return word & 0xFE;
|
||||
}
|
||||
|
||||
|
||||
static void MakeKey(key, des_key)
|
||||
u_char *key; /* IN 56 bit DES key missing parity bits */
|
||||
u_char *des_key; /* OUT 64 bit DES key with parity bits added */
|
||||
{
|
||||
des_key[0] = Get7Bits(key, 0);
|
||||
des_key[1] = Get7Bits(key, 7);
|
||||
des_key[2] = Get7Bits(key, 14);
|
||||
des_key[3] = Get7Bits(key, 21);
|
||||
des_key[4] = Get7Bits(key, 28);
|
||||
des_key[5] = Get7Bits(key, 35);
|
||||
des_key[6] = Get7Bits(key, 42);
|
||||
des_key[7] = Get7Bits(key, 49);
|
||||
|
||||
des_set_odd_parity((des_cblock *)des_key);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X",
|
||||
key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
|
||||
CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_MSCHAP */
|
||||
|
||||
void
|
||||
ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len)
|
||||
chap_state *cstate;
|
||||
char *rchallenge;
|
||||
int rchallenge_len;
|
||||
char *secret;
|
||||
int secret_len;
|
||||
{
|
||||
#ifdef USE_MSCHAP
|
||||
int i;
|
||||
MDstruct md4Context;
|
||||
MS_ChapResponse response;
|
||||
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret));
|
||||
#endif
|
||||
|
||||
BZERO(&response, sizeof(response));
|
||||
|
||||
/* Initialize the Unicode version of the secret (== password). */
|
||||
/* This implicitly supports 8-bit ISO8859/1 characters. */
|
||||
BZERO(unicodePassword, sizeof(unicodePassword));
|
||||
for (i = 0; i < secret_len; i++)
|
||||
unicodePassword[i * 2] = (u_char)secret[i];
|
||||
|
||||
MDbegin(&md4Context);
|
||||
MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */
|
||||
MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */
|
||||
|
||||
ChallengeResponse(rchallenge, (char *)md4Context.buffer, response.NTResp);
|
||||
|
||||
response.UseNT = 1;
|
||||
|
||||
BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
|
||||
cstate->resp_length = MS_CHAP_RESPONSE_LEN;
|
||||
#endif /* USE_MSCHAP */
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* chap.h - Cryptographic Handshake Authentication Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||
* http://www.strataware.com/
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Eric Rosenquist. The name of the author may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap_ms.h,v 1.1 1997/03/07 16:01:15 hipp Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CHAPMS_INCLUDE__
|
||||
|
||||
#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */
|
||||
|
||||
void ChapMS __P((chap_state *, char *, int, char *, int));
|
||||
|
||||
#define __CHAPMS_INCLUDE__
|
||||
#endif /* __CHAPMS_INCLUDE__ */
|
|
@ -0,0 +1,747 @@
|
|||
/*
|
||||
* fsm.c - {Link, IP} Control Protocol Finite State Machine.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: fsm.c,v 1.1 1997/03/07 16:01:15 hipp Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* Randomize fsm id on link/init.
|
||||
* Deal with variable outgoing MTU.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "fsm.h"
|
||||
#include "pppd.h"
|
||||
#include "lcp.h"
|
||||
|
||||
extern char *proto_name();
|
||||
|
||||
static void fsm_timeout __P((caddr_t));
|
||||
static void fsm_rconfreq __P((fsm *, int, u_char *, int));
|
||||
static void fsm_rconfack __P((fsm *, int, u_char *, int));
|
||||
static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int));
|
||||
static void fsm_rtermreq __P((fsm *, int, u_char *, int));
|
||||
static void fsm_rtermack __P((fsm *));
|
||||
static void fsm_rcoderej __P((fsm *, u_char *, int));
|
||||
static void fsm_sconfreq __P((fsm *, int));
|
||||
|
||||
#define PROTO_NAME(f) ((f)->callbacks->proto_name)
|
||||
|
||||
/*
|
||||
* fsm_init - Initialize fsm.
|
||||
*
|
||||
* Initialize fsm state.
|
||||
*/
|
||||
void fsm_init(fsm *f)
|
||||
{
|
||||
f->state = INITIAL;
|
||||
f->flags = 0;
|
||||
f->id = 0; /* XXX Start with random id? */
|
||||
f->timeouttime = DEFTIMEOUT;
|
||||
f->maxconfreqtransmits = DEFMAXCONFREQS;
|
||||
f->maxtermtransmits = DEFMAXTERMREQS;
|
||||
f->maxnakloops = DEFMAXNAKLOOPS;
|
||||
f->term_reason_len = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_lowerup - The lower layer is up.
|
||||
*/
|
||||
void fsm_lowerup(fsm *f)
|
||||
{
|
||||
switch( f->state ){
|
||||
case INITIAL:
|
||||
f->state = CLOSED;
|
||||
break;
|
||||
|
||||
case STARTING:
|
||||
if( f->flags & OPT_SILENT )
|
||||
f->state = STOPPED;
|
||||
else {
|
||||
/* Send an initial configure-request */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Up event in state %d!",
|
||||
PROTO_NAME(f), f->state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_lowerdown - The lower layer is down.
|
||||
*
|
||||
* Cancel all timeouts and inform upper layers.
|
||||
*/
|
||||
void fsm_lowerdown(fsm *f)
|
||||
{
|
||||
switch( f->state ){
|
||||
case CLOSED:
|
||||
f->state = INITIAL;
|
||||
break;
|
||||
|
||||
case STOPPED:
|
||||
f->state = STARTING;
|
||||
if( f->callbacks->starting )
|
||||
(*f->callbacks->starting)(f);
|
||||
break;
|
||||
|
||||
case CLOSING:
|
||||
f->state = INITIAL;
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
break;
|
||||
|
||||
case STOPPING:
|
||||
case REQSENT:
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
f->state = STARTING;
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
if( f->callbacks->down )
|
||||
(*f->callbacks->down)(f);
|
||||
f->state = STARTING;
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Down event in state %d!",
|
||||
PROTO_NAME(f), f->state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_open - Link is allowed to come up.
|
||||
*/
|
||||
void fsm_open(fsm *f)
|
||||
{
|
||||
switch( f->state ){
|
||||
case INITIAL:
|
||||
f->state = STARTING;
|
||||
if( f->callbacks->starting )
|
||||
(*f->callbacks->starting)(f);
|
||||
break;
|
||||
|
||||
case CLOSED:
|
||||
if( f->flags & OPT_SILENT )
|
||||
f->state = STOPPED;
|
||||
else {
|
||||
/* Send an initial configure-request */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLOSING:
|
||||
f->state = STOPPING;
|
||||
/* fall through */
|
||||
case STOPPED:
|
||||
case OPENED:
|
||||
if( f->flags & OPT_RESTART ){
|
||||
fsm_lowerdown(f);
|
||||
fsm_lowerup(f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_close - Start closing connection.
|
||||
*
|
||||
* Cancel timeouts and either initiate close or possibly go directly to
|
||||
* the CLOSED state.
|
||||
*/
|
||||
void fsm_close(fsm *f,char *reason)
|
||||
{
|
||||
f->term_reason = reason;
|
||||
f->term_reason_len = (reason == NULL? 0: strlen(reason));
|
||||
switch( f->state ){
|
||||
case STARTING:
|
||||
f->state = INITIAL;
|
||||
break;
|
||||
case STOPPED:
|
||||
f->state = CLOSED;
|
||||
break;
|
||||
case STOPPING:
|
||||
f->state = CLOSING;
|
||||
break;
|
||||
|
||||
case REQSENT:
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
case OPENED:
|
||||
if( f->state != OPENED )
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
else if( f->callbacks->down )
|
||||
(*f->callbacks->down)(f); /* Inform upper layers we're down */
|
||||
|
||||
/* Init restart counter, send Terminate-Request */
|
||||
f->retransmits = f->maxtermtransmits;
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, (caddr_t) f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
|
||||
f->state = CLOSING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_timeout - Timeout expired.
|
||||
*/
|
||||
static void fsm_timeout(caddr_t arg)
|
||||
{
|
||||
fsm *f = (fsm *) arg;
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSING:
|
||||
case STOPPING:
|
||||
if( f->retransmits <= 0 ){
|
||||
/*
|
||||
* We've waited for an ack long enough. Peer probably heard us.
|
||||
*/
|
||||
f->state = (f->state == CLOSING)? CLOSED: STOPPED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
} else {
|
||||
/* Send Terminate-Request */
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, (caddr_t) f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
}
|
||||
break;
|
||||
|
||||
case REQSENT:
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
if (f->retransmits <= 0) {
|
||||
syslog(LOG_WARNING, "%s: timeout sending Config-Requests",
|
||||
PROTO_NAME(f));
|
||||
f->state = STOPPED;
|
||||
if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
|
||||
} else {
|
||||
/* Retransmit the configure-request */
|
||||
if (f->callbacks->retransmit)
|
||||
(*f->callbacks->retransmit)(f);
|
||||
fsm_sconfreq(f, 1); /* Re-send Configure-Request */
|
||||
if( f->state == ACKRCVD )
|
||||
f->state = REQSENT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!",
|
||||
PROTO_NAME(f), f->state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_input - Input packet.
|
||||
*/
|
||||
void fsm_input(fsm *f,u_char *inpacket,int l)
|
||||
{
|
||||
u_char *inp;
|
||||
u_char code, id;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Parse header (code, id and length).
|
||||
* If packet too short, drop it.
|
||||
*/
|
||||
inp = inpacket;
|
||||
if (l < HEADERLEN) {
|
||||
FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < HEADERLEN) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
if (len > l) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
len -= HEADERLEN; /* subtract header length */
|
||||
|
||||
if( f->state == INITIAL || f->state == STARTING ){
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.",
|
||||
f->protocol, f->state));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action depends on code.
|
||||
*/
|
||||
switch (code) {
|
||||
case CONFREQ:
|
||||
fsm_rconfreq(f, id, inp, len);
|
||||
break;
|
||||
|
||||
case CONFACK:
|
||||
fsm_rconfack(f, id, inp, len);
|
||||
break;
|
||||
|
||||
case CONFNAK:
|
||||
case CONFREJ:
|
||||
fsm_rconfnakrej(f, code, id, inp, len);
|
||||
break;
|
||||
|
||||
case TERMREQ:
|
||||
fsm_rtermreq(f, id, inp, len);
|
||||
break;
|
||||
|
||||
case TERMACK:
|
||||
fsm_rtermack(f);
|
||||
break;
|
||||
|
||||
case CODEREJ:
|
||||
fsm_rcoderej(f, inp, len);
|
||||
break;
|
||||
|
||||
default:
|
||||
if( !f->callbacks->extcode
|
||||
|| !(*f->callbacks->extcode)(f, code, id, inp, len) )
|
||||
fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rconfreq - Receive Configure-Request.
|
||||
*/
|
||||
static void fsm_rconfreq(fsm *f,int id,u_char *inp,int len)
|
||||
{
|
||||
int code, reject_if_disagree;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d.", PROTO_NAME(f), id));
|
||||
switch( f->state ){
|
||||
case CLOSED:
|
||||
/* Go away, we're closed */
|
||||
fsm_sdata(f, TERMACK, id, NULL, 0);
|
||||
return;
|
||||
case CLOSING:
|
||||
case STOPPING:
|
||||
return;
|
||||
|
||||
case OPENED:
|
||||
/* Go down and restart negotiation */
|
||||
if( f->callbacks->down )
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
||||
break;
|
||||
|
||||
case STOPPED:
|
||||
/* Negotiation started by our peer */
|
||||
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass the requested configuration options
|
||||
* to protocol-specific code for checking.
|
||||
*/
|
||||
if (f->callbacks->reqci){ /* Check CI */
|
||||
reject_if_disagree = (f->nakloops >= f->maxnakloops);
|
||||
code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
|
||||
} else if (len)
|
||||
code = CONFREJ; /* Reject all CI */
|
||||
else
|
||||
code = CONFACK;
|
||||
|
||||
/* send the Ack, Nak or Rej to the peer */
|
||||
fsm_sdata(f, code, id, inp, len);
|
||||
|
||||
if (code == CONFACK) {
|
||||
if (f->state == ACKRCVD) {
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
f->state = OPENED;
|
||||
if (f->callbacks->up)
|
||||
(*f->callbacks->up)(f); /* Inform upper layers */
|
||||
} else
|
||||
f->state = ACKSENT;
|
||||
f->nakloops = 0;
|
||||
|
||||
} else {
|
||||
/* we sent CONFACK or CONFREJ */
|
||||
if (f->state != ACKRCVD)
|
||||
f->state = REQSENT;
|
||||
if( code == CONFNAK )
|
||||
++f->nakloops;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rconfack - Receive Configure-Ack.
|
||||
*/
|
||||
static void fsm_rconfack(fsm *f,int id,u_char *inp,int len)
|
||||
{
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
|
||||
PROTO_NAME(f), id));
|
||||
|
||||
if (id != f->reqid || f->seen_ack) /* Expected id? */
|
||||
return; /* Nope, toss... */
|
||||
if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
|
||||
(len == 0)) ){
|
||||
/* Ack is bad - ignore it */
|
||||
FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
|
||||
PROTO_NAME(f), len));
|
||||
return;
|
||||
}
|
||||
f->seen_ack = 1;
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSED:
|
||||
case STOPPED:
|
||||
fsm_sdata(f, TERMACK, id, NULL, 0);
|
||||
break;
|
||||
|
||||
case REQSENT:
|
||||
f->state = ACKRCVD;
|
||||
f->retransmits = f->maxconfreqtransmits;
|
||||
break;
|
||||
|
||||
case ACKRCVD:
|
||||
/* Huh? an extra valid Ack? oh well... */
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
|
||||
case ACKSENT:
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
f->state = OPENED;
|
||||
f->retransmits = f->maxconfreqtransmits;
|
||||
if (f->callbacks->up)
|
||||
(*f->callbacks->up)(f); /* Inform upper layers */
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
/* Go down and restart negotiation */
|
||||
if (f->callbacks->down)
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
|
||||
*/
|
||||
static void fsm_rconfnakrej(fsm *f,int code,int id,u_char *inp,int len)
|
||||
{
|
||||
int (*proc)();
|
||||
int ret;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.",
|
||||
PROTO_NAME(f), id));
|
||||
|
||||
if (id != f->reqid || f->seen_ack) /* Expected id? */
|
||||
return; /* Nope, toss... */
|
||||
proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
|
||||
if (!proc || !(ret = proc(f, inp, len))) {
|
||||
/* Nak/reject is bad - ignore it */
|
||||
FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)",
|
||||
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
|
||||
return;
|
||||
}
|
||||
f->seen_ack = 1;
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSED:
|
||||
case STOPPED:
|
||||
fsm_sdata(f, TERMACK, id, NULL, 0);
|
||||
break;
|
||||
|
||||
case REQSENT:
|
||||
case ACKSENT:
|
||||
/* They didn't agree to what we wanted - try another request */
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
if (ret < 0)
|
||||
f->state = STOPPED; /* kludge for stopping CCP */
|
||||
else
|
||||
fsm_sconfreq(f, 0); /* Send Configure-Request */
|
||||
break;
|
||||
|
||||
case ACKRCVD:
|
||||
/* Got a Nak/reject when we had already had an Ack?? oh well... */
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
/* Go down and restart negotiation */
|
||||
if (f->callbacks->down)
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rtermreq - Receive Terminate-Req.
|
||||
*/
|
||||
static void fsm_rtermreq(fsm *f,int id,u_char *p,int len)
|
||||
{
|
||||
char str[80];
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
|
||||
PROTO_NAME(f), id));
|
||||
|
||||
switch (f->state) {
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
f->state = REQSENT; /* Start over but keep trying */
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
if (len > 0) {
|
||||
fmtmsg(str, sizeof(str), "%0.*v", len, p);
|
||||
syslog(LOG_INFO, "%s terminated by peer (%s)", PROTO_NAME(f), str);
|
||||
} else
|
||||
syslog(LOG_INFO, "%s terminated by peer", PROTO_NAME(f));
|
||||
if (f->callbacks->down)
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
f->retransmits = 0;
|
||||
f->state = STOPPING;
|
||||
TIMEOUT(fsm_timeout, (caddr_t) f, f->timeouttime);
|
||||
break;
|
||||
}
|
||||
|
||||
fsm_sdata(f, TERMACK, id, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rtermack - Receive Terminate-Ack.
|
||||
*/
|
||||
static void fsm_rtermack(fsm *f)
|
||||
{
|
||||
FSMDEBUG((LOG_INFO, "fsm_rtermack(%s).", PROTO_NAME(f)));
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSING:
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f);
|
||||
f->state = CLOSED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
case STOPPING:
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f);
|
||||
f->state = STOPPED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
|
||||
case ACKRCVD:
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
if (f->callbacks->down)
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
fsm_sconfreq(f, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rcoderej - Receive an Code-Reject.
|
||||
*/
|
||||
static void fsm_rcoderej(fsm *f,u_char *inp,int len)
|
||||
{
|
||||
u_char code, id;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s).", PROTO_NAME(f)));
|
||||
|
||||
if (len < HEADERLEN) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!"));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
syslog(LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d",
|
||||
PROTO_NAME(f), code, id);
|
||||
|
||||
if( f->state == ACKRCVD )
|
||||
f->state = REQSENT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_protreject - Peer doesn't speak this protocol.
|
||||
*
|
||||
* Treat this as a catastrophic error (RXJ-).
|
||||
*/
|
||||
void fsm_protreject(fsm *f)
|
||||
{
|
||||
switch( f->state ){
|
||||
case CLOSING:
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
/* fall through */
|
||||
case CLOSED:
|
||||
f->state = CLOSED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
|
||||
case STOPPING:
|
||||
case REQSENT:
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
UNTIMEOUT(fsm_timeout, (caddr_t) f); /* Cancel timeout */
|
||||
/* fall through */
|
||||
case STOPPED:
|
||||
f->state = STOPPED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
if( f->callbacks->down )
|
||||
(*f->callbacks->down)(f);
|
||||
|
||||
/* Init restart counter, send Terminate-Request */
|
||||
f->retransmits = f->maxtermtransmits;
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, (caddr_t) f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
|
||||
f->state = STOPPING;
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!",
|
||||
PROTO_NAME(f), f->state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_sconfreq - Send a Configure-Request.
|
||||
*/
|
||||
static void fsm_sconfreq(fsm *f,int retransmit)
|
||||
{
|
||||
u_char *outp;
|
||||
int cilen;
|
||||
|
||||
if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){
|
||||
/* Not currently negotiating - reset options */
|
||||
if( f->callbacks->resetci )
|
||||
(*f->callbacks->resetci)(f);
|
||||
f->nakloops = 0;
|
||||
}
|
||||
|
||||
if( !retransmit ){
|
||||
/* New request - reset retransmission counter, use new ID */
|
||||
f->retransmits = f->maxconfreqtransmits;
|
||||
f->reqid = ++f->id;
|
||||
}
|
||||
|
||||
f->seen_ack = 0;
|
||||
|
||||
/*
|
||||
* Make up the request packet
|
||||
*/
|
||||
outp = outpacket_buf + PPP_HDRLEN + HEADERLEN;
|
||||
if( f->callbacks->cilen && f->callbacks->addci ){
|
||||
cilen = (*f->callbacks->cilen)(f);
|
||||
if( cilen > lns[f->unit].peer_mru - HEADERLEN )
|
||||
cilen = lns[f->unit].peer_mru - HEADERLEN;
|
||||
if (f->callbacks->addci)
|
||||
(*f->callbacks->addci)(f, outp, &cilen);
|
||||
} else
|
||||
cilen = 0;
|
||||
|
||||
/* send the request to our peer */
|
||||
fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
|
||||
|
||||
/* start the retransmit timer */
|
||||
--f->retransmits;
|
||||
TIMEOUT(fsm_timeout, (caddr_t) f, f->timeouttime);
|
||||
|
||||
FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d",
|
||||
PROTO_NAME(f), f->reqid));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_sdata - Send some data.
|
||||
*
|
||||
* Used for all packets sent to our peer by this module.
|
||||
*/
|
||||
void fsm_sdata(fsm *f,int code,int id,u_char *data,int datalen)
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
/* Adjust length to be smaller than MTU */
|
||||
outp = outpacket_buf;
|
||||
if (datalen > lns[f->unit].peer_mru - HEADERLEN)
|
||||
datalen = lns[f->unit].peer_mru - HEADERLEN;
|
||||
if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)
|
||||
BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
|
||||
outlen = datalen + HEADERLEN;
|
||||
MAKEHEADER(outp, f->protocol);
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
output(f->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d, id %d.",
|
||||
PROTO_NAME(f), code, id));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: fsm.h,v 1.1 1997/03/07 16:01:16 hipp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Packet header = Code, id, length.
|
||||
*/
|
||||
#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
|
||||
|
||||
|
||||
/*
|
||||
* CP (LCP, IPCP, etc.) codes.
|
||||
*/
|
||||
#define CONFREQ 1 /* Configuration Request */
|
||||
#define CONFACK 2 /* Configuration Ack */
|
||||
#define CONFNAK 3 /* Configuration Nak */
|
||||
#define CONFREJ 4 /* Configuration Reject */
|
||||
#define TERMREQ 5 /* Termination Request */
|
||||
#define TERMACK 6 /* Termination Ack */
|
||||
#define CODEREJ 7 /* Code Reject */
|
||||
|
||||
|
||||
/*
|
||||
* Each FSM is described by a fsm_callbacks and a fsm structure.
|
||||
*/
|
||||
typedef struct fsm_callbacks {
|
||||
void (*resetci)(); /* Reset our Configuration Information */
|
||||
int (*cilen)(); /* Length of our Configuration Information */
|
||||
void (*addci)(); /* Add our Configuration Information */
|
||||
int (*ackci)(); /* ACK our Configuration Information */
|
||||
int (*nakci)(); /* NAK our Configuration Information */
|
||||
int (*rejci)(); /* Reject our Configuration Information */
|
||||
int (*reqci)(); /* Request peer's Configuration Information */
|
||||
void (*up)(); /* Called when fsm reaches OPENED state */
|
||||
void (*down)(); /* Called when fsm leaves OPENED state */
|
||||
void (*starting)(); /* Called when we want the lower layer */
|
||||
void (*finished)(); /* Called when we don't want the lower layer */
|
||||
void (*protreject)(); /* Called when Protocol-Reject received */
|
||||
void (*retransmit)(); /* Retransmission is necessary */
|
||||
int (*extcode)(); /* Called when unknown code received */
|
||||
char *proto_name; /* String name for protocol (for messages) */
|
||||
} fsm_callbacks;
|
||||
|
||||
|
||||
typedef struct fsm {
|
||||
int unit; /* Interface unit number */
|
||||
int inuse; /* this 'unit' in use? */
|
||||
int protocol; /* Data Link Layer Protocol field value */
|
||||
int state; /* State */
|
||||
int flags; /* Contains option bits */
|
||||
u_char id; /* Current id */
|
||||
u_char reqid; /* Current request id */
|
||||
u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */
|
||||
int timeouttime; /* Timeout time in milliseconds */
|
||||
int maxconfreqtransmits; /* Maximum Configure-Request transmissions */
|
||||
int retransmits; /* Number of retransmissions left */
|
||||
int maxtermtransmits; /* Maximum Terminate-Request transmissions */
|
||||
int nakloops; /* Number of nak loops since last ack */
|
||||
int maxnakloops; /* Maximum number of nak loops tolerated */
|
||||
fsm_callbacks *callbacks; /* Callback routines */
|
||||
char *term_reason; /* Reason for closing protocol */
|
||||
int term_reason_len; /* Length of term_reason */
|
||||
} fsm;
|
||||
|
||||
|
||||
/*
|
||||
* Link states.
|
||||
*/
|
||||
#define INITIAL 0 /* Down, hasn't been opened */
|
||||
#define STARTING 1 /* Down, been opened */
|
||||
#define CLOSED 2 /* Up, hasn't been opened */
|
||||
#define STOPPED 3 /* Open, waiting for down event */
|
||||
#define CLOSING 4 /* Terminating the connection, not open */
|
||||
#define STOPPING 5 /* Terminating, but open */
|
||||
#define REQSENT 6 /* We've sent a Config Request */
|
||||
#define ACKRCVD 7 /* We've received a Config Ack */
|
||||
#define ACKSENT 8 /* We've sent a Config Ack */
|
||||
#define OPENED 9 /* Connection available */
|
||||
|
||||
/*
|
||||
* Flags - indicate options controlling FSM operation
|
||||
*/
|
||||
#define OPT_PASSIVE 1 /* Don't die if we don't get a response */
|
||||
#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */
|
||||
#define OPT_SILENT 4 /* Wait for peer to speak first */
|
||||
|
||||
/*
|
||||
* Timeouts.
|
||||
*/
|
||||
#define DEFTIMEOUT 3 /* Timeout time in seconds */
|
||||
#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */
|
||||
#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */
|
||||
#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
void fsm_init __P((fsm *));
|
||||
|
||||
void fsm_lowerup __P((fsm *));
|
||||
|
||||
void fsm_lowerdown __P((fsm *));
|
||||
void fsm_open __P((fsm *));
|
||||
void fsm_close __P((fsm *,char *));
|
||||
void fsm_input __P((fsm *, u_char *, int));
|
||||
void fsm_protreject __P((fsm *));
|
||||
void fsm_sdata __P((fsm *, int, int, u_char *, int));
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* ipcp.h - IP Control Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ipcp.h,v 1.1 1997/03/07 16:01:19 hipp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
#define CI_ADDRS 1 /* IP Addresses */
|
||||
#define CI_COMPRESSTYPE 2 /* Compression Type */
|
||||
#define CI_ADDR 3
|
||||
|
||||
#define CI_MS_DNS1 129 /* Primary DNS value */
|
||||
#define CI_MS_WINS1 130 /* Primary WINS value */
|
||||
#define CI_MS_DNS2 131 /* Secondary DNS value */
|
||||
#define CI_MS_WINS2 132 /* Secondary WINS value */
|
||||
|
||||
#define MAX_STATES 16 /* from slcompress.h */
|
||||
|
||||
#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */
|
||||
#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */
|
||||
#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */
|
||||
/* maxslot and slot number compression) */
|
||||
|
||||
#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/
|
||||
#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */
|
||||
/* compression option*/
|
||||
|
||||
typedef struct ipcp_options {
|
||||
int neg_addr : 1; /* Negotiate IP Address? */
|
||||
int old_addrs : 1; /* Use old (IP-Addresses) option? */
|
||||
int req_addr : 1; /* Ask peer to send IP address? */
|
||||
int default_route : 1; /* Assign default route through interface? */
|
||||
int proxy_arp : 1; /* Make proxy ARP entry for peer? */
|
||||
int neg_vj : 1; /* Van Jacobson Compression? */
|
||||
int old_vj : 1; /* use old (short) form of VJ option? */
|
||||
int accept_local : 1; /* accept peer's value for ouraddr */
|
||||
int accept_remote : 1; /* accept peer's value for hisaddr */
|
||||
u_short vj_protocol; /* protocol value to use in VJ option */
|
||||
u_char maxslotindex, cflag; /* values for RFC1332 VJ compression neg. */
|
||||
u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */
|
||||
u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */
|
||||
u_int32_t winsaddr[2]; /* Primary and secondary MS WINS entries */
|
||||
} ipcp_options;
|
||||
|
||||
extern fsm ipcp_fsm[];
|
||||
extern ipcp_options ipcp_wantoptions[];
|
||||
extern ipcp_options ipcp_gotoptions[];
|
||||
extern ipcp_options ipcp_allowoptions[];
|
||||
extern ipcp_options ipcp_hisoptions[];
|
||||
|
||||
extern struct protent ipcp_protent;
|
||||
|
|
@ -0,0 +1,931 @@
|
|||
.\" manual page [] for pppd 2.0
|
||||
.\" $Id: ipppd.8,v 1.1 1997/03/07 16:01:19 hipp Exp $
|
||||
.\" SH section heading
|
||||
.\" SS subsection heading
|
||||
.\" LP paragraph
|
||||
.\" IP indented paragraph
|
||||
.\" TP hanging label
|
||||
.TH PPPD 8
|
||||
.SH NAME
|
||||
pppd \- Point to Point Protocol daemon
|
||||
.SH SYNOPSIS
|
||||
.B pppd
|
||||
[
|
||||
.I tty_name
|
||||
] [
|
||||
.I speed
|
||||
] [
|
||||
.I options
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
The Point-to-Point Protocol (PPP) provides a method for transmitting
|
||||
datagrams over serial point-to-point links. PPP
|
||||
is composed of three parts: a method for encapsulating datagrams over
|
||||
serial links, an extensible Link Control Protocol (LCP), and
|
||||
a family of Network Control Protocols (NCP) for establishing
|
||||
and configuring different network-layer protocols.
|
||||
.LP
|
||||
The encapsulation scheme is provided by driver code in the kernel.
|
||||
.B pppd
|
||||
provides the basic LCP, authentication support, and an
|
||||
NCP for establishing and configuring the Internet Protocol (IP)
|
||||
(called the IP Control Protocol, IPCP).
|
||||
.SH FREQUENTLY USED OPTIONS
|
||||
.TP
|
||||
.I <tty_name>
|
||||
Communicate over the named device. The string "/dev/"
|
||||
is prepended if necessary. If no device name is given,
|
||||
or if the name of the controlling terminal is given,
|
||||
.I pppd
|
||||
will use the controlling terminal, and will not fork to put itself in
|
||||
the background.
|
||||
.TP
|
||||
.I <speed>
|
||||
Set the baud rate to <speed> (a decimal number). On systems such as
|
||||
4.4BSD and NetBSD, any speed can be specified. Other systems
|
||||
(e.g. SunOS) allow only a limited set of speeds.
|
||||
.TP
|
||||
.B asyncmap \fI<map>
|
||||
Set the async character map to <map>.
|
||||
This map describes which control characters cannot be successfully
|
||||
received over the serial line.
|
||||
.I pppd
|
||||
will ask the peer to send these characters as a 2-byte escape sequence.
|
||||
The argument is a 32 bit hex number
|
||||
with each bit representing a character to escape.
|
||||
Bit 0 (00000001) represents the character 0x00;
|
||||
bit 31 (80000000) represents the character 0x1f or ^_.
|
||||
If multiple \fBasyncmap\fR options are
|
||||
given, the values are ORed together.
|
||||
If no \fBasyncmap\fR option is given, no async character map will be
|
||||
negotiated for the receive direction; the peer should then escape
|
||||
\fIall\fR control characters.
|
||||
.TP
|
||||
.B auth
|
||||
Require the peer to authenticate itself before allowing network
|
||||
packets to be sent or received.
|
||||
.TP
|
||||
.B connect \fI<p>
|
||||
Use the executable or shell command specified by \fI<p>\fR to set up the
|
||||
serial line. This script would typically use the chat(8) program to
|
||||
dial the modem and start the remote ppp session.
|
||||
.TP
|
||||
.B crtscts
|
||||
Use hardware flow control (i.e. RTS/CTS) to control the flow of data
|
||||
on the serial port. If neither the \fBcrtscts\fR nor the
|
||||
\fB\-crtscts\fR option is given, the hardware flow control setting for
|
||||
the serial port is left unchanged.
|
||||
.TP
|
||||
.B defaultroute
|
||||
Add a default route to the system routing tables, using the peer as
|
||||
the gateway, when IPCP negotiation is successfully completed.
|
||||
This entry is removed when the PPP connection is broken.
|
||||
.TP
|
||||
.B disconnect \fI<p>
|
||||
Run the executable or shell command specified by \fI<p>\fR after
|
||||
\fIpppd\fR has terminated the link. This script could, for example,
|
||||
issue commands to the modem to cause it to hang up if hardware modem
|
||||
control signals were not available.
|
||||
.TP
|
||||
.B escape \fIxx,yy,...
|
||||
Specifies that certain characters should be escaped on transmission
|
||||
(regardless of whether the peer requests them to be escaped with its
|
||||
async control character map). The characters to be escaped are
|
||||
specified as a list of hex numbers separated by commas. Note that
|
||||
almost any character can be specified for the \fBescape\fR option,
|
||||
unlike the \fBasyncmap\fR option which only allows control characters
|
||||
to be specified. The characters which may not be escaped are those
|
||||
with hex values 0x20 - 0x3f or 0x5e.
|
||||
.TP
|
||||
.B file \fI<f>
|
||||
Read options from file <f> (the format is described below).
|
||||
.TP
|
||||
.B lock
|
||||
Specifies that \fIpppd\fR should create a UUCP-style lock file for the
|
||||
serial device to ensure exclusive access to the device.
|
||||
.TP
|
||||
.B mru \fI<n>
|
||||
Set the MRU [Maximum Receive Unit] value to <n> for negotiation.
|
||||
.I pppd
|
||||
will ask the peer to send packets of no more than <n> bytes. The
|
||||
minimum MRU value is 128. The default MRU value is 1500. A value of
|
||||
296 is recommended for slow links (40 bytes for TCP/IP header + 256
|
||||
bytes of data).
|
||||
.TP
|
||||
.B mtu \fI<n>
|
||||
Set the MTU [Maximum Transmit Unit] value to \fI<n>\fR. Unless the
|
||||
peer requests a smaller value via MRU negotiation, \fIpppd\fR will
|
||||
request that the kernel networking code send data packets of no more
|
||||
than \fIn\fR bytes through the PPP network interface.
|
||||
.TP
|
||||
.B netmask \fI<n>
|
||||
Set the interface netmask to <n>, a 32 bit netmask in "decimal dot"
|
||||
notation (e.g. 255.255.255.0). If this option is given, the value
|
||||
specified is ORed with the default netmask. The default netmask is
|
||||
chosen based on the negotiated remote IP address; it is the
|
||||
appropriate network mask for the class of the remote IP address, ORed
|
||||
with the netmasks for any non point-to-point network interfaces in the
|
||||
system which are on the same network.
|
||||
.TP
|
||||
.B passive
|
||||
Enables the "passive" option in the LCP. With this option,
|
||||
.I pppd
|
||||
will attempt to initiate a connection; if no reply is received from
|
||||
the peer,
|
||||
.I pppd
|
||||
will then just wait passively for a valid LCP packet from the peer
|
||||
(instead of exiting, as it does without this option).
|
||||
.TP
|
||||
.B silent
|
||||
With this option,
|
||||
.I pppd
|
||||
will not transmit LCP packets to initiate a connection until a valid
|
||||
LCP packet is received from the peer (as for the `passive' option with
|
||||
ancient versions of \fIpppd\fR).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I <local_IP_address>\fB:\fI<remote_IP_address>
|
||||
Set the local and/or remote interface IP addresses. Either one may be
|
||||
omitted. The IP addresses can be specified with a host name or in
|
||||
decimal dot notation (e.g. 150.234.56.78). The default local
|
||||
address is the (first) IP address of the system (unless the
|
||||
.B noipdefault
|
||||
option is given). The remote address will be obtained from the peer
|
||||
if not specified in any option. Thus, in simple cases, this option is
|
||||
not required. If a local and/or remote IP address is specified with
|
||||
this option,
|
||||
.I pppd
|
||||
will not accept a different value from the peer in the IPCP
|
||||
negotiation, unless the
|
||||
.B ipcp-accept-local
|
||||
and/or
|
||||
.B ipcp-accept-remote
|
||||
options are given, respectively.
|
||||
.TP
|
||||
.B -ac
|
||||
Disable Address/Control compression negotiation (use default, i.e.
|
||||
address/control field compression disabled).
|
||||
.TP
|
||||
.B -all
|
||||
Don't request or allow negotiation of any options for LCP and IPCP (use
|
||||
default values).
|
||||
.TP
|
||||
.B -am
|
||||
Disable asyncmap negotiation (use the default asyncmap, i.e. escape
|
||||
all control characters).
|
||||
.TP
|
||||
.B -as \fI<n>
|
||||
Same as
|
||||
.B asyncmap \fI<n>
|
||||
.TP
|
||||
.B bsdcomp \fInr,nt
|
||||
Request that the peer compress packets that it sends, using the
|
||||
BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and
|
||||
agree to compress packets sent to the peer with a maximum code size of
|
||||
\fInt\fR bits. If \fInt\fR is not specified, it defaults to the value
|
||||
given for \fInr\fR. Values in the range 9 to 15 may be used for
|
||||
\fInr\fR and \fInt\fR; larger values give better compression but
|
||||
consume more kernel memory for compression dictionaries.
|
||||
Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
|
||||
compression in the corresponding direction.
|
||||
.TP
|
||||
.B \-bsdcomp
|
||||
Disables compression; \fBpppd\fR will not request or agree to compress
|
||||
packets using the BSD-Compress scheme.
|
||||
.TP
|
||||
.B +chap
|
||||
Require the peer to authenticate itself using CHAP [Cryptographic
|
||||
Handshake Authentication Protocol] authentication.
|
||||
.TP
|
||||
.B -chap
|
||||
Don't agree to authenticate using CHAP.
|
||||
.TP
|
||||
.B chap-interval \fI<n>
|
||||
If this option is given,
|
||||
.I pppd
|
||||
will rechallenge the peer every <n> seconds.
|
||||
.TP
|
||||
.B chap-max-challenge \fI<n>
|
||||
Set the maximum number of CHAP challenge transmissions to <n> (default
|
||||
10).
|
||||
.TP
|
||||
.B chap-restart \fI<n>
|
||||
Set the CHAP restart interval (retransmission timeout for challenges)
|
||||
to <n> seconds (default 3).
|
||||
.TP
|
||||
.B -crtscts
|
||||
Disable hardware flow control (i.e. RTS/CTS) on the serial port. If
|
||||
neither the \fBcrtscts\fR nor the \fB\-crtscts\fR option is given,
|
||||
the hardware flow control setting for the serial port is left
|
||||
unchanged.
|
||||
.TP
|
||||
.B -d
|
||||
Increase debugging level (same as the \fBdebug\fR option).
|
||||
.TP
|
||||
.B debug
|
||||
Increase debugging level (same as \fB\-d\fR).
|
||||
If this option is given, \fIpppd\fR will log the contents of all
|
||||
control packets sent or received in a readable form. The packets are
|
||||
logged through syslog with facility \fIdaemon\fR and level
|
||||
\fIdebug\fR. This information can be directed to a file by setting up
|
||||
/etc/syslog.conf appropriately (see syslog.conf(5)).
|
||||
.TP
|
||||
.B \-defaultroute
|
||||
Disable the \fBdefaultroute\fR option. The system administrator who
|
||||
wishes to prevent users from creating default routes with \fIpppd\fR
|
||||
can do so by placing this option in the /etc/ppp/options file.
|
||||
.TP
|
||||
.B -detach
|
||||
Don't fork to become a background process (otherwise
|
||||
.I pppd
|
||||
will do so if a serial device other than its controlling terminal is
|
||||
specified).
|
||||
.TP
|
||||
.B dns-addr \fI<n>
|
||||
This option sets the IP address or addresses for the Domain Name
|
||||
Server. It is used by Microsoft Windows clients. The primary DNS
|
||||
address is specified by the first instance of the dns-addr option. The
|
||||
secondary is specified by the second instance.
|
||||
.TP
|
||||
.B domain \fI<d>
|
||||
Append the domain name <d> to the local host name for authentication
|
||||
purposes. For example, if gethostname() returns the name porsche, but the
|
||||
fully qualified domain name is porsche.Quotron.COM, you would use the
|
||||
domain option to set the domain name to Quotron.COM.
|
||||
.TP
|
||||
.B -ip
|
||||
Disable IP address negotiation. If this option is used, the remote IP
|
||||
address must be specified with an option on the command line or in an
|
||||
options file.
|
||||
.TP
|
||||
.B +ip-protocol
|
||||
Enable the IPCP and IP protocols. This is the default condition. This
|
||||
option is only needed if the default setting is -ip-protocol.
|
||||
.TP
|
||||
.B -ip-protocol
|
||||
Disable the IPCP and IP protocols. This should only be used if you
|
||||
know that you are using a client which only understands IPX and you
|
||||
don't want to confuse the client with the IPCP protocol.
|
||||
.TP
|
||||
.B +ipx-protocol
|
||||
Enable the IPXCP and IPX protocols. This is the default condition if
|
||||
your kernel supports IPX. This option is only needed if the default
|
||||
setting is -ipx-protocol. If your kernel does not support IPX then this
|
||||
option will have no effect.
|
||||
.TP
|
||||
.B -ipx-protocol
|
||||
Disable the IPXCP and IPX protocols. This should only be used if you
|
||||
know that you are using a client which only understands IP and you
|
||||
don't want to confuse the client with the IPXCP protocol.
|
||||
.TP
|
||||
.B ipcp-accept-local
|
||||
With this option,
|
||||
.I pppd
|
||||
will accept the peer's idea of our local IP address, even if the
|
||||
local IP address was specified in an option.
|
||||
.TP
|
||||
.B ipcp-accept-remote
|
||||
With this option,
|
||||
.I pppd
|
||||
will accept the peer's idea of its (remote) IP address, even if the
|
||||
remote IP address was specified in an option.
|
||||
.TP
|
||||
.B ipcp-max-configure \fI<n>
|
||||
Set the maximum number of IPCP configure-request transmissions to <n>
|
||||
(default 10).
|
||||
.TP
|
||||
.B ipcp-max-failure \fI<n>
|
||||
Set the maximum number of IPCP configure-NAKs returned before starting
|
||||
to send configure-Rejects instead to <n> (default 10).
|
||||
.TP
|
||||
.B ipcp-max-terminate \fI<n>
|
||||
Set the maximum number of IPCP terminate-request transmissions to <n>
|
||||
(default 3).
|
||||
.TP
|
||||
.B ipcp-restart \fI<n>
|
||||
Set the IPCP restart interval (retransmission timeout) to <n> seconds
|
||||
(default 3).
|
||||
.TP
|
||||
.B ipparam \fIstring
|
||||
Provides an extra parameter to the ip-up and ip-down scripts. If this
|
||||
option is given, the \fIstring\fR supplied is given as the 6th
|
||||
parameter to those scripts.
|
||||
.TP
|
||||
.B ipx-network \fI<n>
|
||||
Set the IPX network number in the IPXCP configure request frame to
|
||||
<n>. There is no valid default. If this option is not specified then
|
||||
the network number is obtained from the peer. If the peer does not
|
||||
have the network number, the IPX protocol will not be started. This is
|
||||
a hexadecimal number and is entered without any leading sequence such
|
||||
as 0x. It is related to the \fIipxcp-accept-network\fR option.
|
||||
.TP
|
||||
.B ipx-node \fI<n>:<m>
|
||||
Set the IPX node numbers. The two node numbers are separated from each
|
||||
other with a colon character. The first number <n> is the local node
|
||||
number. The second number <m> is the peer's node number. Each node number
|
||||
is a hexadecimal number, to the maximum of ten significant digits. The
|
||||
node numbers on the ipx-network must be unique. There is no valid
|
||||
default. If this option is not specified then the node number is
|
||||
obtained from the peer. This option is a related to the
|
||||
\fIipxcp-accept-local\fR and \fIipxcp-accept-remote\fR options.
|
||||
.TP
|
||||
.B ipx-router-name \fI<string>
|
||||
Set the name of the router. This is a string and is sent to the peer
|
||||
as information data.
|
||||
.TP
|
||||
.B ipx-routing \fI<n>
|
||||
Set the routing protocol to be received by this option. More than one
|
||||
instance of \fIipx-routing\fR may be specified. The '\fInone\fR'
|
||||
option (0) may be specified as the only instance of ipx-routing. The
|
||||
values may be \fI0\fR for \fINONE\fR, \fI2\fR for \fIRIP/SAP\fR, and
|
||||
\fI4\fR for \fINLSP\fR.
|
||||
.TP
|
||||
.B ipxcp-accept-local
|
||||
Accept the peer's NAK for the node number specified in the ipx-node
|
||||
option. If a node number was specified, and non-zero, the default is
|
||||
to insist that the value be used. If you include this option then you
|
||||
will permit the peer to override the entry of the node number.
|
||||
.TP
|
||||
.B ipxcp-accept-network
|
||||
Accept the peer's NAK for the network number specified in the
|
||||
ipx-network option. If a network number was specified, and non-zero, the
|
||||
default is to insist that the value be used. If you include this
|
||||
option then you will permit the peer to override the entry of the node
|
||||
number.
|
||||
.TP
|
||||
.B ipxcp-accept-remote
|
||||
Use the peer's network number specified in the configure request
|
||||
frame. If a node number was specified for the peer and this option was
|
||||
not specified, the peer will be forced to use the value which you have
|
||||
specified.
|
||||
.TP
|
||||
.B ipxcp-max-configure \fI<n>
|
||||
Set the maximum number of IPXCP configure request frames which the
|
||||
system will send to <n>. The default is 10.
|
||||
.TP
|
||||
.B ipxcp-max-failure \fI<n>
|
||||
Set the maximum number of IPXCP NAK frames which the local system will
|
||||
send before it rejects the options. The default value is 3.
|
||||
.TP
|
||||
.B ipxcp-max-terminate \fI<n>
|
||||
Set the maximum nuber of IPXCP terminate request frames before the
|
||||
local system considers that the peer is not listening to them. The
|
||||
default value is 3.
|
||||
.TP
|
||||
.B kdebug \fIn
|
||||
Enable debugging code in the kernel-level PPP driver. The argument
|
||||
\fIn\fR is a number which is the sum of the following values: 1 to
|
||||
enable general debug messages, 2 to request that the contents of
|
||||
received packets be printed, and 4 to request that the contents of
|
||||
transmitted packets be printed.
|
||||
.TP
|
||||
.B lcp-echo-failure \fI<n>
|
||||
If this option is given, \fIpppd\fR will presume the peer to be dead
|
||||
if \fIn\fR LCP echo-requests are sent without receiving a valid LCP
|
||||
echo-reply. If this happens, \fIpppd\fR will terminate the
|
||||
connection. Use of this option requires a non-zero value for the
|
||||
\fIlcp-echo-interval\fR parameter. This option can be used to enable
|
||||
\fIpppd\fR to terminate after the physical connection has been broken
|
||||
(e.g., the modem has hung up) in situations where no hardware modem
|
||||
control lines are available.
|
||||
.TP
|
||||
.B lcp-echo-interval \fI<n>
|
||||
If this option is given, \fIpppd\fR will send an LCP echo-request
|
||||
frame to the peer every \fIn\fR seconds. Under Linux, the
|
||||
echo-request is sent when no packets have been received from the peer
|
||||
for \fIn\fR seconds. Normally the peer should respond to the
|
||||
echo-request by sending an echo-reply. This option can be used with
|
||||
the \fIlcp-echo-failure\fR option to detect that the peer is no longer
|
||||
connected.
|
||||
.TP
|
||||
.B lcp-max-configure \fI<n>
|
||||
Set the maximum number of LCP configure-request transmissions to <n>
|
||||
(default 10).
|
||||
.TP
|
||||
.B lcp-max-failure \fI<n>
|
||||
Set the maximum number of LCP configure-NAKs returned before starting
|
||||
to send configure-Rejects instead to <n> (default 10).
|
||||
.TP
|
||||
.B lcp-max-terminate \fI<n>
|
||||
Set the maximum number of LCP terminate-request transmissions to <n>
|
||||
(default 3).
|
||||
.TP
|
||||
.B lcp-restart \fI<n>
|
||||
Set the LCP restart interval (retransmission timeout) to <n> seconds
|
||||
(default 3).
|
||||
.TP
|
||||
.B local
|
||||
Don't use the modem control lines. With this option,
|
||||
.B pppd
|
||||
will ignore the state of the CD (Carrier Detect) signal from the modem and
|
||||
will not change the state of the DTR (Data Terminal Ready) signal.
|
||||
.TP
|
||||
.B login
|
||||
Use the system password database for authenticating the peer using
|
||||
PAP, and record the user in the system wtmp file.
|
||||
.TP
|
||||
.B modem
|
||||
Use the modem control lines. This option is the default. With this
|
||||
option,
|
||||
.B pppd
|
||||
will wait for the CD (Carrier Detect) signal from the modem to be asserted
|
||||
when opening the serial device
|
||||
(unless a connect script is specified), and it will drop the DTR (Data
|
||||
Terminal Ready) signal briefly when the connection is terminated and before
|
||||
executing the connect script.
|
||||
On Ultrix, this option implies hardware
|
||||
flow control, as for the \fBcrtscts\fR option.
|
||||
.TP
|
||||
.B -mn
|
||||
Disable magic number negotiation. With this option,
|
||||
.I pppd
|
||||
cannot detect a looped-back line.
|
||||
.TP
|
||||
.B -mru
|
||||
Disable MRU [Maximum Receive Unit] negotiation. With this option,
|
||||
\fIpppd\fR will use the default MRU value of 1500 bytes.
|
||||
.TP
|
||||
.B name \fI<n>
|
||||
Set the name of the local system for authentication purposes to <n>.
|
||||
.TP
|
||||
.B noipdefault
|
||||
Disables the default behaviour when no local IP address is specified,
|
||||
which is to determine (if possible) the local IP address from the
|
||||
hostname. With this option, the peer will have to supply the local IP
|
||||
address during IPCP negotiation (unless it specified explicitly on the
|
||||
command line or in an options file).
|
||||
.TP
|
||||
.B -p
|
||||
Same as the
|
||||
.B passive
|
||||
option.
|
||||
.TP
|
||||
.B +pap
|
||||
Require the peer to authenticate itself using PAP.
|
||||
.TP
|
||||
.B -pap
|
||||
Don't agree to authenticate using PAP.
|
||||
.TP
|
||||
.B papcrypt
|
||||
Indicates that all secrets in the /etc/ppp/pap-secrets file which
|
||||
are used for checking the identity of the peer are encrypted, and thus
|
||||
pppd should not accept a password which (before encryption) is
|
||||
identical to the secret from the /etc/ppp/pap-secrets file.
|
||||
.TP
|
||||
.B pap-max-authreq \fI<n>
|
||||
Set the maximum number of PAP authenticate-request transmissions to
|
||||
<n> (default 10).
|
||||
.TP
|
||||
.B pap-restart \fI<n>
|
||||
Set the PAP restart interval (retransmission timeout) to <n> seconds
|
||||
(default 3).
|
||||
.TP
|
||||
.B pap-timeout \fI<n>
|
||||
Set the maximum time that
|
||||
.I pppd
|
||||
will wait for the peer to authenticate itself with PAP to
|
||||
<n> seconds (0 means no limit).
|
||||
.TP
|
||||
.B -pc
|
||||
Disable protocol field compression negotiation (use default, i.e.
|
||||
protocol field compression disabled).
|
||||
.TP
|
||||
.B persist
|
||||
Do not exit after a connection is terminated; instead try to reopen
|
||||
the connection.
|
||||
.TP
|
||||
.B pred1comp
|
||||
Attempt to request that the peer send the local system frames which
|
||||
have been compressed by the Predictor-1 compression. The compression
|
||||
protocols must be loaded or this option will be ignored.
|
||||
.TP
|
||||
.B -pred1comp
|
||||
Do not accept Predictor-1 comprssion, even if the peer wants to send
|
||||
this type of compression and support has been defined in the kernel.
|
||||
.TP
|
||||
.B proxyarp
|
||||
Add an entry to this system's ARP [Address Resolution Protocol] table
|
||||
with the IP address of the peer and the Ethernet address of this
|
||||
system.
|
||||
.TP
|
||||
.B \-proxyarp
|
||||
Disable the \fBproxyarp\fR option. The system administrator who
|
||||
wishes to prevent users from creating proxy ARP entries with
|
||||
\fIpppd\fR can do so by placing this option in the /etc/ppp/options
|
||||
file.
|
||||
.TP
|
||||
.B remotename \fI<n>
|
||||
Set the assumed name of the remote system for authentication purposes
|
||||
to <n>.
|
||||
.TP
|
||||
.B +ua \fI<p>
|
||||
Agree to authenticate using PAP [Password Authentication Protocol] if
|
||||
requested by the peer, and
|
||||
use the data in file <p> for the user and password to send to the
|
||||
peer. The file contains the remote user name, followed by a newline,
|
||||
followed by the remote password, followed by a newline. This option
|
||||
is obsolescent.
|
||||
.TP
|
||||
.B usehostname
|
||||
Enforce the use of the hostname as the name of the local system for
|
||||
authentication purposes (overrides the
|
||||
.B name
|
||||
option).
|
||||
.TP
|
||||
.B user \fI<u>
|
||||
Set the user name to use for authenticating this machine with the peer
|
||||
using PAP to <u>.
|
||||
.TP
|
||||
.B -vj
|
||||
Disable negotiation of Van Jacobson style TCP/IP header compression (use
|
||||
default, i.e. no compression).
|
||||
.TP
|
||||
.B -vjccomp
|
||||
Disable the connection-ID compression option in Van Jacobson style
|
||||
TCP/IP header compression. With this option, \fIpppd\fR will not omit
|
||||
the connection-ID byte from Van Jacobson compressed TCP/IP headers,
|
||||
nor ask the peer to do so.
|
||||
.TP
|
||||
.B vj-max-slots \fIn
|
||||
Sets the number of connection slots to be used by the Van Jacobson
|
||||
TCP/IP header compression and decompression code to \fIn\fR, which
|
||||
must be between 2 and 16 (inclusive).
|
||||
.TP
|
||||
.B xonxoff
|
||||
Use software flow control (i.e. XON/XOFF) to control the flow of data on
|
||||
the serial port. This option is only implemented on Linux systems
|
||||
at present.
|
||||
.SH OPTIONS FILES
|
||||
Options can be taken from files as well as the command line.
|
||||
.I pppd
|
||||
reads options from the files /etc/ppp/options and ~/.ppprc before
|
||||
looking at the command line. An options file is parsed into a series
|
||||
of words, delimited by whitespace. Whitespace can be included in a
|
||||
word by enclosing the word in quotes ("). A backslash (\\) quotes the
|
||||
following character. A hash (#) starts a comment, which continues
|
||||
until the end of the line.
|
||||
.SH AUTHENTICATION
|
||||
.I pppd
|
||||
provides system administrators with sufficient access control that PPP
|
||||
access to a server machine can be provided to legitimate users without
|
||||
fear of compromising the security of the server or the network it's
|
||||
on. In part this is provided by the /etc/ppp/options file, where the
|
||||
administrator can place options to require authentication whenever
|
||||
.I pppd
|
||||
is run, and in part by the PAP and CHAP secrets files, where the
|
||||
administrator can restrict the set of IP addresses which individual
|
||||
users may use.
|
||||
.LP
|
||||
The default behaviour of
|
||||
.I pppd
|
||||
is to agree to authenticate if requested, and to not
|
||||
require authentication from the peer. However,
|
||||
.I pppd
|
||||
will not agree to
|
||||
authenticate itself with a particular protocol if it has no secrets
|
||||
which could be used to do so.
|
||||
.LP
|
||||
Authentication is based on secrets, which are selected from secrets
|
||||
files (/etc/ppp/pap-secrets for PAP, /etc/ppp/chap-secrets for CHAP).
|
||||
Both secrets files have the same format, and both can store secrets
|
||||
for several combinations of server (authenticating peer) and client
|
||||
(peer being authenticated). Note that
|
||||
.I pppd
|
||||
can be both a server
|
||||
and client, and that different protocols can be used in the two
|
||||
directions if desired.
|
||||
.LP
|
||||
A secrets file is parsed into words as for a options file. A secret
|
||||
is specified by a line containing at least 3 words, in the order
|
||||
client name, server name, secret. Any following words on the same line are
|
||||
taken to be a list of acceptable IP addresses for that client. If
|
||||
there are only 3 words on the line, it is assumed that any IP address
|
||||
is OK; to disallow all IP addresses, use "-". If the secret starts
|
||||
with an `@', what follows is assumed to be the name of a file from
|
||||
which to read the secret. A "*" as the client or server name matches
|
||||
any name. When selecting a secret, \fIpppd\fR takes the best match, i.e.
|
||||
the match with the fewest wildcards.
|
||||
.LP
|
||||
Thus a secrets file contains both secrets for use in authenticating
|
||||
other hosts, plus secrets which we use for authenticating ourselves to
|
||||
others. Which secret to use is chosen based on the names of the host
|
||||
(the `local name') and its peer (the `remote name'). The local name
|
||||
is set as follows:
|
||||
.TP 3
|
||||
if the \fBusehostname\fR option is given,
|
||||
then the local name is the hostname of this machine
|
||||
(with the domain appended, if given)
|
||||
.TP 3
|
||||
else if the \fBname\fR option is given,
|
||||
then use the argument of the first \fBname\fR option seen
|
||||
.TP 3
|
||||
else if the local IP address is specified with a hostname,
|
||||
then use that name
|
||||
.TP 3
|
||||
else use the hostname of this machine (with the domain appended, if given)
|
||||
.LP
|
||||
When authenticating ourselves using PAP, there is also a `username'
|
||||
which is the local name by default, but can be set with the \fBuser\fR
|
||||
option or the \fB+ua\fR option.
|
||||
.LP
|
||||
The remote name is set as follows:
|
||||
.TP 3
|
||||
if the \fBremotename\fR option is given,
|
||||
then use the argument of the last \fBremotename\fR option seen
|
||||
.TP 3
|
||||
else if the remote IP address is specified with a hostname,
|
||||
then use that host name
|
||||
.TP 3
|
||||
else the remote name is the null string "".
|
||||
.LP
|
||||
Secrets are selected from the PAP secrets file as follows:
|
||||
.TP 2
|
||||
*
|
||||
For authenticating the peer, look for a secret with client ==
|
||||
username specified in the PAP authenticate-request, and server ==
|
||||
local name.
|
||||
.TP 2
|
||||
*
|
||||
For authenticating ourselves to the peer, look for a secret with
|
||||
client == our username, server == remote name.
|
||||
.LP
|
||||
When authenticating the peer with PAP, a secret of "" matches any
|
||||
password supplied by the peer. If the password doesn't match the
|
||||
secret, the password is encrypted using crypt() and checked against
|
||||
the secret again; thus secrets for authenticating the peer can be
|
||||
stored in encrypted form. If the \fBpapcrypt\fR option is given, the
|
||||
first (unencrypted) comparison is omitted, for better security.
|
||||
.LP
|
||||
If the \fBlogin\fR option was specified, the
|
||||
username and password are also checked against the system password
|
||||
database. Thus, the system administrator can set up the pap-secrets
|
||||
file to allow PPP access only to certain users, and to restrict the
|
||||
set of IP addresses that each user can use. Typically, when using the
|
||||
\fBlogin\fR option, the secret in /etc/ppp/pap-secrets would be "", to
|
||||
avoid the need to have the same secret in two places.
|
||||
.LP
|
||||
Secrets are selected from the CHAP secrets file as follows:
|
||||
.TP 2
|
||||
*
|
||||
For authenticating the peer, look for a secret with client == name
|
||||
specified in the CHAP-Response message, and server == local name.
|
||||
.TP 2
|
||||
*
|
||||
For authenticating ourselves to the peer, look for a secret with
|
||||
client == local name, and server == name specified in the
|
||||
CHAP-Challenge message.
|
||||
.LP
|
||||
Authentication must be satisfactorily completed before IPCP (or any
|
||||
other Network Control Protocol) can be started. If authentication
|
||||
fails, \fIpppd\fR will terminated the link (by closing LCP). If IPCP
|
||||
negotiates an unacceptable IP address for the remote host, IPCP will
|
||||
be closed. IP packets can only be sent or received when IPCP is open.
|
||||
.LP
|
||||
In some cases it is desirable to allow some hosts which can't
|
||||
authenticate themselves to connect and use one of a restricted set of
|
||||
IP addresses, even when the local host generally requires
|
||||
authentication. If the peer refuses to authenticate itself when
|
||||
requested, \fIpppd\fR takes that as equivalent to authenticating with
|
||||
PAP using the empty string for the username and password. Thus, by
|
||||
adding a line to the pap-secrets file which specifies the empty string
|
||||
for the client and password, it is possible to allow restricted access
|
||||
to hosts which refuse to authenticate themselves.
|
||||
.SH ROUTING
|
||||
.LP
|
||||
When IPCP negotiation is completed successfully,
|
||||
.I pppd
|
||||
will inform the kernel of the local and remote IP addresses for the
|
||||
ppp interface. This is sufficient to create a
|
||||
host route to the remote end of the link, which will enable the peers
|
||||
to exchange IP packets. Communication with other machines generally
|
||||
requires further modification to routing tables and/or ARP (Address
|
||||
Resolution Protocol) tables. In some cases this will be done
|
||||
automatically through the actions of the \fIrouted\fR or \fIgated\fR
|
||||
daemons, but in most cases some further intervention is required.
|
||||
.LP
|
||||
Sometimes it is desirable
|
||||
to add a default route through the remote host, as in the case of a
|
||||
machine whose only connection to the Internet is through the ppp
|
||||
interface. The \fBdefaultroute\fR option causes \fIpppd\fR to create such a
|
||||
default route when IPCP comes up, and delete it when the link is
|
||||
terminated.
|
||||
.LP
|
||||
In some cases it is desirable to use proxy ARP, for example on a
|
||||
server machine connected to a LAN, in order to allow other hosts to
|
||||
communicate with the remote host. The \fBproxyarp\fR option causes \fIpppd\fR
|
||||
to look for a network interface on the same subnet as the remote host
|
||||
(an interface supporting broadcast and ARP, which is up and not a
|
||||
point-to-point or loopback interface). If found, \fIpppd\fR creates a
|
||||
permanent, published ARP entry with the IP address of the remote host
|
||||
and the hardware address of the network interface found.
|
||||
.SH EXAMPLES
|
||||
.LP
|
||||
In the simplest case, you can connect the serial ports of two machines
|
||||
and issue a command like
|
||||
.IP
|
||||
pppd /dev/ttya 9600 passive
|
||||
.LP
|
||||
to each machine, assuming there is no \fIgetty\fR running on the
|
||||
serial ports. If one machine has a \fIgetty\fR running, you can use
|
||||
\fIkermit\fR or \fItip\fR on the other machine to log in to the first
|
||||
machine and issue a command like
|
||||
.IP
|
||||
pppd passive
|
||||
.LP
|
||||
Then exit from the communications program (making sure the connection
|
||||
isn't dropped), and issue a command like
|
||||
.IP
|
||||
pppd /dev/ttya 9600
|
||||
.LP
|
||||
The process of logging in to the other machine and starting \fIpppd\fR
|
||||
can be automated by using the \fBconnect\fR option to run \fIchat\fR,
|
||||
for example:
|
||||
.IP
|
||||
pppd /dev/ttya 38400 connect 'chat "" "" "login:" "username"
|
||||
"Password:" "password" "% " "exec pppd passive"'
|
||||
.LP
|
||||
(Note however that running chat like this will leave the password
|
||||
visible in the parameter list of pppd and chat.)
|
||||
.LP
|
||||
If your serial connection is any more complicated than a piece of
|
||||
wire, you may need to arrange for some control characters to be
|
||||
escaped. In particular, it is often useful to escape XON (^Q) and
|
||||
XOFF (^S), using \fBasyncmap a0000\fR. If the path includes a telnet,
|
||||
you probably should escape ^] as well (\fBasyncmap 200a0000\fR).
|
||||
If the path includes an rlogin, you will need to use the \fBescape
|
||||
ff\fR option on the end which is running the rlogin client, since many
|
||||
rlogin implementations are not
|
||||
transparent; they will remove the sequence [0xff, 0xff, 0x73, 0x73,
|
||||
followed by any 8 bytes] from the stream.
|
||||
.SH DIAGNOSTICS
|
||||
.LP
|
||||
Messages are sent to the syslog daemon using facility LOG_DAEMON.
|
||||
(This can be overriden by recompiling \fIpppd\fR with the macro
|
||||
LOG_PPP defined as the desired facility.) In order to see the error
|
||||
and debug messages, you will need to edit your /etc/syslog.conf file
|
||||
to direct the messages to the desired output device or file.
|
||||
.LP
|
||||
The \fBdebug\fR option causes the contents of all control packets sent
|
||||
or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets.
|
||||
This can be useful if the PPP negotiation does not succeed.
|
||||
If debugging is enabled at compile time, the \fBdebug\fR option also
|
||||
causes other debugging messages to be logged.
|
||||
.LP
|
||||
Debugging can also be enabled or disabled by sending a
|
||||
SIGUSR1 to the
|
||||
.I pppd
|
||||
process. This signal acts as a toggle.
|
||||
.SH FILES
|
||||
.TP
|
||||
.B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others)
|
||||
Process-ID for \fIpppd\fR process on ppp interface unit \fIn\fR.
|
||||
.TP
|
||||
.B /etc/ppp/ip-up
|
||||
A program or script which is executed when the link is available for
|
||||
sending and receiving IP packets (that is, IPCP has come up). It is
|
||||
executed with the parameters
|
||||
.IP
|
||||
\fIinterface-name tty-device speed local-IP-address
|
||||
remote-IP-address\fR
|
||||
.IP
|
||||
and with its standard input,
|
||||
output and error streams redirected to \fB/dev/null\fR.
|
||||
.IP
|
||||
This program or script is executed with the same real and effective
|
||||
user-ID as \fIpppd\fR, that is, at least the effective user-ID and
|
||||
possibly the real user-ID will be \fBroot\fR. This is so that it can
|
||||
be used to manipulate routes, run privileged daemons (e.g.
|
||||
\fBsendmail\fR), etc. Be careful that the contents of the
|
||||
/etc/ppp/ip-up and /etc/ppp/ip-down scripts do not compromise your
|
||||
system's security.
|
||||
.TP
|
||||
.B /etc/ppp/ip-down
|
||||
A program or script which is executed when the link is no longer
|
||||
available for sending and receiving IP packets. This script can be
|
||||
used for undoing the effects of the /etc/ppp/ip-up script. It is
|
||||
invoked with the same parameters as the ip-up script, and the same
|
||||
security considerations apply, since it is executed with the same
|
||||
effective and real user-IDs as \fIpppd\fR.
|
||||
.TP
|
||||
.B /etc/ppp/ipx-up
|
||||
A program or script which is executed when the link is available for
|
||||
sending and receiving IPX packets (that is, IPXCP has come up). It is
|
||||
executed with the parameters
|
||||
.IP
|
||||
\fIinterface-name tty-device speed network-number local-IPX-node-address
|
||||
remote-IPX-node-address local-IPX-routing-protocol remote-IPX-routing-protocol
|
||||
local-IPX-router-name remote-IPX-router-name ipparam pppd-pid\fR
|
||||
.IP
|
||||
and with its standard input,
|
||||
output and error streams redirected to \fB/dev/null\fR.
|
||||
.br
|
||||
.IP
|
||||
The local-IPX-routing-protocol and remote-IPX-routing-protocol field
|
||||
may be one of the following:
|
||||
.IP
|
||||
NONE to indicate that there is no routing protocol
|
||||
.br
|
||||
RIP to indicate that RIP/SAP should be used
|
||||
.br
|
||||
NLSP to indicate that Novell NLSP should be used
|
||||
.br
|
||||
RIP NLSP to indicate that both RIP/SAP and NLSP should be used
|
||||
.br
|
||||
.IP
|
||||
This program or script is executed with the same real and effective
|
||||
user-ID as \fIpppd\fR, that is, at least the effective user-ID and
|
||||
possibly the real user-ID will be \fBroot\fR. This is so that it can
|
||||
be used to manipulate routes, run privileged daemons (e.g.
|
||||
\fBripd\fR), etc. Be careful that the contents of the
|
||||
/etc/ppp/ipx-up and /etc/ppp/ipx-down scripts do not compromise your
|
||||
system's security.
|
||||
.TP
|
||||
.B /etc/ppp/ipx-down
|
||||
A program or script which is executed when the link is no longer
|
||||
available for sending and receiving IPX packets. This script can be
|
||||
used for undoing the effects of the /etc/ppp/ipx-up script. It is
|
||||
invoked with the same parameters as the ipx-up script, and the same
|
||||
security considerations apply, since it is executed with the same
|
||||
effective and real user-IDs as \fIpppd\fR.
|
||||
.TP
|
||||
.B /etc/ppp/pap-secrets
|
||||
Usernames, passwords and IP addresses for PAP authentication.
|
||||
.TP
|
||||
.B /etc/ppp/chap-secrets
|
||||
Names, secrets and IP addresses for CHAP authentication.
|
||||
.TP
|
||||
.B /etc/ppp/options
|
||||
System default options for
|
||||
.I pppd,
|
||||
read before user default options or command-line options.
|
||||
.TP
|
||||
.B ~/.ppprc
|
||||
User default options, read before command-line options.
|
||||
.TP
|
||||
.B /etc/ppp/options.\fIttyname
|
||||
System default options for the serial port being used, read after
|
||||
command-line options.
|
||||
.SH SEE ALSO
|
||||
.TP
|
||||
.B RFC1144
|
||||
Jacobson, V.
|
||||
.I Compressing TCP/IP headers for low-speed serial links.
|
||||
1990 February.
|
||||
.TP
|
||||
.B RFC1321
|
||||
Rivest, R.
|
||||
.I The MD5 Message-Digest Algorithm.
|
||||
1992 April.
|
||||
.TP
|
||||
.B RFC1332
|
||||
McGregor, G.
|
||||
.I PPP Internet Protocol Control Protocol (IPCP).
|
||||
1992 May.
|
||||
.TP
|
||||
.B RFC1334
|
||||
Lloyd, B.; Simpson, W.A.
|
||||
.I PPP authentication protocols.
|
||||
1992 October.
|
||||
.TP
|
||||
.B RFC1548
|
||||
Simpson, W.A.
|
||||
.I The Point\-to\-Point Protocol (PPP).
|
||||
1993 December.
|
||||
.TP
|
||||
.B RFC1549
|
||||
Simpson, W.A.
|
||||
.I PPP in HDLC Framing.
|
||||
1993 December
|
||||
.SH NOTES
|
||||
The following signals have the specified effect when sent to the
|
||||
.I pppd
|
||||
process.
|
||||
.TP
|
||||
.B SIGINT, SIGTERM
|
||||
These signals cause \fBpppd\fR to terminate the link (by closing LCP),
|
||||
restore the serial device settings, and exit.
|
||||
.TP
|
||||
.B SIGHUP
|
||||
This signal causes \fBpppd\fR to terminate the link, restore the
|
||||
serial device settings, and close the serial device. If the
|
||||
\fBpersist\fR option has been specified, \fBpppd\fR will try to reopen
|
||||
the serial device and start another connection. Otherwise \fBpppd\fR
|
||||
will exit.
|
||||
.TP
|
||||
.B SIGUSR2
|
||||
This signal causes
|
||||
.B pppd
|
||||
to renegotiate compression. This can be useful to re-enable
|
||||
compression after it has been disabled as a result of a fatal
|
||||
decompression error. With the BSD Compress scheme, fatal
|
||||
decompression errors generally indicate a bug in one or other
|
||||
implementation.
|
||||
|
||||
.SH AUTHORS
|
||||
Drew Perkins,
|
||||
Brad Clements,
|
||||
Karl Fox,
|
||||
Greg Christy,
|
||||
Brad Parker,
|
||||
Paul Mackerras (paulus@cs.anu.edu.au).
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* ipxcp.h - IPX Control Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ipxcp.h,v 1.1 1997/03/07 16:01:22 hipp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
#define IPX_NETWORK_NUMBER 1 /* IPX Network Number */
|
||||
#define IPX_NODE_NUMBER 2
|
||||
#define IPX_COMPRESSION_PROTOCOL 3
|
||||
#define IPX_ROUTER_PROTOCOL 4
|
||||
#define IPX_ROUTER_NAME 5
|
||||
#define IPX_COMPLETE 6
|
||||
|
||||
|
||||
typedef struct ipxcp_options {
|
||||
int neg_node : 1; /* Negotiate IPX node number? */
|
||||
int req_node : 1; /* Ask peer to send IPX node number? */
|
||||
|
||||
int neg_nn : 1; /* Negotiate IPX network number? */
|
||||
int req_nn : 1; /* Ask peer to send IPX network number */
|
||||
|
||||
int neg_name : 1; /* Negotiate IPX router name */
|
||||
int neg_complete : 1; /* Negotiate completion */
|
||||
int neg_router : 1; /* Negotiate IPX router number */
|
||||
|
||||
int accept_local : 1; /* accept peer's value for ournode */
|
||||
int accept_remote : 1; /* accept peer's value for hisnode */
|
||||
int accept_network : 1; /* accept network number */
|
||||
|
||||
u_int32_t his_network; /* base network number */
|
||||
u_int32_t our_network; /* our value for network number */
|
||||
u_int32_t network; /* the final network number */
|
||||
|
||||
u_char his_node[6]; /* peer's node number */
|
||||
u_char our_node[6]; /* our node number */
|
||||
u_char name [48]; /* name of the router */
|
||||
int router; /* routing protocol */
|
||||
} ipxcp_options;
|
||||
|
||||
extern fsm ipxcp_fsm[];
|
||||
extern ipxcp_options ipxcp_wantoptions[];
|
||||
extern ipxcp_options ipxcp_gotoptions[];
|
||||
extern ipxcp_options ipxcp_allowoptions[];
|
||||
extern ipxcp_options ipxcp_hisoptions[];
|
||||
|
||||
extern struct protent ipxcp_protent;
|
||||
|
||||
int ipxcp_getunit __P((int));
|
||||
void ipxcp_freeunit __P((int));
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright 1989 - 1994, John F. Haugh II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John F. Haugh, II
|
||||
* and other contributors.
|
||||
* 4. Neither the name of John F. Haugh, II nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL JOHN HAUGH OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extracted from age.c and made part of libshadow.a - may be useful
|
||||
* in other shadow-aware programs. --marekm
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef BSD
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include <shadow.h>
|
||||
|
||||
#define DAY (24L*3600L)
|
||||
#define SCALE DAY
|
||||
|
||||
extern time_t time ();
|
||||
|
||||
/*
|
||||
* isexpired - determine if account is expired yet
|
||||
*
|
||||
* isexpired calculates the expiration date based on the
|
||||
* password expiration criteria.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
|
||||
int
|
||||
isexpired (pw, sp)
|
||||
const struct passwd *pw;
|
||||
const struct spwd *sp;
|
||||
{
|
||||
long now;
|
||||
now = time ((time_t *) 0) / SCALE;
|
||||
|
||||
/*
|
||||
* Quick and easy - there is an expired account field
|
||||
* along with an inactive account field. Do the expired
|
||||
* one first since it is worse.
|
||||
*/
|
||||
|
||||
if (sp->sp_expire > 0 && sp->sp_expire < now)
|
||||
return 3;
|
||||
|
||||
/*
|
||||
* Hack: last changed date 1970-01-01 (not very likely) means that
|
||||
* the password must be changed as soon as possible. This is used
|
||||
* by passwd -e (SunOS 4.x has a similar feature). --marekm
|
||||
*/
|
||||
if (sp->sp_lstchg == 0)
|
||||
return 1;
|
||||
|
||||
if (sp->sp_inact > 0 && sp->sp_lstchg > 0 && sp->sp_max > 0 &&
|
||||
sp->sp_inact + sp->sp_lstchg + sp->sp_max < now)
|
||||
return 2;
|
||||
/*
|
||||
* The last and max fields must be present for an account
|
||||
* to have an expired password. A maximum of >10000 days
|
||||
* is considered to be infinite.
|
||||
*/
|
||||
|
||||
if (sp->sp_lstchg == -1 ||
|
||||
sp->sp_max == -1 || sp->sp_max >= (10000L*DAY/SCALE))
|
||||
return 0;
|
||||
/*
|
||||
* Calculate today's day and the day on which the password
|
||||
* is going to expire. If that date has already passed,
|
||||
* the password has expired.
|
||||
*/
|
||||
|
||||
if (sp->sp_lstchg + sp->sp_max < now)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* lcp.h - Link Control Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcp.h,v 1.1 1997/03/07 16:01:27 hipp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
#define CI_MRU 1 /* Maximum Receive Unit */
|
||||
#define CI_ASYNCMAP 2 /* Async Control Character Map */
|
||||
#define CI_AUTHTYPE 3 /* Authentication Type */
|
||||
#define CI_QUALITY 4 /* Quality Protocol */
|
||||
#define CI_MAGICNUMBER 5 /* Magic Number */
|
||||
#define CI_PCOMPRESSION 7 /* Protocol Field Compression */
|
||||
#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */
|
||||
#define CI_CALLBACK 13 /* callback */
|
||||
|
||||
#define CI_MPMRRU 17
|
||||
#define CI_MPSHORTSEQ 18
|
||||
#define CI_MPDISCRIMINATOR 19
|
||||
|
||||
/*
|
||||
* LCP-specific packet types.
|
||||
*/
|
||||
#define PROTREJ 8 /* Protocol Reject */
|
||||
#define ECHOREQ 9 /* Echo Request */
|
||||
#define ECHOREP 10 /* Echo Reply */
|
||||
#define DISCREQ 11 /* Discard Request */
|
||||
#define CBCP_OPT 6
|
||||
|
||||
struct cbcp {
|
||||
int type;
|
||||
unsigned char *message;
|
||||
int mlen;
|
||||
};
|
||||
|
||||
/*
|
||||
* The state of options is described by an lcp_options structure.
|
||||
*/
|
||||
typedef struct lcp_options {
|
||||
int passive : 1; /* Don't die if we don't get a response */
|
||||
int silent : 1; /* Wait for the other end to start first */
|
||||
int restart : 1; /* Restart vs. exit after close */
|
||||
int neg_mru : 1; /* Negotiate the MRU? */
|
||||
int neg_asyncmap : 1; /* Negotiate the async map? */
|
||||
int neg_upap : 1; /* Ask for UPAP authentication? */
|
||||
int neg_chap : 1; /* Ask for CHAP authentication? */
|
||||
int neg_magicnumber : 1; /* Ask for magic number? */
|
||||
int neg_pcompression : 1; /* HDLC Protocol Field Compression? */
|
||||
int neg_accompression : 1; /* HDLC Address/Control Field Compression? */
|
||||
int neg_lqr : 1; /* Negotiate use of Link Quality Reports */
|
||||
|
||||
int neg_mpshortseq : 1; /* MP 12 bit instead of 24 bit sequence numbers */
|
||||
int neg_mpdiscr : 1; /* MP protocol ? */
|
||||
int neg_mpmrru : 1;
|
||||
int neg_mp : 1;
|
||||
int neg_cbcp : 1;
|
||||
u_char mp_class; /* MP discri. class */
|
||||
u_char mp_addr[20]; /* MP discri. addr */
|
||||
u_char mp_alen;
|
||||
u_short mp_mrru; /* MP mrru */
|
||||
u_char cb_type;
|
||||
u_char cb_num[20];
|
||||
u_char cb_numlen;
|
||||
|
||||
u_short mru; /* Value of MRU */
|
||||
u_char chap_mdtype; /* which MD type (hashing algorithm) */
|
||||
u_int32_t asyncmap; /* Value of async map */
|
||||
u_int32_t magicnumber;
|
||||
int numloops; /* Number of loops during magic number neg. */
|
||||
u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */
|
||||
struct cbcp cbcp;
|
||||
} lcp_options;
|
||||
|
||||
extern fsm lcp_fsm[];
|
||||
extern lcp_options lcp_wantoptions[];
|
||||
extern lcp_options lcp_gotoptions[];
|
||||
extern lcp_options lcp_allowoptions[];
|
||||
extern lcp_options lcp_hisoptions[];
|
||||
extern u_int32_t xmit_accm[][8];
|
||||
|
||||
extern struct protent lcp_protent;
|
||||
|
||||
#define DEFMRU 1500 /* Try for this */
|
||||
#define MINMRU 128 /* No MRUs below this */
|
||||
#define MAXMRU 16384 /* Normally limit MRU to this */
|
||||
|
||||
void lcp_open __P((int));
|
||||
void lcp_close __P((int,char *));
|
||||
void lcp_lowerup __P((int));
|
||||
void lcp_lowerdown __P((int));
|
||||
void lcp_sprotrej __P((int, u_char *, int));
|
||||
|
||||
/* Default number of times we receive our magic number from the peer
|
||||
before deciding the link is looped-back. */
|
||||
#define DEFLOOPBACKFAIL 5
|
||||
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* magic.c - PPP Magic Number routines.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: magic.c,v 1.1 1997/03/07 16:01:27 hipp Exp $";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include "fsm.h"
|
||||
#include "pppd.h"
|
||||
#include "magic.h"
|
||||
|
||||
#if 0
|
||||
static u_int32_t next; /* Next value to return */
|
||||
#endif
|
||||
|
||||
extern long mrand48 __P((void));
|
||||
extern void srand48 __P((long));
|
||||
|
||||
|
||||
/*
|
||||
* magic_init - Initialize the magic number generator.
|
||||
*
|
||||
* Attempts to compute a random number seed which will not repeat.
|
||||
* The current method uses the current hostid, current process ID
|
||||
* and current time, currently.
|
||||
*/
|
||||
void
|
||||
magic_init()
|
||||
{
|
||||
long seed;
|
||||
struct timeval t;
|
||||
struct utsname uts;
|
||||
unsigned long val=0x12345678;
|
||||
int i;
|
||||
|
||||
gettimeofday(&t, NULL);
|
||||
if(uname(&uts)==0) {
|
||||
unsigned char *p = (unsigned char *) &uts;
|
||||
int len = sizeof(struct utsname);
|
||||
int step=47;
|
||||
if(len % step == 0) /* unlikely, but ;) */
|
||||
step = 43;
|
||||
for(i=0;i<len;i++) {
|
||||
if(val & 0x80000000)
|
||||
val = ( (val<<1) + p[ (i*step)%len ]) + 1;
|
||||
else
|
||||
val = ( (val<<1) + p[ (i*step)%len ]);
|
||||
val &= 0xffffffff;
|
||||
}
|
||||
}
|
||||
else
|
||||
val = gethostid();
|
||||
|
||||
seed = val ^ t.tv_sec ^ t.tv_usec ^ getpid();
|
||||
srand48(seed);
|
||||
}
|
||||
|
||||
/*
|
||||
* magic - Returns the next magic number.
|
||||
*/
|
||||
u_int32_t
|
||||
magic(void)
|
||||
{
|
||||
return (u_int32_t) mrand48();
|
||||
}
|
||||
|
||||
#ifdef NO_DRAND48
|
||||
/*
|
||||
* Substitute procedures for those systems which don't have
|
||||
* drand48 et al.
|
||||
*/
|
||||
|
||||
double
|
||||
drand48()
|
||||
{
|
||||
return (double)random() / (double)0x7fffffffL; /* 2**31-1 */
|
||||
}
|
||||
|
||||
long
|
||||
mrand48()
|
||||
{
|
||||
return random();
|
||||
}
|
||||
|
||||
void
|
||||
srand48(seedval)
|
||||
long seedval;
|
||||
{
|
||||
srandom((int)seedval);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* magic.h - PPP Magic Number definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: magic.h,v 1.1 1997/03/07 16:01:28 hipp Exp $
|
||||
*/
|
||||
|
||||
void magic_init __P((void)); /* Initialize the magic number generator */
|
||||
u_int32_t magic __P((void)); /* Returns the next magic number */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
** ********************************************************************
|
||||
** md4.c -- Implementation of MD4 Message Digest Algorithm **
|
||||
** Updated: 2/16/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
** To use MD4:
|
||||
** -- Include md4.h in your program
|
||||
** -- Declare an MDstruct MD to hold the state of the digest
|
||||
** computation.
|
||||
** -- Initialize MD using MDbegin(&MD)
|
||||
** -- For each full block (64 bytes) X you wish to process, call
|
||||
** MDupdate(&MD,X,512)
|
||||
** (512 is the number of bits in a full block.)
|
||||
** -- For the last block (less than 64 bytes) you wish to process,
|
||||
** MDupdate(&MD,X,n)
|
||||
** where n is the number of bits in the partial block. A partial
|
||||
** block terminates the computation, so every MD computation
|
||||
** should terminate by processing a partial block, even if it
|
||||
** has n = 0.
|
||||
** -- The message digest is available in MD.buffer[0] ...
|
||||
** MD.buffer[3]. (Least-significant byte of each word
|
||||
** should be output first.)
|
||||
** -- You can print out the digest using MDprint(&MD)
|
||||
*/
|
||||
|
||||
/* Implementation notes:
|
||||
** This implementation assumes that ints are 32-bit quantities.
|
||||
** If the machine stores the least-significant byte of an int in the
|
||||
** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
|
||||
** should be set to TRUE. Otherwise (e.g., SUNS), LOWBYTEFIRST
|
||||
** should be set to FALSE. Note that on machines with LOWBYTEFIRST
|
||||
** FALSE the routine MDupdate modifies has a side-effect on its input
|
||||
** array (the order of bytes in each word are reversed). If this is
|
||||
** undesired a call to MDreverse(X) can reverse the bytes of X back
|
||||
** into order after each call to MDupdate.
|
||||
**
|
||||
** NOTE: LOWBYTEFIRST removed by Eric Rosenquist in favour of run-time
|
||||
** detection to simplify build process.
|
||||
*/
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
/* Compile-time includes
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <netinet/in.h>
|
||||
#include "md4.h"
|
||||
#include "pppd.h"
|
||||
|
||||
/* Compile-time declarations of MD4 "magic constants".
|
||||
*/
|
||||
#define I0 0x67452301 /* Initial values for MD buffer */
|
||||
#define I1 0xefcdab89
|
||||
#define I2 0x98badcfe
|
||||
#define I3 0x10325476
|
||||
#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
|
||||
#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
|
||||
/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
|
||||
** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
|
||||
** Table 2, page 660.
|
||||
*/
|
||||
|
||||
#define fs1 3 /* round 1 shift amounts */
|
||||
#define fs2 7
|
||||
#define fs3 11
|
||||
#define fs4 19
|
||||
#define gs1 3 /* round 2 shift amounts */
|
||||
#define gs2 5
|
||||
#define gs3 9
|
||||
#define gs4 13
|
||||
#define hs1 3 /* round 3 shift amounts */
|
||||
#define hs2 9
|
||||
#define hs3 11
|
||||
#define hs4 15
|
||||
|
||||
/* Compile-time macro declarations for MD4.
|
||||
** Note: The "rot" operator uses the variable "tmp".
|
||||
** It assumes tmp is declared as unsigned int, so that the >>
|
||||
** operator will shift in zeros rather than extending the sign bit.
|
||||
*/
|
||||
#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
|
||||
#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
|
||||
#define h(X,Y,Z) (X^Y^Z)
|
||||
#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
|
||||
#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
|
||||
#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
|
||||
#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
|
||||
|
||||
/* MDprint(MDp)
|
||||
** Print message digest buffer MDp as 32 hexadecimal digits.
|
||||
** Order is from low-order byte of buffer[0] to high-order byte of
|
||||
** buffer[3].
|
||||
** Each byte is printed with high-order hexadecimal digit first.
|
||||
** This is a user-callable routine.
|
||||
*/
|
||||
void
|
||||
MDprint(MDp)
|
||||
MDptr MDp;
|
||||
{ int i,j;
|
||||
for (i=0;i<4;i++)
|
||||
for (j=0;j<32;j=j+8)
|
||||
printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
|
||||
}
|
||||
|
||||
/* MDbegin(MDp)
|
||||
** Initialize message digest buffer MDp.
|
||||
** This is a user-callable routine.
|
||||
*/
|
||||
void
|
||||
MDbegin(MDp)
|
||||
MDptr MDp;
|
||||
{ int i;
|
||||
MDp->buffer[0] = I0;
|
||||
MDp->buffer[1] = I1;
|
||||
MDp->buffer[2] = I2;
|
||||
MDp->buffer[3] = I3;
|
||||
for (i=0;i<8;i++) MDp->count[i] = 0;
|
||||
MDp->done = 0;
|
||||
}
|
||||
|
||||
/* MDreverse(X)
|
||||
** Reverse the byte-ordering of every int in X.
|
||||
** Assumes X is an array of 16 ints.
|
||||
** The macro revx reverses the byte-ordering of the next word of X.
|
||||
*/
|
||||
#define revx { t = (*X << 16) | (*X >> 16); \
|
||||
*X++ = ((t & 0xFF00FF00) >> 8) | ((t & 0x00FF00FF) << 8); }
|
||||
void
|
||||
MDreverse(X)
|
||||
unsigned int *X;
|
||||
{ register unsigned int t;
|
||||
revx; revx; revx; revx; revx; revx; revx; revx;
|
||||
revx; revx; revx; revx; revx; revx; revx; revx;
|
||||
}
|
||||
|
||||
/* MDblock(MDp,X)
|
||||
** Update message digest buffer MDp->buffer using 16-word data block X.
|
||||
** Assumes all 16 words of X are full of data.
|
||||
** Does not update MDp->count.
|
||||
** This routine is not user-callable.
|
||||
*/
|
||||
static void
|
||||
MDblock(MDp,X)
|
||||
MDptr MDp;
|
||||
unsigned int *X;
|
||||
{
|
||||
register unsigned int tmp, A, B, C, D;
|
||||
static int low_byte_first = -1;
|
||||
|
||||
if (low_byte_first == -1) {
|
||||
low_byte_first = (htons((unsigned short int)1) != 1);
|
||||
}
|
||||
|
||||
if (low_byte_first == 0) {
|
||||
MDreverse(X);
|
||||
}
|
||||
|
||||
A = MDp->buffer[0];
|
||||
B = MDp->buffer[1];
|
||||
C = MDp->buffer[2];
|
||||
D = MDp->buffer[3];
|
||||
/* Update the message digest buffer */
|
||||
ff(A , B , C , D , 0 , fs1); /* Round 1 */
|
||||
ff(D , A , B , C , 1 , fs2);
|
||||
ff(C , D , A , B , 2 , fs3);
|
||||
ff(B , C , D , A , 3 , fs4);
|
||||
ff(A , B , C , D , 4 , fs1);
|
||||
ff(D , A , B , C , 5 , fs2);
|
||||
ff(C , D , A , B , 6 , fs3);
|
||||
ff(B , C , D , A , 7 , fs4);
|
||||
ff(A , B , C , D , 8 , fs1);
|
||||
ff(D , A , B , C , 9 , fs2);
|
||||
ff(C , D , A , B , 10 , fs3);
|
||||
ff(B , C , D , A , 11 , fs4);
|
||||
ff(A , B , C , D , 12 , fs1);
|
||||
ff(D , A , B , C , 13 , fs2);
|
||||
ff(C , D , A , B , 14 , fs3);
|
||||
ff(B , C , D , A , 15 , fs4);
|
||||
gg(A , B , C , D , 0 , gs1); /* Round 2 */
|
||||
gg(D , A , B , C , 4 , gs2);
|
||||
gg(C , D , A , B , 8 , gs3);
|
||||
gg(B , C , D , A , 12 , gs4);
|
||||
gg(A , B , C , D , 1 , gs1);
|
||||
gg(D , A , B , C , 5 , gs2);
|
||||
gg(C , D , A , B , 9 , gs3);
|
||||
gg(B , C , D , A , 13 , gs4);
|
||||
gg(A , B , C , D , 2 , gs1);
|
||||
gg(D , A , B , C , 6 , gs2);
|
||||
gg(C , D , A , B , 10 , gs3);
|
||||
gg(B , C , D , A , 14 , gs4);
|
||||
gg(A , B , C , D , 3 , gs1);
|
||||
gg(D , A , B , C , 7 , gs2);
|
||||
gg(C , D , A , B , 11 , gs3);
|
||||
gg(B , C , D , A , 15 , gs4);
|
||||
hh(A , B , C , D , 0 , hs1); /* Round 3 */
|
||||
hh(D , A , B , C , 8 , hs2);
|
||||
hh(C , D , A , B , 4 , hs3);
|
||||
hh(B , C , D , A , 12 , hs4);
|
||||
hh(A , B , C , D , 2 , hs1);
|
||||
hh(D , A , B , C , 10 , hs2);
|
||||
hh(C , D , A , B , 6 , hs3);
|
||||
hh(B , C , D , A , 14 , hs4);
|
||||
hh(A , B , C , D , 1 , hs1);
|
||||
hh(D , A , B , C , 9 , hs2);
|
||||
hh(C , D , A , B , 5 , hs3);
|
||||
hh(B , C , D , A , 13 , hs4);
|
||||
hh(A , B , C , D , 3 , hs1);
|
||||
hh(D , A , B , C , 11 , hs2);
|
||||
hh(C , D , A , B , 7 , hs3);
|
||||
hh(B , C , D , A , 15 , hs4);
|
||||
MDp->buffer[0] += A;
|
||||
MDp->buffer[1] += B;
|
||||
MDp->buffer[2] += C;
|
||||
MDp->buffer[3] += D;
|
||||
}
|
||||
|
||||
/* MDupdate(MDp,X,count)
|
||||
** Input: MDp -- an MDptr
|
||||
** X -- a pointer to an array of unsigned characters.
|
||||
** count -- the number of bits of X to use.
|
||||
** (if not a multiple of 8, uses high bits of last byte.)
|
||||
** Update MDp using the number of bits of X given by count.
|
||||
** This is the basic input routine for an MD4 user.
|
||||
** The routine completes the MD computation when count < 512, so
|
||||
** every MD computation should end with one call to MDupdate with a
|
||||
** count less than 512. A call with count 0 will be ignored if the
|
||||
** MD has already been terminated (done != 0), so an extra call with
|
||||
** count 0 can be given as a "courtesy close" to force termination
|
||||
** if desired.
|
||||
*/
|
||||
void
|
||||
MDupdate(MDp,X,count)
|
||||
MDptr MDp;
|
||||
unsigned char *X;
|
||||
unsigned int count;
|
||||
{ unsigned int i, tmp, bit, byte, mask;
|
||||
unsigned char XX[64];
|
||||
unsigned char *p;
|
||||
/* return with no error if this is a courtesy close with count
|
||||
** zero and MDp->done is true.
|
||||
*/
|
||||
if (count == 0 && MDp->done) return;
|
||||
/* check to see if MD is already done and report error */
|
||||
if (MDp->done)
|
||||
{ printf("\nError: MDupdate MD already done."); return; }
|
||||
/* Add count to MDp->count */
|
||||
tmp = count;
|
||||
p = MDp->count;
|
||||
while (tmp)
|
||||
{ tmp += *p;
|
||||
*p++ = tmp;
|
||||
tmp = tmp >> 8;
|
||||
}
|
||||
/* Process data */
|
||||
if (count == 512)
|
||||
{ /* Full block of data to handle */
|
||||
MDblock(MDp,(unsigned int *)X);
|
||||
}
|
||||
else if (count > 512) /* Check for count too large */
|
||||
{ printf("\nError: MDupdate called with illegal count value %d."
|
||||
,count);
|
||||
return;
|
||||
}
|
||||
else /* partial block -- must be last block so finish up */
|
||||
{ /* Find out how many bytes and residual bits there are */
|
||||
byte = count >> 3;
|
||||
bit = count & 7;
|
||||
/* Copy X into XX since we need to modify it */
|
||||
for (i=0;i<=byte;i++) XX[i] = X[i];
|
||||
for (i=byte+1;i<64;i++) XX[i] = 0;
|
||||
/* Add padding '1' bit and low-order zeros in last byte */
|
||||
mask = 1 << (7 - bit);
|
||||
XX[byte] = (XX[byte] | mask) & ~( mask - 1);
|
||||
/* If room for bit count, finish up with this block */
|
||||
if (byte <= 55)
|
||||
{ for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
MDblock(MDp,(unsigned int *)XX);
|
||||
}
|
||||
else /* need to do two blocks to finish up */
|
||||
{ MDblock(MDp,(unsigned int *)XX);
|
||||
for (i=0;i<56;i++) XX[i] = 0;
|
||||
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
MDblock(MDp,(unsigned int *)XX);
|
||||
}
|
||||
/* Set flag saying we're done with MD computation */
|
||||
MDp->done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** End of md4.c
|
||||
****************************(cut)***********************************/
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
** ********************************************************************
|
||||
** md4.h -- Header file for implementation of **
|
||||
** MD4 Message Digest Algorithm **
|
||||
** Updated: 2/13/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
/* MDstruct is the data structure for a message digest computation.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int buffer[4]; /* Holds 4-word result of MD computation */
|
||||
unsigned char count[8]; /* Number of bits processed so far */
|
||||
unsigned int done; /* Nonzero means MD computation finished */
|
||||
} MDstruct, *MDptr;
|
||||
|
||||
/* MDbegin(MD)
|
||||
** Input: MD -- an MDptr
|
||||
** Initialize the MDstruct prepatory to doing a message digest
|
||||
** computation.
|
||||
*/
|
||||
extern void MDbegin();
|
||||
|
||||
/* MDupdate(MD,X,count)
|
||||
** Input: MD -- an MDptr
|
||||
** X -- a pointer to an array of unsigned characters.
|
||||
** count -- the number of bits of X to use (an unsigned int).
|
||||
** Updates MD using the first "count" bits of X.
|
||||
** The array pointed to by X is not modified.
|
||||
** If count is not a multiple of 8, MDupdate uses high bits of
|
||||
** last byte.
|
||||
** This is the basic input routine for a user.
|
||||
** The routine terminates the MD computation when count < 512, so
|
||||
** every MD computation should end with one call to MDupdate with a
|
||||
** count less than 512. Zero is OK for a count.
|
||||
*/
|
||||
extern void MDupdate();
|
||||
|
||||
/* MDprint(MD)
|
||||
** Input: MD -- an MDptr
|
||||
** Prints message digest buffer MD as 32 hexadecimal digits.
|
||||
** Order is from low-order byte of buffer[0] to high-order byte
|
||||
** of buffer[3].
|
||||
** Each byte is printed with high-order hexadecimal digit first.
|
||||
*/
|
||||
extern void MDprint();
|
||||
|
||||
/*
|
||||
** End of md4.h
|
||||
****************************(cut)***********************************/
|
|
@ -0,0 +1,304 @@
|
|||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** md5.c -- the source code for MD5 routines **
|
||||
** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
|
||||
** Created: 2/17/90 RLR **
|
||||
** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
|
||||
** **
|
||||
** License to copy and use this software is granted provided that **
|
||||
** it is identified as the "RSA Data Security, Inc. MD5 Message- **
|
||||
** Digest Algorithm" in all material mentioning or referencing this **
|
||||
** software or this function. **
|
||||
** **
|
||||
** License is also granted to make and use derivative works **
|
||||
** provided that such works are identified as "derived from the RSA **
|
||||
** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
|
||||
** material mentioning or referencing the derived work. **
|
||||
** **
|
||||
** RSA Data Security, Inc. makes no representations concerning **
|
||||
** either the merchantability of this software or the suitability **
|
||||
** of this software for any particular purpose. It is provided "as **
|
||||
** is" without express or implied warranty of any kind. **
|
||||
** **
|
||||
** These notices must be retained in any copies of any part of this **
|
||||
** documentation and/or software. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Message-digest routines: **
|
||||
** To form the message digest for a message M **
|
||||
** (1) Initialize a context buffer mdContext using MD5Init **
|
||||
** (2) Call MD5Update on mdContext and M **
|
||||
** (3) Call MD5Final on mdContext **
|
||||
** The message digest is now in mdContext->digest[0...15] **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/* forward declaration */
|
||||
static void Transform ();
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* F, G, H and I are basic MD5 functions */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
#define FF(a, b, c, d, x, s, ac) \
|
||||
{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) \
|
||||
{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) \
|
||||
{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) \
|
||||
{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
#define UL(x) x##U
|
||||
#else
|
||||
#define UL(x) x
|
||||
#endif
|
||||
|
||||
/* The routine MD5Init initializes the message-digest context
|
||||
mdContext. All fields are set to zero.
|
||||
*/
|
||||
void MD5Init (mdContext)
|
||||
MD5_CTX *mdContext;
|
||||
{
|
||||
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
|
||||
|
||||
/* Load magic initialization constants.
|
||||
*/
|
||||
mdContext->buf[0] = (UINT4)0x67452301;
|
||||
mdContext->buf[1] = (UINT4)0xefcdab89;
|
||||
mdContext->buf[2] = (UINT4)0x98badcfe;
|
||||
mdContext->buf[3] = (UINT4)0x10325476;
|
||||
}
|
||||
|
||||
/* The routine MD5Update updates the message-digest context to
|
||||
account for the presence of each of the characters inBuf[0..inLen-1]
|
||||
in the message whose digest is being computed.
|
||||
*/
|
||||
void MD5Update (mdContext, inBuf, inLen)
|
||||
MD5_CTX *mdContext;
|
||||
unsigned char *inBuf;
|
||||
unsigned int inLen;
|
||||
{
|
||||
UINT4 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
|
||||
|
||||
/* update number of bits */
|
||||
if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
|
||||
mdContext->i[1]++;
|
||||
mdContext->i[0] += ((UINT4)inLen << 3);
|
||||
mdContext->i[1] += ((UINT4)inLen >> 29);
|
||||
|
||||
while (inLen--) {
|
||||
/* add new character to buffer, increment mdi */
|
||||
mdContext->in[mdi++] = *inBuf++;
|
||||
|
||||
/* transform if necessary */
|
||||
if (mdi == 0x40) {
|
||||
for (i = 0, ii = 0; i < 16; i++, ii += 4)
|
||||
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
|
||||
(((UINT4)mdContext->in[ii+2]) << 16) |
|
||||
(((UINT4)mdContext->in[ii+1]) << 8) |
|
||||
((UINT4)mdContext->in[ii]);
|
||||
Transform (mdContext->buf, in);
|
||||
mdi = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The routine MD5Final terminates the message-digest computation and
|
||||
ends with the desired message digest in mdContext->digest[0...15].
|
||||
*/
|
||||
void MD5Final (mdContext)
|
||||
MD5_CTX *mdContext;
|
||||
{
|
||||
UINT4 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
unsigned int padLen;
|
||||
|
||||
/* save number of bits */
|
||||
in[14] = mdContext->i[0];
|
||||
in[15] = mdContext->i[1];
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
|
||||
|
||||
/* pad out to 56 mod 64 */
|
||||
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
|
||||
MD5Update (mdContext, PADDING, padLen);
|
||||
|
||||
/* append length in bits and transform */
|
||||
for (i = 0, ii = 0; i < 14; i++, ii += 4)
|
||||
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
|
||||
(((UINT4)mdContext->in[ii+2]) << 16) |
|
||||
(((UINT4)mdContext->in[ii+1]) << 8) |
|
||||
((UINT4)mdContext->in[ii]);
|
||||
Transform (mdContext->buf, in);
|
||||
|
||||
/* store buffer in digest */
|
||||
for (i = 0, ii = 0; i < 4; i++, ii += 4) {
|
||||
mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
|
||||
mdContext->digest[ii+1] =
|
||||
(unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
|
||||
mdContext->digest[ii+2] =
|
||||
(unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
|
||||
mdContext->digest[ii+3] =
|
||||
(unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Basic MD5 step. Transforms buf based on in.
|
||||
*/
|
||||
static void Transform (buf, in)
|
||||
UINT4 *buf;
|
||||
UINT4 *in;
|
||||
{
|
||||
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
|
||||
|
||||
/* Round 1 */
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
|
||||
FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
|
||||
FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
|
||||
FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
|
||||
FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
|
||||
FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
|
||||
FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
|
||||
FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
|
||||
FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
|
||||
FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
|
||||
FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
|
||||
FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
|
||||
FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
|
||||
FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
|
||||
FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
|
||||
FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
|
||||
GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
|
||||
GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
|
||||
GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
|
||||
GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
|
||||
GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */
|
||||
GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
|
||||
GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
|
||||
GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
|
||||
GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
|
||||
GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
|
||||
GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
|
||||
GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
|
||||
GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
|
||||
GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
|
||||
GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
|
||||
HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
|
||||
HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
|
||||
HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
|
||||
HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
|
||||
HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
|
||||
HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
|
||||
HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
|
||||
HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
|
||||
HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
|
||||
HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
|
||||
HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */
|
||||
HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
|
||||
HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
|
||||
HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
|
||||
HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
|
||||
II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
|
||||
II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
|
||||
II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
|
||||
II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
|
||||
II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
|
||||
II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
|
||||
II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
|
||||
II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
|
||||
II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
|
||||
II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
|
||||
II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
|
||||
II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
|
||||
II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
|
||||
II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
|
||||
II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** End of md5.c **
|
||||
******************************** (cut) ********************************
|
||||
*/
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
***********************************************************************
|
||||
** md5.h -- header file for implementation of MD5 **
|
||||
** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
|
||||
** Created: 2/17/90 RLR **
|
||||
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
|
||||
** Revised (for MD5): RLR 4/27/91 **
|
||||
** -- G modified to have y&~z instead of y&z **
|
||||
** -- FF, GG, HH modified to add in last register done **
|
||||
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
|
||||
** -- distinct additive constant for each step **
|
||||
** -- round 4 added, working mod 7 **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
|
||||
** **
|
||||
** License to copy and use this software is granted provided that **
|
||||
** it is identified as the "RSA Data Security, Inc. MD5 Message- **
|
||||
** Digest Algorithm" in all material mentioning or referencing this **
|
||||
** software or this function. **
|
||||
** **
|
||||
** License is also granted to make and use derivative works **
|
||||
** provided that such works are identified as "derived from the RSA **
|
||||
** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
|
||||
** material mentioning or referencing the derived work. **
|
||||
** **
|
||||
** RSA Data Security, Inc. makes no representations concerning **
|
||||
** either the merchantability of this software or the suitability **
|
||||
** of this software for any particular purpose. It is provided "as **
|
||||
** is" without express or implied warranty of any kind. **
|
||||
** **
|
||||
** These notices must be retained in any copies of any part of this **
|
||||
** documentation and/or software. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __MD5_INCLUDE__
|
||||
|
||||
/* typedef a 32-bit type */
|
||||
typedef unsigned int UINT4;
|
||||
|
||||
/* Data structure for MD5 (Message-Digest) computation */
|
||||
typedef struct {
|
||||
UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
|
||||
UINT4 buf[4]; /* scratch buffer */
|
||||
unsigned char in[64]; /* input buffer */
|
||||
unsigned char digest[16]; /* actual digest after MD5Final call */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init ();
|
||||
void MD5Update ();
|
||||
void MD5Final ();
|
||||
|
||||
#define __MD5_INCLUDE__
|
||||
#endif /* __MD5_INCLUDE__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
#define PATCHLEVEL 8
|
||||
|
||||
#define VERSION "i2.2"
|
||||
#define IMPLEMENTATION "anubis"
|
||||
#define DATE "31. January 97"
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* define path names
|
||||
*
|
||||
* $Id: pathnames.h,v 1.1 1997/03/07 16:01:36 hipp Exp $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h>
|
||||
#else
|
||||
# define _PATH_VARRUN "/etc/ppp/"
|
||||
# define _PATH_DEVNULL "/dev/null"
|
||||
#endif
|
||||
|
||||
#define _PATH_UPAPFILE "/etc/ppp/pap-secrets"
|
||||
#define _PATH_CHAPFILE "/etc/ppp/chap-secrets"
|
||||
#define _PATH_SYSOPTIONS "/etc/ppp/ioptions"
|
||||
#define _PATH_IPUP "/etc/ppp/ip-up"
|
||||
#define _PATH_IPDOWN "/etc/ppp/ip-down"
|
||||
#define _PATH_TTYOPT "/etc/ppp/ioptions."
|
||||
#define _PATH_CONNERRS "/etc/ppp/connect-errors"
|
||||
#define _PATH_PEERFILES "/etc/ppp/peers/"
|
||||
#define _PATH_USEROPT ".ippprc"
|
||||
|
||||
/* Programs for processing authenticated logins */
|
||||
#define _PATH_AUTHUP "/etc/ppp/auth-up"
|
||||
#define _PATH_AUTHDOWN "/etc/ppp/auth-down"
|
||||
|
||||
# define _PATH_IPXUP "/etc/ppp/ipx-up"
|
||||
# define _PATH_IPXDOWN "/etc/ppp/ipx-down"
|
||||
|
|
@ -0,0 +1,931 @@
|
|||
.\" manual page [] for pppd 2.0
|
||||
.\" $Id: pppd.8,v 1.1 1997/03/07 16:01:37 hipp Exp $
|
||||
.\" SH section heading
|
||||
.\" SS subsection heading
|
||||
.\" LP paragraph
|
||||
.\" IP indented paragraph
|
||||
.\" TP hanging label
|
||||
.TH PPPD 8
|
||||
.SH NAME
|
||||
pppd \- Point to Point Protocol daemon
|
||||
.SH SYNOPSIS
|
||||
.B pppd
|
||||
[
|
||||
.I tty_name
|
||||
] [
|
||||
.I speed
|
||||
] [
|
||||
.I options
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
The Point-to-Point Protocol (PPP) provides a method for transmitting
|
||||
datagrams over serial point-to-point links. PPP
|
||||
is composed of three parts: a method for encapsulating datagrams over
|
||||
serial links, an extensible Link Control Protocol (LCP), and
|
||||
a family of Network Control Protocols (NCP) for establishing
|
||||
and configuring different network-layer protocols.
|
||||
.LP
|
||||
The encapsulation scheme is provided by driver code in the kernel.
|
||||
.B pppd
|
||||
provides the basic LCP, authentication support, and an
|
||||
NCP for establishing and configuring the Internet Protocol (IP)
|
||||
(called the IP Control Protocol, IPCP).
|
||||
.SH FREQUENTLY USED OPTIONS
|
||||
.TP
|
||||
.I <tty_name>
|
||||
Communicate over the named device. The string "/dev/"
|
||||
is prepended if necessary. If no device name is given,
|
||||
or if the name of the controlling terminal is given,
|
||||
.I pppd
|
||||
will use the controlling terminal, and will not fork to put itself in
|
||||
the background.
|
||||
.TP
|
||||
.I <speed>
|
||||
Set the baud rate to <speed> (a decimal number). On systems such as
|
||||
4.4BSD and NetBSD, any speed can be specified. Other systems
|
||||
(e.g. SunOS) allow only a limited set of speeds.
|
||||
.TP
|
||||
.B asyncmap \fI<map>
|
||||
Set the async character map to <map>.
|
||||
This map describes which control characters cannot be successfully
|
||||
received over the serial line.
|
||||
.I pppd
|
||||
will ask the peer to send these characters as a 2-byte escape sequence.
|
||||
The argument is a 32 bit hex number
|
||||
with each bit representing a character to escape.
|
||||
Bit 0 (00000001) represents the character 0x00;
|
||||
bit 31 (80000000) represents the character 0x1f or ^_.
|
||||
If multiple \fBasyncmap\fR options are
|
||||
given, the values are ORed together.
|
||||
If no \fBasyncmap\fR option is given, no async character map will be
|
||||
negotiated for the receive direction; the peer should then escape
|
||||
\fIall\fR control characters.
|
||||
.TP
|
||||
.B auth
|
||||
Require the peer to authenticate itself before allowing network
|
||||
packets to be sent or received.
|
||||
.TP
|
||||
.B connect \fI<p>
|
||||
Use the executable or shell command specified by \fI<p>\fR to set up the
|
||||
serial line. This script would typically use the chat(8) program to
|
||||
dial the modem and start the remote ppp session.
|
||||
.TP
|
||||
.B crtscts
|
||||
Use hardware flow control (i.e. RTS/CTS) to control the flow of data
|
||||
on the serial port. If neither the \fBcrtscts\fR nor the
|
||||
\fB\-crtscts\fR option is given, the hardware flow control setting for
|
||||
the serial port is left unchanged.
|
||||
.TP
|
||||
.B defaultroute
|
||||
Add a default route to the system routing tables, using the peer as
|
||||
the gateway, when IPCP negotiation is successfully completed.
|
||||
This entry is removed when the PPP connection is broken.
|
||||
.TP
|
||||
.B disconnect \fI<p>
|
||||
Run the executable or shell command specified by \fI<p>\fR after
|
||||
\fIpppd\fR has terminated the link. This script could, for example,
|
||||
issue commands to the modem to cause it to hang up if hardware modem
|
||||
control signals were not available.
|
||||
.TP
|
||||
.B escape \fIxx,yy,...
|
||||
Specifies that certain characters should be escaped on transmission
|
||||
(regardless of whether the peer requests them to be escaped with its
|
||||
async control character map). The characters to be escaped are
|
||||
specified as a list of hex numbers separated by commas. Note that
|
||||
almost any character can be specified for the \fBescape\fR option,
|
||||
unlike the \fBasyncmap\fR option which only allows control characters
|
||||
to be specified. The characters which may not be escaped are those
|
||||
with hex values 0x20 - 0x3f or 0x5e.
|
||||
.TP
|
||||
.B file \fI<f>
|
||||
Read options from file <f> (the format is described below).
|
||||
.TP
|
||||
.B lock
|
||||
Specifies that \fIpppd\fR should create a UUCP-style lock file for the
|
||||
serial device to ensure exclusive access to the device.
|
||||
.TP
|
||||
.B mru \fI<n>
|
||||
Set the MRU [Maximum Receive Unit] value to <n> for negotiation.
|
||||
.I pppd
|
||||
will ask the peer to send packets of no more than <n> bytes. The
|
||||
minimum MRU value is 128. The default MRU value is 1500. A value of
|
||||
296 is recommended for slow links (40 bytes for TCP/IP header + 256
|
||||
bytes of data).
|
||||
.TP
|
||||
.B mtu \fI<n>
|
||||
Set the MTU [Maximum Transmit Unit] value to \fI<n>\fR. Unless the
|
||||
peer requests a smaller value via MRU negotiation, \fIpppd\fR will
|
||||
request that the kernel networking code send data packets of no more
|
||||
than \fIn\fR bytes through the PPP network interface.
|
||||
.TP
|
||||
.B netmask \fI<n>
|
||||
Set the interface netmask to <n>, a 32 bit netmask in "decimal dot"
|
||||
notation (e.g. 255.255.255.0). If this option is given, the value
|
||||
specified is ORed with the default netmask. The default netmask is
|
||||
chosen based on the negotiated remote IP address; it is the
|
||||
appropriate network mask for the class of the remote IP address, ORed
|
||||
with the netmasks for any non point-to-point network interfaces in the
|
||||
system which are on the same network.
|
||||
.TP
|
||||
.B passive
|
||||
Enables the "passive" option in the LCP. With this option,
|
||||
.I pppd
|
||||
will attempt to initiate a connection; if no reply is received from
|
||||
the peer,
|
||||
.I pppd
|
||||
will then just wait passively for a valid LCP packet from the peer
|
||||
(instead of exiting, as it does without this option).
|
||||
.TP
|
||||
.B silent
|
||||
With this option,
|
||||
.I pppd
|
||||
will not transmit LCP packets to initiate a connection until a valid
|
||||
LCP packet is received from the peer (as for the `passive' option with
|
||||
ancient versions of \fIpppd\fR).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I <local_IP_address>\fB:\fI<remote_IP_address>
|
||||
Set the local and/or remote interface IP addresses. Either one may be
|
||||
omitted. The IP addresses can be specified with a host name or in
|
||||
decimal dot notation (e.g. 150.234.56.78). The default local
|
||||
address is the (first) IP address of the system (unless the
|
||||
.B noipdefault
|
||||
option is given). The remote address will be obtained from the peer
|
||||
if not specified in any option. Thus, in simple cases, this option is
|
||||
not required. If a local and/or remote IP address is specified with
|
||||
this option,
|
||||
.I pppd
|
||||
will not accept a different value from the peer in the IPCP
|
||||
negotiation, unless the
|
||||
.B ipcp-accept-local
|
||||
and/or
|
||||
.B ipcp-accept-remote
|
||||
options are given, respectively.
|
||||
.TP
|
||||
.B -ac
|
||||
Disable Address/Control compression negotiation (use default, i.e.
|
||||
address/control field compression disabled).
|
||||
.TP
|
||||
.B -all
|
||||
Don't request or allow negotiation of any options for LCP and IPCP (use
|
||||
default values).
|
||||
.TP
|
||||
.B -am
|
||||
Disable asyncmap negotiation (use the default asyncmap, i.e. escape
|
||||
all control characters).
|
||||
.TP
|
||||
.B -as \fI<n>
|
||||
Same as
|
||||
.B asyncmap \fI<n>
|
||||
.TP
|
||||
.B bsdcomp \fInr,nt
|
||||
Request that the peer compress packets that it sends, using the
|
||||
BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and
|
||||
agree to compress packets sent to the peer with a maximum code size of
|
||||
\fInt\fR bits. If \fInt\fR is not specified, it defaults to the value
|
||||
given for \fInr\fR. Values in the range 9 to 15 may be used for
|
||||
\fInr\fR and \fInt\fR; larger values give better compression but
|
||||
consume more kernel memory for compression dictionaries.
|
||||
Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
|
||||
compression in the corresponding direction.
|
||||
.TP
|
||||
.B \-bsdcomp
|
||||
Disables compression; \fBpppd\fR will not request or agree to compress
|
||||
packets using the BSD-Compress scheme.
|
||||
.TP
|
||||
.B +chap
|
||||
Require the peer to authenticate itself using CHAP [Cryptographic
|
||||
Handshake Authentication Protocol] authentication.
|
||||
.TP
|
||||
.B -chap
|
||||
Don't agree to authenticate using CHAP.
|
||||
.TP
|
||||
.B chap-interval \fI<n>
|
||||
If this option is given,
|
||||
.I pppd
|
||||
will rechallenge the peer every <n> seconds.
|
||||
.TP
|
||||
.B chap-max-challenge \fI<n>
|
||||
Set the maximum number of CHAP challenge transmissions to <n> (default
|
||||
10).
|
||||
.TP
|
||||
.B chap-restart \fI<n>
|
||||
Set the CHAP restart interval (retransmission timeout for challenges)
|
||||
to <n> seconds (default 3).
|
||||
.TP
|
||||
.B -crtscts
|
||||
Disable hardware flow control (i.e. RTS/CTS) on the serial port. If
|
||||
neither the \fBcrtscts\fR nor the \fB\-crtscts\fR option is given,
|
||||
the hardware flow control setting for the serial port is left
|
||||
unchanged.
|
||||
.TP
|
||||
.B -d
|
||||
Increase debugging level (same as the \fBdebug\fR option).
|
||||
.TP
|
||||
.B debug
|
||||
Increase debugging level (same as \fB\-d\fR).
|
||||
If this option is given, \fIpppd\fR will log the contents of all
|
||||
control packets sent or received in a readable form. The packets are
|
||||
logged through syslog with facility \fIdaemon\fR and level
|
||||
\fIdebug\fR. This information can be directed to a file by setting up
|
||||
/etc/syslog.conf appropriately (see syslog.conf(5)).
|
||||
.TP
|
||||
.B \-defaultroute
|
||||
Disable the \fBdefaultroute\fR option. The system administrator who
|
||||
wishes to prevent users from creating default routes with \fIpppd\fR
|
||||
can do so by placing this option in the /etc/ppp/options file.
|
||||
.TP
|
||||
.B -detach
|
||||
Don't fork to become a background process (otherwise
|
||||
.I pppd
|
||||
will do so if a serial device other than its controlling terminal is
|
||||
specified).
|
||||
.TP
|
||||
.B dns-addr \fI<n>
|
||||
This option sets the IP address or addresses for the Domain Name
|
||||
Server. It is used by Microsoft Windows clients. The primary DNS
|
||||
address is specified by the first instance of the dns-addr option. The
|
||||
secondary is specified by the second instance.
|
||||
.TP
|
||||
.B domain \fI<d>
|
||||
Append the domain name <d> to the local host name for authentication
|
||||
purposes. For example, if gethostname() returns the name porsche, but the
|
||||
fully qualified domain name is porsche.Quotron.COM, you would use the
|
||||
domain option to set the domain name to Quotron.COM.
|
||||
.TP
|
||||
.B -ip
|
||||
Disable IP address negotiation. If this option is used, the remote IP
|
||||
address must be specified with an option on the command line or in an
|
||||
options file.
|
||||
.TP
|
||||
.B +ip-protocol
|
||||
Enable the IPCP and IP protocols. This is the default condition. This
|
||||
option is only needed if the default setting is -ip-protocol.
|
||||
.TP
|
||||
.B -ip-protocol
|
||||
Disable the IPCP and IP protocols. This should only be used if you
|
||||
know that you are using a client which only understands IPX and you
|
||||
don't want to confuse the client with the IPCP protocol.
|
||||
.TP
|
||||
.B +ipx-protocol
|
||||
Enable the IPXCP and IPX protocols. This is the default condition if
|
||||
your kernel supports IPX. This option is only needed if the default
|
||||
setting is -ipx-protocol. If your kernel does not support IPX then this
|
||||
option will have no effect.
|
||||
.TP
|
||||
.B -ipx-protocol
|
||||
Disable the IPXCP and IPX protocols. This should only be used if you
|
||||
know that you are using a client which only understands IP and you
|
||||
don't want to confuse the client with the IPXCP protocol.
|
||||
.TP
|
||||
.B ipcp-accept-local
|
||||
With this option,
|
||||
.I pppd
|
||||
will accept the peer's idea of our local IP address, even if the
|
||||
local IP address was specified in an option.
|
||||
.TP
|
||||
.B ipcp-accept-remote
|
||||
With this option,
|
||||
.I pppd
|
||||
will accept the peer's idea of its (remote) IP address, even if the
|
||||
remote IP address was specified in an option.
|
||||
.TP
|
||||
.B ipcp-max-configure \fI<n>
|
||||
Set the maximum number of IPCP configure-request transmissions to <n>
|
||||
(default 10).
|
||||
.TP
|
||||
.B ipcp-max-failure \fI<n>
|
||||
Set the maximum number of IPCP configure-NAKs returned before starting
|
||||
to send configure-Rejects instead to <n> (default 10).
|
||||
.TP
|
||||
.B ipcp-max-terminate \fI<n>
|
||||
Set the maximum number of IPCP terminate-request transmissions to <n>
|
||||
(default 3).
|
||||
.TP
|
||||
.B ipcp-restart \fI<n>
|
||||
Set the IPCP restart interval (retransmission timeout) to <n> seconds
|
||||
(default 3).
|
||||
.TP
|
||||
.B ipparam \fIstring
|
||||
Provides an extra parameter to the ip-up and ip-down scripts. If this
|
||||
option is given, the \fIstring\fR supplied is given as the 6th
|
||||
parameter to those scripts.
|
||||
.TP
|
||||
.B ipx-network \fI<n>
|
||||
Set the IPX network number in the IPXCP configure request frame to
|
||||
<n>. There is no valid default. If this option is not specified then
|
||||
the network number is obtained from the peer. If the peer does not
|
||||
have the network number, the IPX protocol will not be started. This is
|
||||
a hexadecimal number and is entered without any leading sequence such
|
||||
as 0x. It is related to the \fIipxcp-accept-network\fR option.
|
||||
.TP
|
||||
.B ipx-node \fI<n>:<m>
|
||||
Set the IPX node numbers. The two node numbers are separated from each
|
||||
other with a colon character. The first number <n> is the local node
|
||||
number. The second number <m> is the peer's node number. Each node number
|
||||
is a hexadecimal number, to the maximum of ten significant digits. The
|
||||
node numbers on the ipx-network must be unique. There is no valid
|
||||
default. If this option is not specified then the node number is
|
||||
obtained from the peer. This option is a related to the
|
||||
\fIipxcp-accept-local\fR and \fIipxcp-accept-remote\fR options.
|
||||
.TP
|
||||
.B ipx-router-name \fI<string>
|
||||
Set the name of the router. This is a string and is sent to the peer
|
||||
as information data.
|
||||
.TP
|
||||
.B ipx-routing \fI<n>
|
||||
Set the routing protocol to be received by this option. More than one
|
||||
instance of \fIipx-routing\fR may be specified. The '\fInone\fR'
|
||||
option (0) may be specified as the only instance of ipx-routing. The
|
||||
values may be \fI0\fR for \fINONE\fR, \fI2\fR for \fIRIP/SAP\fR, and
|
||||
\fI4\fR for \fINLSP\fR.
|
||||
.TP
|
||||
.B ipxcp-accept-local
|
||||
Accept the peer's NAK for the node number specified in the ipx-node
|
||||
option. If a node number was specified, and non-zero, the default is
|
||||
to insist that the value be used. If you include this option then you
|
||||
will permit the peer to override the entry of the node number.
|
||||
.TP
|
||||
.B ipxcp-accept-network
|
||||
Accept the peer's NAK for the network number specified in the
|
||||
ipx-network option. If a network number was specified, and non-zero, the
|
||||
default is to insist that the value be used. If you include this
|
||||
option then you will permit the peer to override the entry of the node
|
||||
number.
|
||||
.TP
|
||||
.B ipxcp-accept-remote
|
||||
Use the peer's network number specified in the configure request
|
||||
frame. If a node number was specified for the peer and this option was
|
||||
not specified, the peer will be forced to use the value which you have
|
||||
specified.
|
||||
.TP
|
||||
.B ipxcp-max-configure \fI<n>
|
||||
Set the maximum number of IPXCP configure request frames which the
|
||||
system will send to <n>. The default is 10.
|
||||
.TP
|
||||
.B ipxcp-max-failure \fI<n>
|
||||
Set the maximum number of IPXCP NAK frames which the local system will
|
||||
send before it rejects the options. The default value is 3.
|
||||
.TP
|
||||
.B ipxcp-max-terminate \fI<n>
|
||||
Set the maximum nuber of IPXCP terminate request frames before the
|
||||
local system considers that the peer is not listening to them. The
|
||||
default value is 3.
|
||||
.TP
|
||||
.B kdebug \fIn
|
||||
Enable debugging code in the kernel-level PPP driver. The argument
|
||||
\fIn\fR is a number which is the sum of the following values: 1 to
|
||||
enable general debug messages, 2 to request that the contents of
|
||||
received packets be printed, and 4 to request that the contents of
|
||||
transmitted packets be printed.
|
||||
.TP
|
||||
.B lcp-echo-failure \fI<n>
|
||||
If this option is given, \fIpppd\fR will presume the peer to be dead
|
||||
if \fIn\fR LCP echo-requests are sent without receiving a valid LCP
|
||||
echo-reply. If this happens, \fIpppd\fR will terminate the
|
||||
connection. Use of this option requires a non-zero value for the
|
||||
\fIlcp-echo-interval\fR parameter. This option can be used to enable
|
||||
\fIpppd\fR to terminate after the physical connection has been broken
|
||||
(e.g., the modem has hung up) in situations where no hardware modem
|
||||
control lines are available.
|
||||
.TP
|
||||
.B lcp-echo-interval \fI<n>
|
||||
If this option is given, \fIpppd\fR will send an LCP echo-request
|
||||
frame to the peer every \fIn\fR seconds. Under Linux, the
|
||||
echo-request is sent when no packets have been received from the peer
|
||||
for \fIn\fR seconds. Normally the peer should respond to the
|
||||
echo-request by sending an echo-reply. This option can be used with
|
||||
the \fIlcp-echo-failure\fR option to detect that the peer is no longer
|
||||
connected.
|
||||
.TP
|
||||
.B lcp-max-configure \fI<n>
|
||||
Set the maximum number of LCP configure-request transmissions to <n>
|
||||
(default 10).
|
||||
.TP
|
||||
.B lcp-max-failure \fI<n>
|
||||
Set the maximum number of LCP configure-NAKs returned before starting
|
||||
to send configure-Rejects instead to <n> (default 10).
|
||||
.TP
|
||||
.B lcp-max-terminate \fI<n>
|
||||
Set the maximum number of LCP terminate-request transmissions to <n>
|
||||
(default 3).
|
||||
.TP
|
||||
.B lcp-restart \fI<n>
|
||||
Set the LCP restart interval (retransmission timeout) to <n> seconds
|
||||
(default 3).
|
||||
.TP
|
||||
.B local
|
||||
Don't use the modem control lines. With this option,
|
||||
.B pppd
|
||||
will ignore the state of the CD (Carrier Detect) signal from the modem and
|
||||
will not change the state of the DTR (Data Terminal Ready) signal.
|
||||
.TP
|
||||
.B login
|
||||
Use the system password database for authenticating the peer using
|
||||
PAP, and record the user in the system wtmp file.
|
||||
.TP
|
||||
.B modem
|
||||
Use the modem control lines. This option is the default. With this
|
||||
option,
|
||||
.B pppd
|
||||
will wait for the CD (Carrier Detect) signal from the modem to be asserted
|
||||
when opening the serial device
|
||||
(unless a connect script is specified), and it will drop the DTR (Data
|
||||
Terminal Ready) signal briefly when the connection is terminated and before
|
||||
executing the connect script.
|
||||
On Ultrix, this option implies hardware
|
||||
flow control, as for the \fBcrtscts\fR option.
|
||||
.TP
|
||||
.B -mn
|
||||
Disable magic number negotiation. With this option,
|
||||
.I pppd
|
||||
cannot detect a looped-back line.
|
||||
.TP
|
||||
.B -mru
|
||||
Disable MRU [Maximum Receive Unit] negotiation. With this option,
|
||||
\fIpppd\fR will use the default MRU value of 1500 bytes.
|
||||
.TP
|
||||
.B name \fI<n>
|
||||
Set the name of the local system for authentication purposes to <n>.
|
||||
.TP
|
||||
.B noipdefault
|
||||
Disables the default behaviour when no local IP address is specified,
|
||||
which is to determine (if possible) the local IP address from the
|
||||
hostname. With this option, the peer will have to supply the local IP
|
||||
address during IPCP negotiation (unless it specified explicitly on the
|
||||
command line or in an options file).
|
||||
.TP
|
||||
.B -p
|
||||
Same as the
|
||||
.B passive
|
||||
option.
|
||||
.TP
|
||||
.B +pap
|
||||
Require the peer to authenticate itself using PAP.
|
||||
.TP
|
||||
.B -pap
|
||||
Don't agree to authenticate using PAP.
|
||||
.TP
|
||||
.B papcrypt
|
||||
Indicates that all secrets in the /etc/ppp/pap-secrets file which
|
||||
are used for checking the identity of the peer are encrypted, and thus
|
||||
pppd should not accept a password which (before encryption) is
|
||||
identical to the secret from the /etc/ppp/pap-secrets file.
|
||||
.TP
|
||||
.B pap-max-authreq \fI<n>
|
||||
Set the maximum number of PAP authenticate-request transmissions to
|
||||
<n> (default 10).
|
||||
.TP
|
||||
.B pap-restart \fI<n>
|
||||
Set the PAP restart interval (retransmission timeout) to <n> seconds
|
||||
(default 3).
|
||||
.TP
|
||||
.B pap-timeout \fI<n>
|
||||
Set the maximum time that
|
||||
.I pppd
|
||||
will wait for the peer to authenticate itself with PAP to
|
||||
<n> seconds (0 means no limit).
|
||||
.TP
|
||||
.B -pc
|
||||
Disable protocol field compression negotiation (use default, i.e.
|
||||
protocol field compression disabled).
|
||||
.TP
|
||||
.B persist
|
||||
Do not exit after a connection is terminated; instead try to reopen
|
||||
the connection.
|
||||
.TP
|
||||
.B pred1comp
|
||||
Attempt to request that the peer send the local system frames which
|
||||
have been compressed by the Predictor-1 compression. The compression
|
||||
protocols must be loaded or this option will be ignored.
|
||||
.TP
|
||||
.B -pred1comp
|
||||
Do not accept Predictor-1 comprssion, even if the peer wants to send
|
||||
this type of compression and support has been defined in the kernel.
|
||||
.TP
|
||||
.B proxyarp
|
||||
Add an entry to this system's ARP [Address Resolution Protocol] table
|
||||
with the IP address of the peer and the Ethernet address of this
|
||||
system.
|
||||
.TP
|
||||
.B \-proxyarp
|
||||
Disable the \fBproxyarp\fR option. The system administrator who
|
||||
wishes to prevent users from creating proxy ARP entries with
|
||||
\fIpppd\fR can do so by placing this option in the /etc/ppp/options
|
||||
file.
|
||||
.TP
|
||||
.B remotename \fI<n>
|
||||
Set the assumed name of the remote system for authentication purposes
|
||||
to <n>.
|
||||
.TP
|
||||
.B +ua \fI<p>
|
||||
Agree to authenticate using PAP [Password Authentication Protocol] if
|
||||
requested by the peer, and
|
||||
use the data in file <p> for the user and password to send to the
|
||||
peer. The file contains the remote user name, followed by a newline,
|
||||
followed by the remote password, followed by a newline. This option
|
||||
is obsolescent.
|
||||
.TP
|
||||
.B usehostname
|
||||
Enforce the use of the hostname as the name of the local system for
|
||||
authentication purposes (overrides the
|
||||
.B name
|
||||
option).
|
||||
.TP
|
||||
.B user \fI<u>
|
||||
Set the user name to use for authenticating this machine with the peer
|
||||
using PAP to <u>.
|
||||
.TP
|
||||
.B -vj
|
||||
Disable negotiation of Van Jacobson style TCP/IP header compression (use
|
||||
default, i.e. no compression).
|
||||
.TP
|
||||
.B -vjccomp
|
||||
Disable the connection-ID compression option in Van Jacobson style
|
||||
TCP/IP header compression. With this option, \fIpppd\fR will not omit
|
||||
the connection-ID byte from Van Jacobson compressed TCP/IP headers,
|
||||
nor ask the peer to do so.
|
||||
.TP
|
||||
.B vj-max-slots \fIn
|
||||
Sets the number of connection slots to be used by the Van Jacobson
|
||||
TCP/IP header compression and decompression code to \fIn\fR, which
|
||||
must be between 2 and 16 (inclusive).
|
||||
.TP
|
||||
.B xonxoff
|
||||
Use software flow control (i.e. XON/XOFF) to control the flow of data on
|
||||
the serial port. This option is only implemented on Linux systems
|
||||
at present.
|
||||
.SH OPTIONS FILES
|
||||
Options can be taken from files as well as the command line.
|
||||
.I pppd
|
||||
reads options from the files /etc/ppp/options and ~/.ppprc before
|
||||
looking at the command line. An options file is parsed into a series
|
||||
of words, delimited by whitespace. Whitespace can be included in a
|
||||
word by enclosing the word in quotes ("). A backslash (\\) quotes the
|
||||
following character. A hash (#) starts a comment, which continues
|
||||
until the end of the line.
|
||||
.SH AUTHENTICATION
|
||||
.I pppd
|
||||
provides system administrators with sufficient access control that PPP
|
||||
access to a server machine can be provided to legitimate users without
|
||||
fear of compromising the security of the server or the network it's
|
||||
on. In part this is provided by the /etc/ppp/options file, where the
|
||||
administrator can place options to require authentication whenever
|
||||
.I pppd
|
||||
is run, and in part by the PAP and CHAP secrets files, where the
|
||||
administrator can restrict the set of IP addresses which individual
|
||||
users may use.
|
||||
.LP
|
||||
The default behaviour of
|
||||
.I pppd
|
||||
is to agree to authenticate if requested, and to not
|
||||
require authentication from the peer. However,
|
||||
.I pppd
|
||||
will not agree to
|
||||
authenticate itself with a particular protocol if it has no secrets
|
||||
which could be used to do so.
|
||||
.LP
|
||||
Authentication is based on secrets, which are selected from secrets
|
||||
files (/etc/ppp/pap-secrets for PAP, /etc/ppp/chap-secrets for CHAP).
|
||||
Both secrets files have the same format, and both can store secrets
|
||||
for several combinations of server (authenticating peer) and client
|
||||
(peer being authenticated). Note that
|
||||
.I pppd
|
||||
can be both a server
|
||||
and client, and that different protocols can be used in the two
|
||||
directions if desired.
|
||||
.LP
|
||||
A secrets file is parsed into words as for a options file. A secret
|
||||
is specified by a line containing at least 3 words, in the order
|
||||
client name, server name, secret. Any following words on the same line are
|
||||
taken to be a list of acceptable IP addresses for that client. If
|
||||
there are only 3 words on the line, it is assumed that any IP address
|
||||
is OK; to disallow all IP addresses, use "-". If the secret starts
|
||||
with an `@', what follows is assumed to be the name of a file from
|
||||
which to read the secret. A "*" as the client or server name matches
|
||||
any name. When selecting a secret, \fIpppd\fR takes the best match, i.e.
|
||||
the match with the fewest wildcards.
|
||||
.LP
|
||||
Thus a secrets file contains both secrets for use in authenticating
|
||||
other hosts, plus secrets which we use for authenticating ourselves to
|
||||
others. Which secret to use is chosen based on the names of the host
|
||||
(the `local name') and its peer (the `remote name'). The local name
|
||||
is set as follows:
|
||||
.TP 3
|
||||
if the \fBusehostname\fR option is given,
|
||||
then the local name is the hostname of this machine
|
||||
(with the domain appended, if given)
|
||||
.TP 3
|
||||
else if the \fBname\fR option is given,
|
||||
then use the argument of the first \fBname\fR option seen
|
||||
.TP 3
|
||||
else if the local IP address is specified with a hostname,
|
||||
then use that name
|
||||
.TP 3
|
||||
else use the hostname of this machine (with the domain appended, if given)
|
||||
.LP
|
||||
When authenticating ourselves using PAP, there is also a `username'
|
||||
which is the local name by default, but can be set with the \fBuser\fR
|
||||
option or the \fB+ua\fR option.
|
||||
.LP
|
||||
The remote name is set as follows:
|
||||
.TP 3
|
||||
if the \fBremotename\fR option is given,
|
||||
then use the argument of the last \fBremotename\fR option seen
|
||||
.TP 3
|
||||
else if the remote IP address is specified with a hostname,
|
||||
then use that host name
|
||||
.TP 3
|
||||
else the remote name is the null string "".
|
||||
.LP
|
||||
Secrets are selected from the PAP secrets file as follows:
|
||||
.TP 2
|
||||
*
|
||||
For authenticating the peer, look for a secret with client ==
|
||||
username specified in the PAP authenticate-request, and server ==
|
||||
local name.
|
||||
.TP 2
|
||||
*
|
||||
For authenticating ourselves to the peer, look for a secret with
|
||||
client == our username, server == remote name.
|
||||
.LP
|
||||
When authenticating the peer with PAP, a secret of "" matches any
|
||||
password supplied by the peer. If the password doesn't match the
|
||||
secret, the password is encrypted using crypt() and checked against
|
||||
the secret again; thus secrets for authenticating the peer can be
|
||||
stored in encrypted form. If the \fBpapcrypt\fR option is given, the
|
||||
first (unencrypted) comparison is omitted, for better security.
|
||||
.LP
|
||||
If the \fBlogin\fR option was specified, the
|
||||
username and password are also checked against the system password
|
||||
database. Thus, the system administrator can set up the pap-secrets
|
||||
file to allow PPP access only to certain users, and to restrict the
|
||||
set of IP addresses that each user can use. Typically, when using the
|
||||
\fBlogin\fR option, the secret in /etc/ppp/pap-secrets would be "", to
|
||||
avoid the need to have the same secret in two places.
|
||||
.LP
|
||||
Secrets are selected from the CHAP secrets file as follows:
|
||||
.TP 2
|
||||
*
|
||||
For authenticating the peer, look for a secret with client == name
|
||||
specified in the CHAP-Response message, and server == local name.
|
||||
.TP 2
|
||||
*
|
||||
For authenticating ourselves to the peer, look for a secret with
|
||||
client == local name, and server == name specified in the
|
||||
CHAP-Challenge message.
|
||||
.LP
|
||||
Authentication must be satisfactorily completed before IPCP (or any
|
||||
other Network Control Protocol) can be started. If authentication
|
||||
fails, \fIpppd\fR will terminated the link (by closing LCP). If IPCP
|
||||
negotiates an unacceptable IP address for the remote host, IPCP will
|
||||
be closed. IP packets can only be sent or received when IPCP is open.
|
||||
.LP
|
||||
In some cases it is desirable to allow some hosts which can't
|
||||
authenticate themselves to connect and use one of a restricted set of
|
||||
IP addresses, even when the local host generally requires
|
||||
authentication. If the peer refuses to authenticate itself when
|
||||
requested, \fIpppd\fR takes that as equivalent to authenticating with
|
||||
PAP using the empty string for the username and password. Thus, by
|
||||
adding a line to the pap-secrets file which specifies the empty string
|
||||
for the client and password, it is possible to allow restricted access
|
||||
to hosts which refuse to authenticate themselves.
|
||||
.SH ROUTING
|
||||
.LP
|
||||
When IPCP negotiation is completed successfully,
|
||||
.I pppd
|
||||
will inform the kernel of the local and remote IP addresses for the
|
||||
ppp interface. This is sufficient to create a
|
||||
host route to the remote end of the link, which will enable the peers
|
||||
to exchange IP packets. Communication with other machines generally
|
||||
requires further modification to routing tables and/or ARP (Address
|
||||
Resolution Protocol) tables. In some cases this will be done
|
||||
automatically through the actions of the \fIrouted\fR or \fIgated\fR
|
||||
daemons, but in most cases some further intervention is required.
|
||||
.LP
|
||||
Sometimes it is desirable
|
||||
to add a default route through the remote host, as in the case of a
|
||||
machine whose only connection to the Internet is through the ppp
|
||||
interface. The \fBdefaultroute\fR option causes \fIpppd\fR to create such a
|
||||
default route when IPCP comes up, and delete it when the link is
|
||||
terminated.
|
||||
.LP
|
||||
In some cases it is desirable to use proxy ARP, for example on a
|
||||
server machine connected to a LAN, in order to allow other hosts to
|
||||
communicate with the remote host. The \fBproxyarp\fR option causes \fIpppd\fR
|
||||
to look for a network interface on the same subnet as the remote host
|
||||
(an interface supporting broadcast and ARP, which is up and not a
|
||||
point-to-point or loopback interface). If found, \fIpppd\fR creates a
|
||||
permanent, published ARP entry with the IP address of the remote host
|
||||
and the hardware address of the network interface found.
|
||||
.SH EXAMPLES
|
||||
.LP
|
||||
In the simplest case, you can connect the serial ports of two machines
|
||||
and issue a command like
|
||||
.IP
|
||||
pppd /dev/ttya 9600 passive
|
||||
.LP
|
||||
to each machine, assuming there is no \fIgetty\fR running on the
|
||||
serial ports. If one machine has a \fIgetty\fR running, you can use
|
||||
\fIkermit\fR or \fItip\fR on the other machine to log in to the first
|
||||
machine and issue a command like
|
||||
.IP
|
||||
pppd passive
|
||||
.LP
|
||||
Then exit from the communications program (making sure the connection
|
||||
isn't dropped), and issue a command like
|
||||
.IP
|
||||
pppd /dev/ttya 9600
|
||||
.LP
|
||||
The process of logging in to the other machine and starting \fIpppd\fR
|
||||
can be automated by using the \fBconnect\fR option to run \fIchat\fR,
|
||||
for example:
|
||||
.IP
|
||||
pppd /dev/ttya 38400 connect 'chat "" "" "login:" "username"
|
||||
"Password:" "password" "% " "exec pppd passive"'
|
||||
.LP
|
||||
(Note however that running chat like this will leave the password
|
||||
visible in the parameter list of pppd and chat.)
|
||||
.LP
|
||||
If your serial connection is any more complicated than a piece of
|
||||
wire, you may need to arrange for some control characters to be
|
||||
escaped. In particular, it is often useful to escape XON (^Q) and
|
||||
XOFF (^S), using \fBasyncmap a0000\fR. If the path includes a telnet,
|
||||
you probably should escape ^] as well (\fBasyncmap 200a0000\fR).
|
||||
If the path includes an rlogin, you will need to use the \fBescape
|
||||
ff\fR option on the end which is running the rlogin client, since many
|
||||
rlogin implementations are not
|
||||
transparent; they will remove the sequence [0xff, 0xff, 0x73, 0x73,
|
||||
followed by any 8 bytes] from the stream.
|
||||
.SH DIAGNOSTICS
|
||||
.LP
|
||||
Messages are sent to the syslog daemon using facility LOG_DAEMON.
|
||||
(This can be overriden by recompiling \fIpppd\fR with the macro
|
||||
LOG_PPP defined as the desired facility.) In order to see the error
|
||||
and debug messages, you will need to edit your /etc/syslog.conf file
|
||||
to direct the messages to the desired output device or file.
|
||||
.LP
|
||||
The \fBdebug\fR option causes the contents of all control packets sent
|
||||
or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets.
|
||||
This can be useful if the PPP negotiation does not succeed.
|
||||
If debugging is enabled at compile time, the \fBdebug\fR option also
|
||||
causes other debugging messages to be logged.
|
||||
.LP
|
||||
Debugging can also be enabled or disabled by sending a
|
||||
SIGUSR1 to the
|
||||
.I pppd
|
||||
process. This signal acts as a toggle.
|
||||
.SH FILES
|
||||
.TP
|
||||
.B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others)
|
||||
Process-ID for \fIpppd\fR process on ppp interface unit \fIn\fR.
|
||||
.TP
|
||||
.B /etc/ppp/ip-up
|
||||
A program or script which is executed when the link is available for
|
||||
sending and receiving IP packets (that is, IPCP has come up). It is
|
||||
executed with the parameters
|
||||
.IP
|
||||
\fIinterface-name tty-device speed local-IP-address
|
||||
remote-IP-address\fR
|
||||
.IP
|
||||
and with its standard input,
|
||||
output and error streams redirected to \fB/dev/null\fR.
|
||||
.IP
|
||||
This program or script is executed with the same real and effective
|
||||
user-ID as \fIpppd\fR, that is, at least the effective user-ID and
|
||||
possibly the real user-ID will be \fBroot\fR. This is so that it can
|
||||
be used to manipulate routes, run privileged daemons (e.g.
|
||||
\fBsendmail\fR), etc. Be careful that the contents of the
|
||||
/etc/ppp/ip-up and /etc/ppp/ip-down scripts do not compromise your
|
||||
system's security.
|
||||
.TP
|
||||
.B /etc/ppp/ip-down
|
||||
A program or script which is executed when the link is no longer
|
||||
available for sending and receiving IP packets. This script can be
|
||||
used for undoing the effects of the /etc/ppp/ip-up script. It is
|
||||
invoked with the same parameters as the ip-up script, and the same
|
||||
security considerations apply, since it is executed with the same
|
||||
effective and real user-IDs as \fIpppd\fR.
|
||||
.TP
|
||||
.B /etc/ppp/ipx-up
|
||||
A program or script which is executed when the link is available for
|
||||
sending and receiving IPX packets (that is, IPXCP has come up). It is
|
||||
executed with the parameters
|
||||
.IP
|
||||
\fIinterface-name tty-device speed network-number local-IPX-node-address
|
||||
remote-IPX-node-address local-IPX-routing-protocol remote-IPX-routing-protocol
|
||||
local-IPX-router-name remote-IPX-router-name ipparam pppd-pid\fR
|
||||
.IP
|
||||
and with its standard input,
|
||||
output and error streams redirected to \fB/dev/null\fR.
|
||||
.br
|
||||
.IP
|
||||
The local-IPX-routing-protocol and remote-IPX-routing-protocol field
|
||||
may be one of the following:
|
||||
.IP
|
||||
NONE to indicate that there is no routing protocol
|
||||
.br
|
||||
RIP to indicate that RIP/SAP should be used
|
||||
.br
|
||||
NLSP to indicate that Novell NLSP should be used
|
||||
.br
|
||||
RIP NLSP to indicate that both RIP/SAP and NLSP should be used
|
||||
.br
|
||||
.IP
|
||||
This program or script is executed with the same real and effective
|
||||
user-ID as \fIpppd\fR, that is, at least the effective user-ID and
|
||||
possibly the real user-ID will be \fBroot\fR. This is so that it can
|
||||
be used to manipulate routes, run privileged daemons (e.g.
|
||||
\fBripd\fR), etc. Be careful that the contents of the
|
||||
/etc/ppp/ipx-up and /etc/ppp/ipx-down scripts do not compromise your
|
||||
system's security.
|
||||
.TP
|
||||
.B /etc/ppp/ipx-down
|
||||
A program or script which is executed when the link is no longer
|
||||
available for sending and receiving IPX packets. This script can be
|
||||
used for undoing the effects of the /etc/ppp/ipx-up script. It is
|
||||
invoked with the same parameters as the ipx-up script, and the same
|
||||
security considerations apply, since it is executed with the same
|
||||
effective and real user-IDs as \fIpppd\fR.
|
||||
.TP
|
||||
.B /etc/ppp/pap-secrets
|
||||
Usernames, passwords and IP addresses for PAP authentication.
|
||||
.TP
|
||||
.B /etc/ppp/chap-secrets
|
||||
Names, secrets and IP addresses for CHAP authentication.
|
||||
.TP
|
||||
.B /etc/ppp/options
|
||||
System default options for
|
||||
.I pppd,
|
||||
read before user default options or command-line options.
|
||||
.TP
|
||||
.B ~/.ppprc
|
||||
User default options, read before command-line options.
|
||||
.TP
|
||||
.B /etc/ppp/options.\fIttyname
|
||||
System default options for the serial port being used, read after
|
||||
command-line options.
|
||||
.SH SEE ALSO
|
||||
.TP
|
||||
.B RFC1144
|
||||
Jacobson, V.
|
||||
.I Compressing TCP/IP headers for low-speed serial links.
|
||||
1990 February.
|
||||
.TP
|
||||
.B RFC1321
|
||||
Rivest, R.
|
||||
.I The MD5 Message-Digest Algorithm.
|
||||
1992 April.
|
||||
.TP
|
||||
.B RFC1332
|
||||
McGregor, G.
|
||||
.I PPP Internet Protocol Control Protocol (IPCP).
|
||||
1992 May.
|
||||
.TP
|
||||
.B RFC1334
|
||||
Lloyd, B.; Simpson, W.A.
|
||||
.I PPP authentication protocols.
|
||||
1992 October.
|
||||
.TP
|
||||
.B RFC1548
|
||||
Simpson, W.A.
|
||||
.I The Point\-to\-Point Protocol (PPP).
|
||||
1993 December.
|
||||
.TP
|
||||
.B RFC1549
|
||||
Simpson, W.A.
|
||||
.I PPP in HDLC Framing.
|
||||
1993 December
|
||||
.SH NOTES
|
||||
The following signals have the specified effect when sent to the
|
||||
.I pppd
|
||||
process.
|
||||
.TP
|
||||
.B SIGINT, SIGTERM
|
||||
These signals cause \fBpppd\fR to terminate the link (by closing LCP),
|
||||
restore the serial device settings, and exit.
|
||||
.TP
|
||||
.B SIGHUP
|
||||
This signal causes \fBpppd\fR to terminate the link, restore the
|
||||
serial device settings, and close the serial device. If the
|
||||
\fBpersist\fR option has been specified, \fBpppd\fR will try to reopen
|
||||
the serial device and start another connection. Otherwise \fBpppd\fR
|
||||
will exit.
|
||||
.TP
|
||||
.B SIGUSR2
|
||||
This signal causes
|
||||
.B pppd
|
||||
to renegotiate compression. This can be useful to re-enable
|
||||
compression after it has been disabled as a result of a fatal
|
||||
decompression error. With the BSD Compress scheme, fatal
|
||||
decompression errors generally indicate a bug in one or other
|
||||
implementation.
|
||||
|
||||
.SH AUTHORS
|
||||
Drew Perkins,
|
||||
Brad Clements,
|
||||
Karl Fox,
|
||||
Greg Christy,
|
||||
Brad Parker,
|
||||
Paul Mackerras (paulus@cs.anu.edu.au).
|
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
* pppd.h - PPP daemon global declarations.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: pppd.h,v 1.1 1997/03/07 16:01:39 hipp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#define ISDN4LINUX_PATCH
|
||||
|
||||
#ifndef __PPPD_H__
|
||||
#define __PPPD_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
|
||||
#include <sys/types.h> /* for u_int32_t, if defined */
|
||||
#include <sys/bitypes.h>
|
||||
#include <linux/ppp_defs.h>
|
||||
#include <linux/isdn_ppp.h>
|
||||
#include <stdio.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#define NUM_PPP 16 /* 16 PPP interface supported (per process) */
|
||||
|
||||
struct wordlist {
|
||||
struct wordlist *next;
|
||||
char word[1];
|
||||
};
|
||||
|
||||
struct link_struct {
|
||||
struct link_struct *bundle_next;
|
||||
int fd; /* link file descriptor */
|
||||
int peer_mru; /* link: peer_mru */
|
||||
int logged_in;
|
||||
int auth_pending;
|
||||
struct wordlist *addresses;
|
||||
int unit; /* link unit */
|
||||
int lcp_unit;
|
||||
int ipcp_unit;
|
||||
int ccp_unit;
|
||||
int chap_unit;
|
||||
int upap_unit;
|
||||
int cbcp_unit;
|
||||
int ipxcp_unit;
|
||||
int phase;
|
||||
int auth_up_script;
|
||||
int kill_link;
|
||||
int open_ccp_flag;
|
||||
int ifunit;
|
||||
int openfails;
|
||||
char ifname[IFNAMSIZ];
|
||||
char devnam[MAXPATHLEN];
|
||||
char peer_authname[64];
|
||||
int initfdflags;
|
||||
int hungup;
|
||||
struct pppcallinfo pci;
|
||||
};
|
||||
|
||||
extern struct link_struct lns[NUM_PPP];
|
||||
|
||||
/*
|
||||
* Limits.
|
||||
*/
|
||||
|
||||
#define MAXWORDLEN 1024 /* max length of word in file (incl null) */
|
||||
#define MAXARGS 1 /* max # args to a command */
|
||||
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
|
||||
#define MAXSECRETLEN 256 /* max length of password or secret */
|
||||
|
||||
/*
|
||||
* Global variables.
|
||||
*/
|
||||
|
||||
extern char hostname[]; /* Our hostname */
|
||||
extern u_char outpacket_buf[]; /* Buffer for outgoing packets */
|
||||
extern int baud_rate; /* Current link speed in bits/sec */
|
||||
extern char *progname; /* Name of this program */
|
||||
|
||||
/*
|
||||
* Variables set by command-line options.
|
||||
*/
|
||||
|
||||
extern int usefirstip,useifip,useifmtu;
|
||||
extern int numdev; /* number of handled devices */
|
||||
extern int debug; /* Debug flag */
|
||||
extern int kdebugflag; /* Tell kernel to print debug messages */
|
||||
extern int default_device; /* Using /dev/tty or equivalent */
|
||||
extern int crtscts; /* Use hardware flow control */
|
||||
extern int modem; /* Use modem control lines */
|
||||
extern int inspeed; /* Input/Output speed requested */
|
||||
extern u_int32_t netmask; /* IP netmask to set on interface */
|
||||
extern int lockflag; /* Create lock file to lock the serial dev */
|
||||
extern int nodetach; /* Don't detach from controlling tty */
|
||||
extern char *connector; /* Script to establish physical link */
|
||||
extern char *disconnector; /* Script to disestablish physical link */
|
||||
extern char user[]; /* Username for PAP */
|
||||
extern char passwd[]; /* Password for PAP */
|
||||
extern int auth_required; /* Peer is required to authenticate */
|
||||
extern int proxyarp; /* Set up proxy ARP entry for peer */
|
||||
extern int persist; /* Reopen link after it goes down */
|
||||
extern int uselogin; /* Use /etc/passwd for checking PAP */
|
||||
extern int lcp_echo_interval; /* Interval between LCP echo-requests */
|
||||
extern int lcp_echo_fails; /* Tolerance to unanswered echo-requests */
|
||||
extern char our_name[]; /* Our name for authentication purposes */
|
||||
extern char remote_name[]; /* Peer's name for authentication */
|
||||
extern int usehostname; /* Use hostname for our_name */
|
||||
extern int disable_defaultip; /* Don't use hostname for default IP adrs */
|
||||
extern char *ipparam; /* Extra parameter for ip up/down scripts */
|
||||
extern int cryptpap; /* Others' PAP passwords are encrypted */
|
||||
#ifdef __linux__
|
||||
extern int hostroute; /* Add a route to the host at the other end? */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Values for phase.
|
||||
*/
|
||||
#define PHASE_WAIT -1
|
||||
#define PHASE_DEAD 0
|
||||
#define PHASE_ESTABLISH 1
|
||||
#define PHASE_AUTHENTICATE 2
|
||||
#define PHASE_CALLBACK 3
|
||||
#define PHASE_NETWORK 4
|
||||
#define PHASE_TERMINATE 5
|
||||
|
||||
/*
|
||||
* The following struct gives the addresses of procedures to call
|
||||
* for a particular protocol.
|
||||
*/
|
||||
struct protent {
|
||||
u_short protocol; /* PPP protocol number */
|
||||
/* Initialization procedure */
|
||||
void (*init) __P((int unit));
|
||||
/* Process a received packet */
|
||||
void (*input) __P((int unit, u_char *pkt, int len));
|
||||
/* Process a received protocol-reject */
|
||||
void (*protrej) __P((int unit));
|
||||
/* Lower layer has come up */
|
||||
void (*lowerup) __P((int unit));
|
||||
/* Lower layer has gone down */
|
||||
void (*lowerdown) __P((int unit));
|
||||
/* Open the protocol */
|
||||
void (*open) __P((int unit));
|
||||
/* Close the protocol */
|
||||
void (*close) __P((int unit, char *reason));
|
||||
/* Print a packet in readable form */
|
||||
int (*printpkt) __P((u_char *pkt, int len,
|
||||
void (*printer) __P((void *, char *, ...)),
|
||||
void *arg));
|
||||
/* Process a received data packet */
|
||||
void (*datainput) __P((int unit, u_char *pkt, int len));
|
||||
int enabled_flag; /* 0 iff protocol is disabled */
|
||||
char *name; /* Text name of protocol */
|
||||
/* Check requested options, assign defaults */
|
||||
void (*check_options) __P((void));
|
||||
/* Configure interface for demand-dial */
|
||||
int (*demand_conf) __P((int unit));
|
||||
/* Say whether to bring up link for this pkt */
|
||||
int (*active_pkt) __P((u_char *pkt, int len));
|
||||
};
|
||||
|
||||
/* Table of pointers to supported protocols */
|
||||
extern struct protent *protocols[];
|
||||
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
void quit __P((void)); /* Cleanup and exit */
|
||||
void timeout __P((void (*)(), caddr_t, int));
|
||||
/* Look-alike of kernel's timeout() */
|
||||
void untimeout __P((void (*)(), caddr_t));
|
||||
/* Look-alike of kernel's untimeout() */
|
||||
void output __P((int, u_char *, int));
|
||||
/* Output a PPP packet */
|
||||
void demuxprotrej __P((int,u_short));
|
||||
/* Demultiplex a Protocol-Reject */
|
||||
int check_passwd __P((int, char *, int, char *, int, char **, int *));
|
||||
/* Check peer-supplied username/password */
|
||||
int get_secret __P((int, char *, char *, char *, int *, int));
|
||||
/* get "secret" for chap */
|
||||
u_int32_t GetMask __P((u_int32_t)); /* get netmask for address */
|
||||
void die __P((int));
|
||||
void check_access __P((FILE *, char *));
|
||||
|
||||
int ccp_getunit(int);
|
||||
int ipcp_getunit(int);
|
||||
int lcp_getunit(int);
|
||||
void ccp_freeunit(int);
|
||||
void ipcp_freeunit(int);
|
||||
void lcp_freeunit(int);
|
||||
char *ip_ntoa(u_int32_t);
|
||||
int bad_ip_adrs(u_int32_t);
|
||||
int getword(FILE *,char *,int *,char *);
|
||||
void print_string(char *p,int len,void (*printer)(void *,char *,...),void *arg);
|
||||
int auth_ip_addr(int unit,u_int32_t addr);
|
||||
void auth_peer_fail(int,int);
|
||||
void auth_withpeer_fail(int unit,int protocol);
|
||||
void auth_peer_success(int unit,int protocol);
|
||||
void auth_withpeer_success(int unit,int protocol);
|
||||
|
||||
void link_required(int);
|
||||
void link_terminated(int);
|
||||
void link_down(int);
|
||||
void link_established(int unit);
|
||||
int device_script(char *program,int in,int out);
|
||||
void check_auth_options(void);
|
||||
void setipdefault(void);
|
||||
int options_from_file(char *filename,int must_exist,int check_prot,int slot);
|
||||
int options_for_tty(void);
|
||||
int options_from_user(void);
|
||||
int parse_args(int argc,char **argv);
|
||||
int run_program(char *prog,char **args,int must_exist,int tu);
|
||||
void establish_ppp __P((int));
|
||||
void calltimeout __P((void));
|
||||
struct timeval *timeleft __P((struct timeval *));
|
||||
void reap_kids __P((void));
|
||||
void cleanup __P((int, caddr_t,int));
|
||||
void close_fd __P((int));
|
||||
void die __P((int));
|
||||
void novm __P((char *));
|
||||
void log_packet __P((u_char *, int, char *,int));
|
||||
void format_packet __P((u_char *,int,void (*) (void *, char *, ...), void *,int));
|
||||
void pr_log __P((void *, char *, ...));
|
||||
void sys_init(void);
|
||||
void note_debug_level (void);
|
||||
void output (int unit, unsigned char *p, int len);
|
||||
void wait_input (struct timeval *timo);
|
||||
int read_packet (unsigned char *buf,int tu);
|
||||
void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp);
|
||||
void ppp_set_xaccm (int unit, ext_accm accm);
|
||||
void ppp_recv_config (int unit,int mru,u_int32_t asyncmap,int pcomp,int accomp);
|
||||
int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit);
|
||||
void ccp_flags_set (int unit, int isopen, int isup);
|
||||
int ccp_fatal_error (int unit);
|
||||
int sifvjcomp (int unit, int vjcomp, int cidcomp, int maxcid);
|
||||
int sifup (int u);
|
||||
int sifdown (int u);
|
||||
int sifbundle(int,int);
|
||||
int sifaddr (int unit, int our_adr, int his_adr, int net_mask);
|
||||
int cifaddr (int unit, int our_adr, int his_adr);
|
||||
int sifdefaultroute (int unit, int gateway);
|
||||
int cifdefaultroute (int unit, int gateway);
|
||||
int sifproxyarp (int unit, u_int32_t his_adr);
|
||||
int cifproxyarp (int unit, u_int32_t his_adr);
|
||||
int sipxfaddr (int unit, u_int32_t network, unsigned char * node );
|
||||
int cipxfaddr (int linkunit);
|
||||
int ppp_available(void);
|
||||
int logwtmp (int unit,char *line, char *name, char *host);
|
||||
int lock (char *dev);
|
||||
void unlock(void);
|
||||
void setifip(int);
|
||||
extern void enable_mp(int,int);
|
||||
void remove_sys_options(void);
|
||||
u_int32_t magic(void);
|
||||
int fmtmsg __P((char *, int, char *, ...)); /* sprintf++ */
|
||||
int vfmtmsg __P((char *, int, char *, va_list)); /* vsprintf++ */
|
||||
void option_error __P((char *fmt, ...));
|
||||
void usage __P((void)); /* Print a usage message */
|
||||
|
||||
/*
|
||||
* This structure is used to store information about certain
|
||||
* options, such as where the option value came from (/etc/ppp/options,
|
||||
* command line, etc.) and whether it came from a privileged source.
|
||||
*/
|
||||
|
||||
struct option_info {
|
||||
int priv; /* was value set by sysadmin? */
|
||||
char *source; /* where option came from */
|
||||
};
|
||||
|
||||
extern struct option_info auth_req_info;
|
||||
extern struct option_info connector_info;
|
||||
extern struct option_info disconnector_info;
|
||||
extern struct option_info welcomer_info;
|
||||
extern struct option_info devnam_info;
|
||||
|
||||
|
||||
/*
|
||||
* Inline versions of get/put char/short/long.
|
||||
* Pointer is advanced; we assume that both arguments
|
||||
* are lvalues and will already be in registers.
|
||||
* cp MUST be u_char *.
|
||||
*/
|
||||
#define GETCHAR(c, cp) { \
|
||||
(c) = *(cp)++; \
|
||||
}
|
||||
#define PUTCHAR(c, cp) { \
|
||||
*(cp)++ = (u_char) (c); \
|
||||
}
|
||||
|
||||
|
||||
#define GETSHORT(s, cp) { \
|
||||
(s) = *(cp)++ << 8; \
|
||||
(s) |= *(cp)++; \
|
||||
}
|
||||
#define PUTSHORT(s, cp) { \
|
||||
*(cp)++ = (u_char) ((s) >> 8); \
|
||||
*(cp)++ = (u_char) (s); \
|
||||
}
|
||||
|
||||
#define GETLONG(l, cp) { \
|
||||
(l) = *(cp)++ << 8; \
|
||||
(l) |= *(cp)++; (l) <<= 8; \
|
||||
(l) |= *(cp)++; (l) <<= 8; \
|
||||
(l) |= *(cp)++; \
|
||||
}
|
||||
#define PUTLONG(l, cp) { \
|
||||
*(cp)++ = (u_char) ((l) >> 24); \
|
||||
*(cp)++ = (u_char) ((l) >> 16); \
|
||||
*(cp)++ = (u_char) ((l) >> 8); \
|
||||
*(cp)++ = (u_char) (l); \
|
||||
}
|
||||
|
||||
#define INCPTR(n, cp) ((cp) += (n))
|
||||
#define DECPTR(n, cp) ((cp) -= (n))
|
||||
|
||||
#undef FALSE
|
||||
#define FALSE 0
|
||||
#undef TRUE
|
||||
#define TRUE 1
|
||||
|
||||
/*
|
||||
* System dependent definitions for user-level 4.3BSD UNIX implementation.
|
||||
*/
|
||||
|
||||
#define DEMUXPROTREJ(u, p) demuxprotrej(u, p)
|
||||
|
||||
#define TIMEOUT(r, f, t) timeout((r), (f), (t))
|
||||
#define UNTIMEOUT(r, f) untimeout((r), (f))
|
||||
|
||||
#define BCOPY(s, d, l) memcpy(d, s, l)
|
||||
#define BZERO(s, n) memset(s, 0, n)
|
||||
#define EXIT(u) quit()
|
||||
|
||||
#define PRINTMSG(m, l) { m[l] = '\0'; syslog(LOG_INFO, "Remote message: %s", m); }
|
||||
|
||||
/*
|
||||
* MAKEHEADER - Add Header fields to a packet.
|
||||
*/
|
||||
#define MAKEHEADER(p, t) { \
|
||||
PUTCHAR(PPP_ALLSTATIONS, p); \
|
||||
PUTCHAR(PPP_UI, p); \
|
||||
PUTSHORT(t, p); }
|
||||
|
||||
|
||||
#ifdef DEBUGALL
|
||||
#define DEBUGMAIN 1
|
||||
#define DEBUGFSM 1
|
||||
#define DEBUGLCP 1
|
||||
#define DEBUGIPCP 1
|
||||
#define DEBUGIPXCP 1
|
||||
#define DEBUGUPAP 1
|
||||
#define DEBUGCHAP 1
|
||||
#endif
|
||||
|
||||
#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */
|
||||
#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUG) \
|
||||
|| defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \
|
||||
|| defined(DEBUGCHAP) || defined(DEBUGIPXCP)
|
||||
#define LOG_PPP LOG_LOCAL2
|
||||
#else
|
||||
#define LOG_PPP LOG_DAEMON
|
||||
#endif
|
||||
#endif /* LOG_PPP */
|
||||
|
||||
#ifdef DEBUGMAIN
|
||||
#define MAINDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define MAINDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFSM
|
||||
#define FSMDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define FSMDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGLCP
|
||||
#define LCPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define LCPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGIPCP
|
||||
#define IPCPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define IPCPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGIPXCP
|
||||
#define IPXCPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define IPXCPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGUPAP
|
||||
#define UPAPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define UPAPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGCHAP
|
||||
#define CHAPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define CHAPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifndef SIGTYPE
|
||||
#if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE)
|
||||
#define SIGTYPE void
|
||||
#else
|
||||
#define SIGTYPE int
|
||||
#endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */
|
||||
#endif /* SIGTYPE */
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a): (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b)? (a): (b))
|
||||
#endif
|
||||
|
||||
#endif /* __PPP_H__ */
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
struct protos {
|
||||
unsigned int val;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct protos protonames[] = {
|
||||
{ 0x0001,"Padding Protocol" },
|
||||
{ 0x0021,"Internet Protocol" },
|
||||
{ 0x0023,"OSI Network Layer" },
|
||||
{ 0x0025,"Xerox NS IDP" },
|
||||
{ 0x0027,"DECnet Phase IV" },
|
||||
{ 0x0029,"Appletalk" },
|
||||
{ 0x002b,"Novell IPX" },
|
||||
{ 0x002d,"Van Jacobson Compressed TCP/IP" },
|
||||
{ 0x002f,"Van Jacobson Uncompressed TCP/IP" },
|
||||
{ 0x0031,"Bridging PDU" },
|
||||
{ 0x0033,"Stream Protocol (ST-II)" },
|
||||
{ 0x0035,"Banyan Vines" },
|
||||
{ 0x0037,"reserved (until 1993)" },
|
||||
{ 0x0039,"AppleTalk EDDP" },
|
||||
{ 0x003b,"AppleTalk SmartBuffered" },
|
||||
{ 0x003d,"Multi-Link [RFC1717]" },
|
||||
{ 0x003f,"NETBIOS Framing" },
|
||||
{ 0x0041,"Cisco Systems" },
|
||||
{ 0x0043,"Ascom Timeplex" },
|
||||
{ 0x0045,"Fujitsu Link Backup and Load Balancing (LBLB)" },
|
||||
{ 0x0047,"DCA Remote Lan" },
|
||||
{ 0x0049,"Serial Data Transport Protocol (PPP-SDTP)" },
|
||||
{ 0x004b,"SNA over 802.2" },
|
||||
{ 0x004d,"SNA" },
|
||||
{ 0x004f,"IP6 Header Compression" },
|
||||
{ 0x0051,"KNX Bridging Data" },
|
||||
{ 0x0053,"Encryption" },
|
||||
{ 0x0055,"Individual Link Encryption" },
|
||||
{ 0x006f,"Stampede Bridging" },
|
||||
{ 0x00fb,"compression on single link in multilink group" },
|
||||
{ 0x00fd,"1st choice compression" },
|
||||
|
||||
{ 0x0201,"802.1d Hello Packets" },
|
||||
{ 0x0203,"IBM Source Routing BPDU" },
|
||||
{ 0x0205,"DEC LANBridge100 Spanning Tree" },
|
||||
{ 0x0207,"Cisco Discovery Protocol" },
|
||||
{ 0x0209,"Netcs Twin Routing" },
|
||||
{ 0x0231,"Luxcom" },
|
||||
{ 0x0233,"Sigma Network Systems" },
|
||||
{ 0x0235,"Apple Client Server Protocol" },
|
||||
|
||||
{ 0x4001,"Cray Communications Control Protocol" },
|
||||
{ 0x4003,"CDPD Mobile Network Registration Protocol" },
|
||||
{ 0x4021,"Stacker LZS" },
|
||||
|
||||
{ 0x8021,"Internet Protocol Control Protocol" },
|
||||
{ 0x8023,"OSI Network Layer Control Protocol" },
|
||||
{ 0x8025,"Xerox NS IDP Control Protocol" },
|
||||
{ 0x8027,"DECnet Phase IV Control Protocol" },
|
||||
{ 0x8029,"Appletalk Control Protocol" },
|
||||
{ 0x802b,"Novell IPX Control Protocol" },
|
||||
{ 0x8031,"Bridging NCP" },
|
||||
{ 0x8033,"Stream Protocol Control Protocol" },
|
||||
{ 0x8035,"Banyan Vines Control Protocol" },
|
||||
{ 0x803d,"Multi-Link Control Protocol" },
|
||||
{ 0x803f,"NETBIOS Framing Control Protocol" },
|
||||
{ 0x8041,"Cisco Systems Control Protocol" },
|
||||
{ 0x8043,"Ascom Timeplex" },
|
||||
{ 0x8045,"Fujitsu LBLB Control Protocol" },
|
||||
{ 0x8047,"DCA Remote Lan Network Control Protocol (RLNCP)" },
|
||||
{ 0x8049,"Serial Data Control Protocol (PPP-SDCP)" },
|
||||
{ 0x804b,"SNA over 802.2 Control Protocol" },
|
||||
{ 0x804d,"SNA Control Protocol" },
|
||||
{ 0x804f,"IP6 Header Compression Control Protocol" },
|
||||
{ 0x8051,"KNX Bridging Control Protocol" },
|
||||
{ 0x8053,"Encryption Control Protocol" },
|
||||
{ 0x8055,"Individual Link Encryption Control Protocol" },
|
||||
{ 0x806f,"Stampede Bridging Control Protocol" },
|
||||
{ 0x80fb,"compression on single link in multilink group control" },
|
||||
{ 0x80fd,"Compression Control Protocol" },
|
||||
{ 0x8207,"Cisco Discovery Protocol Control" },
|
||||
{ 0x8209,"Netcs Twin Routing" },
|
||||
{ 0x8235,"Apple Client Server Protocol Control" },
|
||||
|
||||
{ 0xc021,"Link Control Protocol" },
|
||||
{ 0xc023,"Password Authentication Protocol" },
|
||||
{ 0xc025,"Link Quality Report" },
|
||||
{ 0xc027,"Shiva Password Authentication Protocol" },
|
||||
{ 0xc029,"CallBack Control Protocol (CBCP)" },
|
||||
{ 0xc081,"Container Control Protocol" },
|
||||
{ 0xc223,"Challenge Handshake Authentication Protocol" },
|
||||
{ 0xc225,"RSA Authentication Protocol" },
|
||||
{ 0xc26f,"Stampede Bridging Authorization Protocol" },
|
||||
{ 0xc281,"Proprietary Authentication Protocol" },
|
||||
{ 0xc283,"Proprietary Authentication Protocol" },
|
||||
{ 0xc481,"Proprietary Node ID Authentication Protocol" }
|
||||
};
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,619 @@
|
|||
/*
|
||||
* upap.c - User/Password Authentication Protocol.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: upap.c,v 1.1 1997/03/07 16:01:41 hipp Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "fsm.h"
|
||||
#include "pppd.h"
|
||||
#include "upap.h"
|
||||
|
||||
extern int log_raw_password;
|
||||
/*
|
||||
* Protocol entry points.
|
||||
*/
|
||||
static void upap_init __P((int));
|
||||
static void upap_lowerup __P((int));
|
||||
static void upap_lowerdown __P((int));
|
||||
static void upap_input __P((int, u_char *, int));
|
||||
static void upap_protrej __P((int));
|
||||
static int upap_printpkt __P((u_char *, int,
|
||||
void (*) __P((void *, char *, ...)), void *));
|
||||
|
||||
struct protent pap_protent = {
|
||||
PPP_PAP,
|
||||
upap_init,
|
||||
upap_input,
|
||||
upap_protrej,
|
||||
upap_lowerup,
|
||||
upap_lowerdown,
|
||||
NULL,
|
||||
NULL,
|
||||
upap_printpkt,
|
||||
NULL,
|
||||
1,
|
||||
"PAP",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
|
||||
|
||||
|
||||
static void upap_timeout __P((caddr_t));
|
||||
static void upap_reqtimeout __P((caddr_t));
|
||||
static void upap_rauthreq __P((upap_state *, u_char *, int, int));
|
||||
static void upap_rauthack __P((upap_state *, u_char *, int, int));
|
||||
static void upap_rauthnak __P((upap_state *, u_char *, int, int));
|
||||
static void upap_sauthreq __P((upap_state *));
|
||||
static void upap_sresp __P((upap_state *, int, int, char *, int));
|
||||
|
||||
|
||||
/*
|
||||
* upap_init - Initialize a UPAP unit.
|
||||
*/
|
||||
void
|
||||
upap_init(unit)
|
||||
int unit;
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
u->us_unit = unit;
|
||||
u->us_ruser[0] = 0;
|
||||
u->us_ruserlen = 0;
|
||||
u->us_rpasswd[0] = 0;
|
||||
u->us_rpasswdlen = 0;
|
||||
u->us_user = NULL;
|
||||
u->us_userlen = 0;
|
||||
u->us_passwd = NULL;
|
||||
u->us_passwdlen = 0;
|
||||
u->us_clientstate = UPAPCS_INITIAL;
|
||||
u->us_serverstate = UPAPSS_INITIAL;
|
||||
u->us_id = 0;
|
||||
u->us_timeouttime = UPAP_DEFTIMEOUT;
|
||||
u->us_maxtransmits = 10;
|
||||
u->us_reqtimeout = UPAP_DEFREQTIME;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_authwithpeer - Authenticate us with our peer (start client).
|
||||
*
|
||||
* Set new state and send authenticate's.
|
||||
*/
|
||||
void upap_authwithpeer(int unit,char *user,char *password)
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
/* Save the username and password we're given */
|
||||
u->us_user = user;
|
||||
u->us_userlen = strlen(user);
|
||||
u->us_passwd = password;
|
||||
u->us_passwdlen = strlen(password);
|
||||
u->us_transmits = 0;
|
||||
|
||||
/* Lower layer up yet? */
|
||||
if (u->us_clientstate == UPAPCS_INITIAL ||
|
||||
u->us_clientstate == UPAPCS_PENDING) {
|
||||
u->us_clientstate = UPAPCS_PENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
upap_sauthreq(u); /* Start protocol */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_authpeer - Authenticate our peer (start server).
|
||||
*
|
||||
* Set new state.
|
||||
*/
|
||||
void upap_authpeer(int unit)
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
/* Lower layer up yet? */
|
||||
if (u->us_serverstate == UPAPSS_INITIAL ||
|
||||
u->us_serverstate == UPAPSS_PENDING) {
|
||||
u->us_serverstate = UPAPSS_PENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
u->us_serverstate = UPAPSS_LISTEN;
|
||||
if (u->us_reqtimeout > 0)
|
||||
TIMEOUT(upap_reqtimeout, (caddr_t) u, u->us_reqtimeout);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_timeout - Retransmission timer for sending auth-reqs expired.
|
||||
*/
|
||||
static void upap_timeout(caddr_t arg)
|
||||
{
|
||||
upap_state *u = (upap_state *) arg;
|
||||
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ)
|
||||
return;
|
||||
|
||||
if (u->us_transmits >= u->us_maxtransmits) {
|
||||
/* give up in disgust */
|
||||
syslog(LOG_ERR, "No response to PAP authenticate-requests");
|
||||
u->us_clientstate = UPAPCS_BADAUTH;
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
return;
|
||||
}
|
||||
|
||||
upap_sauthreq(u); /* Send Authenticate-Request */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_reqtimeout - Give up waiting for the peer to send an auth-req.
|
||||
*/
|
||||
static void
|
||||
upap_reqtimeout(arg)
|
||||
caddr_t arg;
|
||||
{
|
||||
upap_state *u = (upap_state *) arg;
|
||||
|
||||
if (u->us_serverstate != UPAPSS_LISTEN)
|
||||
return; /* huh?? */
|
||||
|
||||
auth_peer_fail(u->us_unit, PPP_PAP);
|
||||
u->us_serverstate = UPAPSS_BADAUTH;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_lowerup - The lower layer is up.
|
||||
*
|
||||
* Start authenticating if pending.
|
||||
*/
|
||||
void upap_lowerup(int unit)
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
if (u->us_clientstate == UPAPCS_INITIAL)
|
||||
u->us_clientstate = UPAPCS_CLOSED;
|
||||
else if (u->us_clientstate == UPAPCS_PENDING) {
|
||||
upap_sauthreq(u); /* send an auth-request */
|
||||
}
|
||||
|
||||
if (u->us_serverstate == UPAPSS_INITIAL)
|
||||
u->us_serverstate = UPAPSS_CLOSED;
|
||||
else if (u->us_serverstate == UPAPSS_PENDING) {
|
||||
u->us_serverstate = UPAPSS_LISTEN;
|
||||
if (u->us_reqtimeout > 0)
|
||||
TIMEOUT(upap_reqtimeout, (caddr_t) u, u->us_reqtimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_lowerdown - The lower layer is down.
|
||||
*
|
||||
* Cancel all timeouts.
|
||||
*/
|
||||
void upap_lowerdown(int unit)
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
|
||||
UNTIMEOUT(upap_timeout, (caddr_t) u); /* Cancel timeout */
|
||||
if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
|
||||
UNTIMEOUT(upap_reqtimeout, (caddr_t) u);
|
||||
|
||||
u->us_clientstate = UPAPCS_INITIAL;
|
||||
u->us_serverstate = UPAPSS_INITIAL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_protrej - Peer doesn't speak this protocol.
|
||||
*
|
||||
* This shouldn't happen. In any case, pretend lower layer went down.
|
||||
*/
|
||||
void upap_protrej(int linkunit)
|
||||
{
|
||||
int unit = lns[linkunit].upap_unit;
|
||||
upap_state *u = &upap[unit]; /* link unit! */
|
||||
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) {
|
||||
syslog(LOG_ERR, "PAP authentication failed due to protocol-reject");
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
if (u->us_serverstate == UPAPSS_LISTEN) {
|
||||
syslog(LOG_ERR, "PAP authentication of peer failed (protocol-reject)");
|
||||
auth_peer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
upap_lowerdown(unit);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_input - Input UPAP packet.
|
||||
*/
|
||||
void upap_input(int linkunit,u_char *inpacket,int l)
|
||||
{
|
||||
int unit = lns[linkunit].upap_unit;
|
||||
upap_state *u = &upap[unit];
|
||||
u_char *inp;
|
||||
u_char code, id;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Parse header (code, id and length).
|
||||
* If packet too short, drop it.
|
||||
*/
|
||||
inp = inpacket;
|
||||
if (l < UPAP_HEADERLEN) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_input: rcvd short header."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < UPAP_HEADERLEN) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_input: rcvd illegal length."));
|
||||
return;
|
||||
}
|
||||
if (len > l) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_input: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
len -= UPAP_HEADERLEN;
|
||||
|
||||
/*
|
||||
* Action depends on code.
|
||||
*/
|
||||
switch (code) {
|
||||
case UPAP_AUTHREQ:
|
||||
upap_rauthreq(u, inp, id, len);
|
||||
break;
|
||||
|
||||
case UPAP_AUTHACK:
|
||||
upap_rauthack(u, inp, id, len);
|
||||
break;
|
||||
|
||||
case UPAP_AUTHNAK:
|
||||
upap_rauthnak(u, inp, id, len);
|
||||
break;
|
||||
|
||||
default: /* XXX Need code reject */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_rauth - Receive Authenticate.
|
||||
*/
|
||||
static void
|
||||
upap_rauthreq(upap_state *u,u_char *inp,int id,int len)
|
||||
{
|
||||
u_char ruserlen, rpasswdlen;
|
||||
char *ruser, *rpasswd;
|
||||
int retcode;
|
||||
char *msg;
|
||||
int msglen;
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauth: Rcvd id %d.", id));
|
||||
|
||||
if (u->us_serverstate < UPAPSS_LISTEN)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If we receive a duplicate authenticate-request, we are
|
||||
* supposed to return the same status as for the first request.
|
||||
*/
|
||||
if (u->us_serverstate == UPAPSS_OPEN) {
|
||||
upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
|
||||
return;
|
||||
}
|
||||
if (u->us_serverstate == UPAPSS_BADAUTH) {
|
||||
upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse user/passwd.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(ruserlen, inp);
|
||||
len -= sizeof (u_char) + ruserlen + sizeof (u_char);
|
||||
if (len < 0) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
ruser = (char *) inp;
|
||||
INCPTR(ruserlen, inp);
|
||||
GETCHAR(rpasswdlen, inp);
|
||||
if (len < rpasswdlen) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
rpasswd = (char *) inp;
|
||||
|
||||
/*
|
||||
* Check the username and password given.
|
||||
*/
|
||||
if(ruserlen > 64)
|
||||
ruserlen = 64;
|
||||
if(rpasswdlen > 64)
|
||||
rpasswdlen = 64;
|
||||
strncpy(u->us_ruser,ruser,(int)ruserlen);
|
||||
strncpy(u->us_rpasswd,rpasswd,(int)rpasswdlen);
|
||||
u->us_rpasswdlen = rpasswdlen;
|
||||
u->us_ruserlen = ruserlen;
|
||||
|
||||
retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
|
||||
rpasswdlen, &msg, &msglen);
|
||||
|
||||
upap_sresp(u, retcode, id, msg, msglen);
|
||||
|
||||
if (retcode == UPAP_AUTHACK) {
|
||||
u->us_serverstate = UPAPSS_OPEN;
|
||||
auth_peer_success(u->us_unit, PPP_PAP);
|
||||
} else {
|
||||
u->us_serverstate = UPAPSS_BADAUTH;
|
||||
auth_peer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
if (u->us_reqtimeout > 0)
|
||||
UNTIMEOUT(upap_reqtimeout, (caddr_t) u);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_rauthack - Receive Authenticate-Ack.
|
||||
*/
|
||||
static void
|
||||
upap_rauthack(u, inp, id, len)
|
||||
upap_state *u;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
u_char msglen;
|
||||
char *msg;
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauthack: Rcvd id %d.", id));
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
|
||||
return;
|
||||
|
||||
/*
|
||||
* Parse message.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauthack: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(msglen, inp);
|
||||
len -= sizeof (u_char);
|
||||
if (len < msglen) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauthack: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
msg = (char *) inp;
|
||||
PRINTMSG(msg, msglen);
|
||||
|
||||
u->us_clientstate = UPAPCS_OPEN;
|
||||
|
||||
auth_withpeer_success(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_rauthnak - Receive Authenticate-Nakk.
|
||||
*/
|
||||
static void
|
||||
upap_rauthnak(u, inp, id, len)
|
||||
upap_state *u;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
u_char msglen;
|
||||
char *msg;
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauthnak: Rcvd id %d.", id));
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
|
||||
return;
|
||||
|
||||
/*
|
||||
* Parse message.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauthnak: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(msglen, inp);
|
||||
len -= sizeof (u_char);
|
||||
if (len < msglen) {
|
||||
UPAPDEBUG((LOG_INFO, "upap_rauthnak: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
msg = (char *) inp;
|
||||
PRINTMSG(msg, msglen);
|
||||
|
||||
u->us_clientstate = UPAPCS_BADAUTH;
|
||||
|
||||
syslog(LOG_ERR, "PAP authentication failed");
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_sauthreq - Send an Authenticate-Request.
|
||||
*/
|
||||
static void
|
||||
upap_sauthreq(u)
|
||||
upap_state *u;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
|
||||
u->us_userlen + u->us_passwdlen;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_PAP);
|
||||
|
||||
PUTCHAR(UPAP_AUTHREQ, outp);
|
||||
PUTCHAR(++u->us_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
PUTCHAR(u->us_userlen, outp);
|
||||
BCOPY(u->us_user, outp, u->us_userlen);
|
||||
INCPTR(u->us_userlen, outp);
|
||||
PUTCHAR(u->us_passwdlen, outp);
|
||||
BCOPY(u->us_passwd, outp, u->us_passwdlen);
|
||||
|
||||
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_sauth: Sent id %d.", u->us_id));
|
||||
|
||||
TIMEOUT(upap_timeout, (caddr_t) u, u->us_timeouttime);
|
||||
++u->us_transmits;
|
||||
u->us_clientstate = UPAPCS_AUTHREQ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_sresp - Send a response (ack or nak).
|
||||
*/
|
||||
static void
|
||||
upap_sresp(u, code, id, msg, msglen)
|
||||
upap_state *u;
|
||||
u_char code, id;
|
||||
char *msg;
|
||||
int msglen;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
|
||||
outp = outpacket_buf;
|
||||
MAKEHEADER(outp, PPP_PAP);
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
PUTCHAR(msglen, outp);
|
||||
BCOPY(msg, outp, msglen);
|
||||
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_sresp: Sent code %d, id %d.", code, id));
|
||||
}
|
||||
|
||||
/*
|
||||
* upap_printpkt - print the contents of a PAP packet.
|
||||
*/
|
||||
char *upap_codenames[] = {
|
||||
"AuthReq", "AuthAck", "AuthNak"
|
||||
};
|
||||
|
||||
int
|
||||
upap_printpkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
int code, id, len;
|
||||
int mlen, ulen, wlen;
|
||||
char *user, *pwd, *msg;
|
||||
u_char *pstart;
|
||||
|
||||
if (plen < UPAP_HEADERLEN)
|
||||
return 0;
|
||||
pstart = p;
|
||||
GETCHAR(code, p);
|
||||
GETCHAR(id, p);
|
||||
GETSHORT(len, p);
|
||||
if (len < UPAP_HEADERLEN || len > plen)
|
||||
return 0;
|
||||
|
||||
if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *))
|
||||
printer(arg, " %s", upap_codenames[code-1]);
|
||||
else
|
||||
printer(arg, " code=0x%x", code);
|
||||
printer(arg, " id=0x%x", id);
|
||||
len -= UPAP_HEADERLEN;
|
||||
switch (code) {
|
||||
case UPAP_AUTHREQ:
|
||||
if (len < 1)
|
||||
break;
|
||||
ulen = p[0];
|
||||
if (len < ulen + 2)
|
||||
break;
|
||||
wlen = p[ulen + 1];
|
||||
if (len < ulen + wlen + 2)
|
||||
break;
|
||||
user = (char *) (p + 1);
|
||||
pwd = (char *) (p + ulen + 2);
|
||||
p += ulen + wlen + 2;
|
||||
len -= ulen + wlen + 2;
|
||||
printer(arg, " user=");
|
||||
print_string(user, ulen, printer, arg);
|
||||
if(log_raw_password) {
|
||||
printer(arg, " password=");
|
||||
print_string(pwd, wlen, printer, arg);
|
||||
}
|
||||
else
|
||||
printer(arg, " password not logged for security reasons! Use '+pwlog' option to enable full logging.");
|
||||
break;
|
||||
case UPAP_AUTHACK:
|
||||
case UPAP_AUTHNAK:
|
||||
if (len < 1)
|
||||
break;
|
||||
mlen = p[0];
|
||||
if (len < mlen + 1)
|
||||
break;
|
||||
msg = (char *) (p + 1);
|
||||
p += mlen + 1;
|
||||
len -= mlen + 1;
|
||||
printer(arg, "msg=");
|
||||
print_string(msg, mlen, printer, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
/* print the rest of the bytes in the packet */
|
||||
for (; len > 0; --len) {
|
||||
GETCHAR(code, p);
|
||||
printer(arg, " %.2x", code);
|
||||
}
|
||||
|
||||
return p - pstart;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* upap.h - User/Password Authentication Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Carnegie Mellon University. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: upap.h,v 1.1 1997/03/07 16:01:42 hipp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Packet header = Code, id, length.
|
||||
*/
|
||||
#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
|
||||
|
||||
|
||||
/*
|
||||
* UPAP codes.
|
||||
*/
|
||||
#define UPAP_AUTHREQ 1 /* Authenticate-Request */
|
||||
#define UPAP_AUTHACK 2 /* Authenticate-Ack */
|
||||
#define UPAP_AUTHNAK 3 /* Authenticate-Nak */
|
||||
|
||||
|
||||
/*
|
||||
* Each interface is described by upap structure.
|
||||
*/
|
||||
typedef struct upap_state {
|
||||
int us_unit; /* Interface unit number */
|
||||
char *us_user; /* User */
|
||||
char us_ruser[64]; /* User */
|
||||
int us_userlen; /* User length */
|
||||
int us_ruserlen; /* User length */
|
||||
char *us_passwd; /* Password */
|
||||
char us_rpasswd[64]; /* Password */
|
||||
int us_passwdlen; /* Password length */
|
||||
int us_rpasswdlen; /* Password length */
|
||||
int us_clientstate; /* Client state */
|
||||
int us_serverstate; /* Server state */
|
||||
u_char us_id; /* Current id */
|
||||
int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */
|
||||
int us_transmits; /* Number of auth-reqs sent */
|
||||
int us_maxtransmits; /* Maximum number of auth-reqs to send */
|
||||
int us_reqtimeout; /* Time to wait for auth-req from peer */
|
||||
} upap_state;
|
||||
|
||||
|
||||
/*
|
||||
* Client states.
|
||||
*/
|
||||
#define UPAPCS_INITIAL 0 /* Connection down */
|
||||
#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */
|
||||
#define UPAPCS_PENDING 2 /* Connection down, have requested auth */
|
||||
#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */
|
||||
#define UPAPCS_OPEN 4 /* We've received an Ack */
|
||||
#define UPAPCS_BADAUTH 5 /* We've received a Nak */
|
||||
|
||||
/*
|
||||
* Server states.
|
||||
*/
|
||||
#define UPAPSS_INITIAL 0 /* Connection down */
|
||||
#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */
|
||||
#define UPAPSS_PENDING 2 /* Connection down, have requested auth */
|
||||
#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */
|
||||
#define UPAPSS_OPEN 4 /* We've sent an Ack */
|
||||
#define UPAPSS_BADAUTH 5 /* We've sent a Nak */
|
||||
|
||||
|
||||
/*
|
||||
* Timeouts.
|
||||
*/
|
||||
#define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */
|
||||
#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */
|
||||
|
||||
|
||||
extern upap_state upap[];
|
||||
extern struct protent pap_protent;
|
||||
|
||||
void upap_authwithpeer __P((int, char *, char *));
|
||||
void upap_authpeer __P((int));
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# pppstats makefile
|
||||
# $Id: Makefile,v 1.1 1997/03/07 15:57:03 hipp Exp $
|
||||
#
|
||||
|
||||
PPPSTATSRCS = ipppstats.c
|
||||
PPPSTATOBJS = ipppstats.o
|
||||
|
||||
CC = gcc
|
||||
COPTS = -O2
|
||||
COMPILE_FLAGS = -m486 -fomit-frame-pointer -I../include
|
||||
LIBS =
|
||||
|
||||
INSTALL= install -o root -g daemon
|
||||
|
||||
CFLAGS = $(COPTS) $(COMPILE_FLAGS)
|
||||
|
||||
all: ipppstats
|
||||
|
||||
install: ipppstats
|
||||
$(INSTALL) -s -c ipppstats $(BINDIR)/ipppstats
|
||||
$(INSTALL) -c -m 444 ipppstats.8 $(MANDIR)/man8/ipppstats.8
|
||||
|
||||
ipppstats: $(PPPSTATSRCS)
|
||||
$(CC) $(CFLAGS) -o ipppstats ipppstats.c $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f ipppstats *~ #* core
|
||||
|
||||
depend:
|
||||
cpp -M $(CFLAGS) $(PPPSTATSRCS) >.depend
|
||||
# makedepend $(CFLAGS) $(PPPSTATSRCS)
|
|
@ -0,0 +1,54 @@
|
|||
.\" @(#) $Id: ipppstats.8,v 1.1 1997/03/07 15:57:04 hipp Exp $
|
||||
.TH PPPSTATS 8 "2 May 1995"
|
||||
.SH NAME
|
||||
pppstats \- print PPP statistics
|
||||
.SH SYNOPSIS
|
||||
.B pppstats
|
||||
[
|
||||
.B -v
|
||||
] [
|
||||
.B -r
|
||||
] [
|
||||
.B -c
|
||||
] [
|
||||
.B -i
|
||||
.I <secs>
|
||||
] [
|
||||
.I <unit#>
|
||||
]
|
||||
.ti 12
|
||||
.SH DESCRIPTION
|
||||
.B pppstats
|
||||
prints PPP-related statistics.
|
||||
.PP
|
||||
The
|
||||
.B -v
|
||||
flag causes
|
||||
.B pppstats
|
||||
to display additional statistics, such as the number of packets tossed
|
||||
(that is, which the VJ TCP header decompression code rejected).
|
||||
.PP
|
||||
The
|
||||
.B -r
|
||||
flag causes
|
||||
.B pppstats
|
||||
to display the overall packet compression rate. The rate value is
|
||||
between 0 and 1, with 0 meaning that the data is incompressible.
|
||||
.PP
|
||||
The
|
||||
.B -c
|
||||
flag is used to specify an alternate display mode that shows
|
||||
packet compression statistics: the number of packets and bytes
|
||||
uncompressed (that is, before compression or after decompression),
|
||||
compressed, and incompressible (packets which did not shrink on
|
||||
compression and were transmitted uncompressed), and the recent
|
||||
compression rate. This rate reflects the recent performance of the
|
||||
compression code rather than the overall rate achieved since
|
||||
compression was enabled.
|
||||
.PP
|
||||
The
|
||||
.B -i
|
||||
flag is used to specify the interval between printouts. The default is
|
||||
5 seconds.
|
||||
.PP
|
||||
<unit#> specifies which interface to use for gathering statistics.
|
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* print PPP statistics:
|
||||
* ipppstats [-i interval] [-v] [-r] [-c] [interface]
|
||||
*
|
||||
* -i <update interval in seconds>
|
||||
* -v Verbose mode for default display
|
||||
* -r Show compression ratio in default display
|
||||
* -c Show Compression statistics instead of default display
|
||||
* -a Do not show relative values. Show absolute values at all times.
|
||||
*
|
||||
*
|
||||
* History:
|
||||
* perkins@cps.msu.edu: Added compression statistics and alternate
|
||||
* display. 11/94
|
||||
|
||||
* Brad Parker (brad@cayman.com) 6/92
|
||||
*
|
||||
* from the original "slstats" by Van Jaconson
|
||||
*
|
||||
* Copyright (c) 1989 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the University of California, Berkeley. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
|
||||
* - Initial distribution.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: ipppstats.c,v 1.1 1997/03/07 15:57:05 hipp Exp $";
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <nlist.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/ppp_defs.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#ifndef STREAMS
|
||||
#include <linux/if_ppp.h> /* BSD, Linux, NeXT, etc. */
|
||||
|
||||
#else /* SunOS 4, AIX 4, OSF/1, etc. */
|
||||
#define PPP_STATS 1 /* should be defined iff it is in ppp_if.c */
|
||||
#include <sys/stream.h>
|
||||
#include <linux/ppp_str.h>
|
||||
#endif
|
||||
|
||||
int vflag, rflag, cflag, aflag;
|
||||
unsigned interval = 5;
|
||||
int unit;
|
||||
int s; /* socket file descriptor */
|
||||
int signalled; /* set if alarm goes off "early" */
|
||||
|
||||
extern char *malloc();
|
||||
void catchalarm __P((int));
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
--argc; ++argv;
|
||||
while (argc > 0) {
|
||||
if (strcmp(argv[0], "-a") == 0) {
|
||||
++aflag;
|
||||
++argv, --argc;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[0], "-v") == 0) {
|
||||
++vflag;
|
||||
++argv, --argc;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[0], "-r") == 0) {
|
||||
++rflag;
|
||||
++argv, --argc;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[0], "-c") == 0) {
|
||||
++cflag;
|
||||
++argv, --argc;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[0], "-i") == 0 && argv[1] &&
|
||||
isdigit(argv[1][0])) {
|
||||
interval = atoi(argv[1]);
|
||||
if (interval < 0)
|
||||
usage();
|
||||
++argv, --argc;
|
||||
++argv, --argc;
|
||||
continue;
|
||||
}
|
||||
if (isdigit(argv[0][0])) {
|
||||
unit = atoi(argv[0]);
|
||||
if (unit < 0)
|
||||
usage();
|
||||
++argv, --argc;
|
||||
continue;
|
||||
}
|
||||
usage();
|
||||
}
|
||||
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
perror("couldn't create IP socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
intpr();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: ipppstats [-v] [-r] [-c] [-i interval] [unit]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define V(offset) (line % 20? cur.offset - old.offset: cur.offset)
|
||||
#define W(offset) (line % 20? ccs.offset - ocs.offset: ccs.offset)
|
||||
|
||||
#define CRATE(comp, inc, unc) ((unc) == 0? 0.0: \
|
||||
1.0 - (double)((comp) + (inc)) / (unc))
|
||||
|
||||
/*
|
||||
* Print a running summary of interface statistics.
|
||||
* Repeat display every interval seconds, showing statistics
|
||||
* collected over that interval. Assumes that interval is non-zero.
|
||||
* First line printed at top of screen is always cumulative.
|
||||
*/
|
||||
intpr()
|
||||
{
|
||||
register int line = 0;
|
||||
sigset_t oldmask, mask;
|
||||
struct ppp_stats cur, old;
|
||||
struct ppp_comp_stats ccs, ocs;
|
||||
|
||||
memset(&old, 0, sizeof(old));
|
||||
memset(&ocs, 0, sizeof(ocs));
|
||||
|
||||
while (1) {
|
||||
get_ppp_stats(&cur);
|
||||
if (cflag || rflag)
|
||||
get_ppp_cstats(&ccs);
|
||||
|
||||
(void)signal(SIGALRM, catchalarm);
|
||||
signalled = 0;
|
||||
(void)alarm(interval);
|
||||
|
||||
if ((line % 20) == 0) {
|
||||
if (line > 0)
|
||||
putchar('\n');
|
||||
if (cflag) {
|
||||
|
||||
printf("%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
|
||||
"ubyte", "upack", "cbyte", "cpack", "ibyte", "ipack", "ratio");
|
||||
printf(" | %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
|
||||
"ubyte", "upack", "cbyte", "cpack", "ibyte", "ipack", "ratio");
|
||||
putchar('\n');
|
||||
} else {
|
||||
|
||||
printf("%6.6s %6.6s %6.6s %6.6s %6.6s",
|
||||
"in", "pack", "comp", "uncomp", "err");
|
||||
if (vflag)
|
||||
printf(" %6.6s %6.6s", "toss", "ip");
|
||||
if (rflag)
|
||||
printf(" %6.6s %6.6s", "ratio", "ubyte");
|
||||
printf(" | %6.6s %6.6s %6.6s %6.6s %6.6s",
|
||||
"out", "pack", "comp", "uncomp", "ip");
|
||||
if (vflag)
|
||||
printf(" %6.6s %6.6s", "search", "miss");
|
||||
if(rflag)
|
||||
printf(" %6.6s %6.6s", "ratio", "ubyte");
|
||||
putchar('\n');
|
||||
}
|
||||
memset(&old, 0, sizeof(old));
|
||||
memset(&ocs, 0, sizeof(ocs));
|
||||
}
|
||||
|
||||
if (cflag) {
|
||||
printf("%6d %6d %6d %6d %6d %6d %6.2f",
|
||||
W(d.unc_bytes),
|
||||
W(d.unc_packets),
|
||||
W(d.comp_bytes),
|
||||
W(d.comp_packets),
|
||||
W(d.inc_bytes),
|
||||
W(d.inc_packets),
|
||||
W(d.ratio) == 0? 0.0: 1 - 1.0 / W(d.ratio) * 256.0);
|
||||
|
||||
printf(" | %6d %6d %6d %6d %6d %6d %6.2f",
|
||||
W(c.unc_bytes),
|
||||
W(c.unc_packets),
|
||||
W(c.comp_bytes),
|
||||
W(c.comp_packets),
|
||||
W(c.inc_bytes),
|
||||
W(c.inc_packets),
|
||||
W(d.ratio) == 0? 0.0: 1 - 1.0 / W(d.ratio) * 256.0);
|
||||
|
||||
putchar('\n');
|
||||
} else {
|
||||
|
||||
printf("%6d %6d %6d %6d %6d",
|
||||
V(p.ppp_ibytes),
|
||||
V(p.ppp_ipackets), V(vj.vjs_compressedin),
|
||||
V(vj.vjs_uncompressedin), V(vj.vjs_errorin));
|
||||
if (vflag)
|
||||
printf(" %6d %6d", V(vj.vjs_tossed),
|
||||
V(p.ppp_ipackets) - V(vj.vjs_compressedin) -
|
||||
V(vj.vjs_uncompressedin) - V(vj.vjs_errorin));
|
||||
if (rflag)
|
||||
printf(" %6.2f %6d",
|
||||
CRATE(W(d.comp_bytes), W(d.unc_bytes), W(d.unc_bytes)),
|
||||
W(d.unc_bytes));
|
||||
printf(" | %6d %6d %6d %6d %6d", V(p.ppp_obytes),
|
||||
V(p.ppp_opackets), V(vj.vjs_compressed),
|
||||
V(vj.vjs_packets) - V(vj.vjs_compressed),
|
||||
V(p.ppp_opackets) - V(vj.vjs_packets));
|
||||
if (vflag)
|
||||
printf(" %6d %6d", V(vj.vjs_searches), V(vj.vjs_misses));
|
||||
|
||||
if (rflag)
|
||||
printf(" %6.2f %6d",
|
||||
CRATE(W(d.comp_bytes), W(d.unc_bytes), W(d.unc_bytes)),
|
||||
W(c.unc_bytes));
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
line++;
|
||||
if (interval == 0)
|
||||
exit(0);
|
||||
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGALRM);
|
||||
sigprocmask(SIG_BLOCK, &mask, &oldmask);
|
||||
if (! signalled) {
|
||||
sigemptyset(&mask);
|
||||
sigsuspend(&mask);
|
||||
}
|
||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
signalled = 0;
|
||||
(void)alarm(interval);
|
||||
|
||||
if (aflag==0) {
|
||||
old = cur;
|
||||
ocs = ccs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called if an interval expires before sidewaysintpr has completed a loop.
|
||||
* Sets a flag to not wait for the alarm.
|
||||
*/
|
||||
void catchalarm(arg)
|
||||
int arg;
|
||||
{
|
||||
signalled = 1;
|
||||
}
|
||||
|
||||
get_ppp_stats(curp)
|
||||
struct ppp_stats *curp;
|
||||
{
|
||||
struct ifpppstatsreq req;
|
||||
|
||||
memset (&req, 0, sizeof (req));
|
||||
|
||||
req.stats_ptr = (caddr_t) &req.stats;
|
||||
#undef ifr_name
|
||||
#define ifr_name ifr__name
|
||||
|
||||
sprintf(req.ifr_name, "ippp%d", unit);
|
||||
if (ioctl(s, SIOCGPPPSTATS, &req) < 0) {
|
||||
if (errno == ENOTTY)
|
||||
fprintf(stderr, "ipppstats: kernel support missing\n");
|
||||
else
|
||||
perror("ioctl(SIOCGPPPSTATS)");
|
||||
exit(1);
|
||||
}
|
||||
*curp = req.stats;
|
||||
}
|
||||
|
||||
get_ppp_cstats(csp)
|
||||
struct ppp_comp_stats *csp;
|
||||
{
|
||||
struct ifpppcstatsreq creq;
|
||||
|
||||
memset (&creq, 0, sizeof (creq));
|
||||
|
||||
creq.stats_ptr = (caddr_t) &creq.stats;
|
||||
#undef ifr_name
|
||||
#define ifr_name ifr__name
|
||||
|
||||
sprintf(creq.ifr_name, "ippp%d", unit);
|
||||
if (ioctl(s, SIOCGPPPCSTATS, &creq) < 0) {
|
||||
if (errno == ENOTTY) {
|
||||
fprintf(stderr, "ipppstats: no kernel compression support\n");
|
||||
if (cflag)
|
||||
exit(1);
|
||||
rflag = 0;
|
||||
} else {
|
||||
perror("ioctl(SIOCGPPPCSTATS)");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (creq.stats.c.bytes_out == 0)
|
||||
creq.stats.c.ratio = 0.0;
|
||||
else
|
||||
creq.stats.c.ratio = (double) creq.stats.c.in_count /
|
||||
(double) creq.stats.c.bytes_out;
|
||||
|
||||
if (creq.stats.d.bytes_out == 0)
|
||||
creq.stats.d.ratio = 0.0;
|
||||
else
|
||||
creq.stats.d.ratio = (double) creq.stats.d.in_count /
|
||||
(double) creq.stats.d.bytes_out;
|
||||
|
||||
*csp = creq.stats;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue