Date: Sun, 16 Jan 2000 15:25:56 +0500 (ES) From: Ruslan Zalata To: bobovsky@koruna.pbko.sk Subject: cbcpS for pppd Hi Mr. Bobovsky! Some time ago I mailed you about your cbcpS patch for pppd. If you are still interesting in these things, here's a patch file one can apply to a pppd v. 2.3.5 or a higher. You can place it on your home page to make it available to other people. The whole pppd packages with the patch already applied one can find at: ftp://ftp.tyumen.ru/pub/stuff/ppp-2.3.5-2cbcps-radius-multiport.tgz BTW, a lot of improvenments and bug fixes were made since the last time I mailed you. Hope, you will like it :-). And thank you again for your valuable work! ------------------------ README.cbcpS-radius-multiport ------------------------- This README file describes how to: 1. Set up pppd to support RFC-1570 (CBCP) on a server side. 2. Set up pppd to support multiport dial-on-demand. CBCPS code: M.Bobovsky (Bbo) bobovsky@koruna.pbko.sk RADIUS code: Cyril A. Vechera St.-Petersburg, RUSSIA Some bug fixes and patches: Ruslan Zalata, rz@tyumen.ru Multiport dial-on-demand code: Ilia Ismailov, dali@trunk.ru URLs: http://rz.tyumen.ru, ftp://ftp.tyumen.ru/pub/stuff http://www.pbko.sk/~bobovsky/archiv/pppd-cbcpS-callback/ 1. What is CBCPS ? It is a Microsoft extention for PPP protocol, a heap of additions which made possible to send some configuration info from client to server during the CONFIGURATION phase within LCP packets. This made possible to have a callback server which asks client for a phone number and makes call back to a client if such required. CBCP stands for CallBack Control Protocol (Server side). 2. What is RADIUS ? It's Authentication and Authorization system developed somewhere in MIT, which let's you to have independent user base somewhere beyond a firewall and access server which authenticate all incoming and outgoing connections to a RADIUS server. NOTE: this packages does not include RADIUS server software. We suppose you already have one installed and operational. 3. What is Multiport Dial-On-Demand ? Originally, pppd has a `demand' option to initiate the link only on demand, i.e. when data traffic is present. You can read more about it in man pages. There's a problem with `demand' mode when pppd is runing on a multi line system with several incoming and outgoing modem lines. The problem is the following: when in demand mode there's no possibility to determine automatically what line to use for outgoing call (it uses the line you specified on command line or in /etc/ppp/options file manually). This is a serious problem when the system is a multi line access server. So, we implemented some mechanism for detecting a free line automatically, based on mgetty /etc/mg-pid.* files. This mechanism also uses .LCK files to lock busy devices to tell mgetty not to affect them. Read more mgetty docs about it. Configutarion procedure we described below in this file, section 10. 4. What is it to PPP ? This package contains a pppd software already patched to support RADIUS authentication system (RADIUS client) and CBCP server. NOTE: In case you got this README file separately from the whole ppp-2.3.5 package, there's a patch attached below. You can download the original ppp-2.3.5, unpack it and apply the patch. That means one can use this pppd software on the server side to handle incoming PPP connections, determine whether they need callback or not. A client side for such a server can be any MS Windows* system with Dialup Networking installed in it. NOTE: here we don't discuss any manipulations on a PPP client side. 5. What OSes currently supported ? Originally CBCPS support was written for Linux system, but it compiles and works just good for most FreeBSD releases. We believe that it will also work for all other systems supported by original ppp-2.3.5 package. 6. How do I set up all this ? There're two ways, you are probably doing one of the following: I. You can apply the patch (below in this file) to the original ppp-2.3.5. 1. you have to download ppp-2.3.5 from any official mirror site. 2. unpack it using tar. cat ppp-2.3.5.tgz | tar -zxpf - -C./ 3. go into pppd-2.3.5 source directory and type: patch -p1 < README.cbcpS-radius-multiport 4. if patch files successfully applied, you need to build the whole package as it described below skipping first two steps. 5. you can apply this patch to any other pppd version higher than 2.3.5 if you are not afraid of hacking, but it will take some time and patience and a lot of axe work :-) II. You can unpacking the ppp-2.3.5-2cbcps-radius-multiport.tgz file and build it just easily. The building process is usual for most unix systems. You have to pass through the following steps: 1. unpack this package somewhere to a /tmp directory cat ppp-2.3.5-2cbcps-radius-multiport.tgz | tar -zxpf - -C/tmp/ 2. chane dir into the package and run GNU configuration utility cd /tmp/ppp-2.3.5-2cbcps-radius-multiport; ./configure 3. read all the REAMEs in package. NOTE: this pppd software is based on ppp-2.3.5 package, so you must know how to set up pppd. Read pppd docs for more information. 4. make; make install 7. How to configure Callback on a server side ? First of all you need some front-end program which handles modems and answers calls. For some reason we recommend mgetty package. During further explainations on how to set up pppd on the server side we will assume that you are using mgetty. For more information on how to set up mgetty you can figure out from mgetty READMEs and docs. After you built and installed this pppd software you need to do the following configurations for a server side system: 1. Build your mgetty with PPP support (look into mgetty manuals) To make mgetty accept PPP calls, place the following line into your mgetty config file (/usr/local/etc/mgetty+sendfax/login.config): # /AutoPPP/ - - /usr/sbin/pppd auth +chap +pap cb login debug # NOTE: you can add/remove +pap and +chap options, but you must know that RADIUS support works with +pap option only. Anyway, you can use both of them. Don't forget to send kill -TERM to mgetty process to reread config. 2. Create a /etc/ppp directory and place there some files: /etc/ppp/options - a file with pppd global options. You can read a pppd man pages for more information on available options. We recommend the following global options: # -detach modem proxyarp crtscts mtu 268 netmask 0xffffffff ms-dns 195.161.8.69 # place here your DNS address asyncmap 0 lock radius /etc/ppp/radius # this is needed for RADIUS support, remove it # in case you don't going to use one # /etc/ppp/options.cuaa0 - place here a pair of IP addresses for this ppp line. Create such files for every line you are going to use for accepting incoming calls. The format of this file is the following: # 1.1.1.1:1.1.1.2 # Where 1.1.1.1 is local IP address, and 1.1.1.2 is remote one. /etc/ppp/radius - a radius client configuration file, contains IP addresses for RADIUS Authentication and Accounting servers. Format is the following: # secret retry_max 2 timeout 2 my_address local.ip.address.of.this.host rs_address ip.of.radius.authentication.server ra_address ip.of.radius.accounting.server rs_port 1645 ra_port 1646 # According to the above, you need to setup your secret password, local IP of your PPP access server (pppd will use it during RADIUS authorization) and a pair of IPs for authentication and accounting server. In ordinary case these two servers are the same. NOTE: don't forget to add your RADIUS client into your RADIUS server configuration files! Read more docs shipped with your RADIUS server. Then you have to proceed with exact Callback configurations: /etc/ppp/callbusers - a list of users who are enabled to use callback feature. The format of this file is rather strange (that was not me who invented it, so don't blame me on that), but very simple: # username!P!!!! otheruser!!V!!!! admuser!!!A!3452-39-00-55! # We'll explain things below: "username" is a name of a user who has callback disabled. It uses ppp in ordinary way. "otheruser" is a name of user who can do callbacks. When such a user connects to your system, pppd asks for a phone number, then drops carrier and makes a call back. "admuser" is a name of user who also has callback feature enableb, but it is not permitted to change his/her phone number. The number is administratively assigned. You can place as many users in /etc/ppp/callbusers as you need. /etc/ppp/callbackser - a simple shell script pppd execs every time it needs to do a callback. This shell script simply calls callback(8) utility to fulfil a required call back to user. We recommend you to use a callback(8) utility from mgetty package as in the follow: #!/bin/sh /usr/local/sbin/callback -l$1 -s 38400 T$3 # NOTE: don't forget to make chmod 755 /etc/ppp/callbackser. Enough descriptions for making callback feature work on your ppp access server. 8. How to configure client side / Windows 95 system to use CBCP ? In general, you don't need it because Dial-UP Networking subsystem in Windows 95 always tries to use CBCP protocol when it tries to establish PPP connection. Just set your server side in proper way and try to make a call. 9. What's about a Windows NT based client ? It's all the same. Except, there're some problems with password encryption. Just disable any password encryptions on NT box. 10. How to set up Multiport Dial-On-Demand ? 1. you have to apply patch and build the ppp-2.3.5 package. Read section 6 of this file. 2. read pppd dosc on how to set up dial on demand feature. Configure your /etc/ppp/options file in proper way. 3. add the followind option into your /etc/ppp/options file: multiport [first_port]:[last_port] Where first_port:last_port is the range of ports available for dial on demand. You can omit ports for all ports available. The details of multiport algorithm described in README.multiport. 11. Contacts If you have any problems, or oposite you have succeed in using this package, please contact me via e-mail: Ruslan Zalata . I would like to know you are using this packages and in what apposition. Thank you for reading this! PS: any additions to the code are also acceptable. 12. Thanks I would like to thank M.Bobovski who wrote all the CBCPS code which I patched a bit to suit my needs. Also I would like to thank Cyril A. Vechera who wrote a nice small code of RADIUS client. Thank you Cyril! ------------------------------------------------------------------------------- diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile *** ppp-2.3.5/pppd/Makefile Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile Thu Aug 19 15:20:02 1999 *************** *** 0 **** --- 1,21 ---- + # $Id: Makefile.bsd,v 1.14 1998/03/25 01:27:00 paulus Exp $ + + BINDIR?= /usr/sbin + # -D_BITYPES is for FreeBSD, which doesn't define anything to + # tell us that u_int32_t gets defined if is included. + # Remove for older *BSD systems for which this isn't true. + CFLAGS+= -g -I../include -DHAVE_PATHS_H -D_BITYPES + + PROG= pppd + SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ + demand.c auth.c options.c sys-bsd.c cbcps.c pppdradius.c libradius.c \ + callerid.c con_state.c + MAN= pppd.cat8 + MAN8= pppd.8 + BINMODE=4555 + BINOWN= root + + LDADD= -lcrypt -lutil + DPADD= ${LIBCRYPT} ${LIBUTIL} + + .include diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.NeXT ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.NeXT *** ppp-2.3.5/pppd/Makefile.NeXT Wed Mar 25 06:26:53 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.NeXT Sun Jan 24 14:39:09 1999 *************** *** 11,17 **** MANDIR = /usr/local/ppp/man OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-NeXT.o # # For HPPA and SPARC, define FIXSIGS to get around posix bugs in --- 11,17 ---- MANDIR = /usr/local/ppp/man OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-NeXT.o cbcps.o pppdradius.o libradius.o # # For HPPA and SPARC, define FIXSIGS to get around posix bugs in diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.bsd ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.bsd *** ppp-2.3.5/pppd/Makefile.bsd Wed Mar 25 06:26:56 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.bsd Thu Aug 19 15:20:02 1999 *************** *** 8,14 **** PROG= pppd SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ ! demand.c auth.c options.c sys-bsd.c MAN= pppd.cat8 MAN8= pppd.8 BINMODE=4555 --- 8,15 ---- PROG= pppd SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ ! demand.c auth.c options.c sys-bsd.c cbcps.c pppdradius.c libradius.c \ ! callerid.c con_state.c MAN= pppd.cat8 MAN8= pppd.8 BINMODE=4555 diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.linux ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.linux *** ppp-2.3.5/pppd/Makefile.linux Mon May 4 12:10:29 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.linux Sun Jan 24 14:42:28 1999 *************** *** 9,20 **** 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 md4.c chap_ms.c cbcp.c \ ! demand.c HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h chap_ms.h md4.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 demand.o sys-linux.o ipxcp.o all: pppd --- 9,20 ---- 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 md4.c chap_ms.c cbcp.c \ ! demand.c cbcps.c pppdradius.c libradius.c HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h chap_ms.h md4.h \ ! ipxcp.h cbcp.h cbcps.h pppdradius.h radius.h libradius.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 demand.o sys-linux.o ipxcp.o cbcps.o pppdradius.o libradius.o all: pppd *************** *** 30,36 **** VER = 2.3.5 LIBS = ! ifneq ($(wildcard /usr/lib/libcrypt*),) LIBS += -lcrypt endif --- 30,36 ---- VER = 2.3.5 LIBS = ! ifneq ($(wildcard /usr/lib/libcrypt.*),) LIBS += -lcrypt endif *************** *** 38,44 **** # MS-CHAP authentication protocol. CHAPMS=y USE_CRYPT=y ! ifneq ($(wildcard /usr/lib/libcrypt*),) HAVE_CRYPT_H=y endif --- 38,44 ---- # MS-CHAP authentication protocol. CHAPMS=y USE_CRYPT=y ! ifneq ($(wildcard /usr/lib/libcrypt.*),) HAVE_CRYPT_H=y endif *************** *** 87,97 **** install: pppd mkdir -p $(BINDIR) $(MANDIR) ! install -s -c -m 4555 -o root pppd $(BINDIR)/pppd install -c -m 444 -o root pppd.8 $(MANDIR)/man8 pppd: $(PPPDOBJS) $(CC) $(CFLAGS) -o pppd $(PPPDOBJS) $(LIBS) clean: rm -f $(PPPDOBJS) pppd *~ #* core --- 87,100 ---- install: pppd mkdir -p $(BINDIR) $(MANDIR) ! install -s -c -m 4555 -o root -g dip pppd $(BINDIR)/pppd install -c -m 444 -o root pppd.8 $(MANDIR)/man8 pppd: $(PPPDOBJS) $(CC) $(CFLAGS) -o pppd $(PPPDOBJS) $(LIBS) + + testchap: testchap.c chap_ms.o md4.o + $(CC) $(CFLAGS) -o testchap $(^) $(LIBS) clean: rm -f $(PPPDOBJS) pppd *~ #* core diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.netbsd-1.2 ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.netbsd-1.2 *** ppp-2.3.5/pppd/Makefile.netbsd-1.2 Thu Mar 12 15:37:32 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.netbsd-1.2 Sun Jan 24 14:42:46 1999 *************** *** 4,10 **** PROG= pppd SRCS= auth.c cbcp.c ccp.c chap.c chap_ms.c demand.c fsm.c ipcp.c \ ! ipxcp.c lcp.c magic.c main.c options.c sys-bsd.c upap.c .PATH: ${PCAPDIR} ${.CURDIR}/../../sys/net MAN= pppd.8 pppd.cbcp.8 --- 4,10 ---- PROG= pppd SRCS= auth.c cbcp.c ccp.c chap.c chap_ms.c demand.c fsm.c ipcp.c \ ! ipxcp.c lcp.c magic.c main.c options.c sys-bsd.c upap.c cbcps.c pppdradius.c libradius.c .PATH: ${PCAPDIR} ${.CURDIR}/../../sys/net MAN= pppd.8 pppd.cbcp.8 diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.osf ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.osf *** ppp-2.3.5/pppd/Makefile.osf Wed Mar 25 06:27:00 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.osf Sun Jan 24 14:43:19 1999 *************** *** 7,16 **** MANDIR = /usr/local/man PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ ! auth.c options.c demand.c sys-osf.c md4.c chap_ms.c PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-osf.o md4.o chap_ms.o CC = cc DEBUG_FLAGS = -DDEBUGALL --- 7,16 ---- MANDIR = /usr/local/man PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ ! auth.c options.c demand.c sys-osf.c md4.c chap_ms.c cbcps.c pppdradius.c libradius.c PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-osf.o md4.o chap_ms.o cbcps.o pppdradius.o libradius.o CC = cc DEBUG_FLAGS = -DDEBUGALL diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.sol2 ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.sol2 *** ppp-2.3.5/pppd/Makefile.sol2 Wed Mar 25 06:27:01 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.sol2 Sun Jan 24 14:43:44 1999 *************** *** 11,17 **** all: pppd OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-svr4.o pppd: $(OBJS) $(CC) -o pppd $(OBJS) $(LIBS) --- 11,17 ---- all: pppd OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-svr4.o cbcps.o pppdradius.o libradius.o pppd: $(OBJS) $(CC) -o pppd $(OBJS) $(LIBS) diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.sunos4 ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.sunos4 *** ppp-2.3.5/pppd/Makefile.sunos4 Wed Mar 25 06:27:03 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.sunos4 Sun Jan 24 14:44:03 1999 *************** *** 12,18 **** all: pppd OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-sunos4.o pppd: $(OBJS) $(CC) -o pppd $(OBJS) $(LIBS) --- 12,18 ---- all: pppd OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-sunos4.o cbcps.o pppdradius.o libradius.o pppd: $(OBJS) $(CC) -o pppd $(OBJS) $(LIBS) diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.svr4 ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.svr4 *** ppp-2.3.5/pppd/Makefile.svr4 Wed Mar 25 06:27:04 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.svr4 Sun Jan 24 14:45:35 1999 *************** *** 11,17 **** all: pppd OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-svr4.o pppd: $(OBJS) $(CC) -o pppd $(OBJS) $(LIBS) --- 11,17 ---- all: pppd OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-svr4.o cbcps.o pppdradius.o libradius.o pppd: $(OBJS) $(CC) -o pppd $(OBJS) $(LIBS) diff -r -P -d -C 3 ppp-2.3.5/pppd/Makefile.ultrix ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.ultrix *** ppp-2.3.5/pppd/Makefile.ultrix Wed Mar 25 06:27:05 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/Makefile.ultrix Sun Jan 24 14:45:23 1999 *************** *** 7,16 **** MANDIR = /usr/local/man PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ ! auth.c options.c demand.c sys-ultrix.c PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-ultrix.o # CC = gcc DEBUG_FLAGS = --- 7,16 ---- MANDIR = /usr/local/man PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ ! auth.c options.c demand.c sys-ultrix.c cbcps.c pppdradius.c libradius.c PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ ! auth.o options.o demand.o sys-ultrix.o cbcps.o pppdradius.o libradius.o # CC = gcc DEBUG_FLAGS = diff -r -P -d -C 3 ppp-2.3.5/pppd/auth.c ppp-2.3.5-2cbcps-radius-multiport/pppd/auth.c *** ppp-2.3.5/pppd/auth.c Thu Mar 26 09:46:00 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/auth.c Fri Dec 3 15:24:10 1999 *************** *** 68,73 **** --- 68,74 ---- #endif #include "pppd.h" + #include "cbcps.h" #include "fsm.h" #include "lcp.h" #include "ipcp.h" *************** *** 77,82 **** --- 78,84 ---- #include "cbcp.h" #endif #include "pathnames.h" + #include "pppdradius.h" /* Used for storing a sequence of words. Usually malloced. */ struct wordlist { *************** *** 102,107 **** --- 104,110 ---- /* Set if we have successfully called plogin() */ static int logged_in; + int fd; /* Set if we have run the /etc/ppp/auth-up script. */ static int did_authup; *************** *** 117,122 **** --- 120,128 ---- /* Set if we got the contents of passwd[] from the pap-secrets file. */ static int passwd_from_file; + /* we store here the user name for future use from akysposobppp() */ + char user[256]; + /* Bits in auth_pending[] */ #define PAP_WITHPEER 1 #define PAP_PEER 2 *************** *** 127,133 **** /* Prototypes for procedures local to this file. */ ! static void network_phase __P((int)); static void check_idle __P((void *)); static void connect_time_expired __P((void *)); static int plogin __P((char *, char *, char **, int *)); --- 133,140 ---- /* Prototypes for procedures local to this file. */ ! void network_phase __P((int)); ! static void callback_phase __P((int)); static void check_idle __P((void *)); static void connect_time_expired __P((void *)); static int plogin __P((char *, char *, char **, int *)); *************** *** 165,170 **** --- 172,179 ---- return; if (logged_in) plogout(); + if (radlogged_in) + radlogout(); phase = PHASE_DEAD; syslog(LOG_NOTICE, "Connection terminated."); } *************** *** 233,238 **** --- 242,255 ---- } } + if(*calleridtool) + getcallerid(devnam); + /* if connection is ok, try to resolve caller's id */ + + if(*con_tool) + getconstate(devnam); + /* get CONNECT string */ + phase = PHASE_AUTHENTICATE; auth = 0; if (go->neg_chap) { *************** *** 256,269 **** } auth_pending[unit] = auth; ! if (!auth) ! network_phase(unit); } /* * Proceed to the network phase. */ ! static void network_phase(unit) int unit; { --- 273,286 ---- } auth_pending[unit] = auth; ! if (!auth) // ak neni auth tak priamo bez chap/pap ideme. ! callback_phase(unit); } /* * Proceed to the network phase. */ ! void network_phase(unit) int unit; { *************** *** 308,313 **** --- 325,361 ---- lcp_close(0, "No network protocols running"); } + static void + callback_phase(int unit) //faza callbacku .. treba pozret ci sa moze obist. + { + lcp_options *wo=&lcp_wantoptions[unit]; + lcp_options *go=&lcp_gotoptions[unit]; + + akysposobppp(user); /* figure out what callback options user has */ + + if(!cbcp_protent.enabled_flag) { + network_phase(unit); + return; + } // neni cb switch + // to sa pouzilo napr pri spatnom volani. + if(!wo->neg_cbcp || !go->neg_cbcp) { //asi by stacilo len go pozerat. + /* + if(cbcp_priamo) // smie sa obist nevylicitovanim ... inac je to podfuk. + */ + network_phase(unit); // pri licitacii alebo cez opt cb nepovolena + /* + else { + syslog(LOG_WARNING, "CBCP Nedovoleny pokus obist cb zlou licitaciu"); + auth_peer_fail(unit,PPP_CBCP); + return;} + */ + } + else { + phase = PHASE_CALLBACK; + cbcp_open(unit); // toto ho prinuti poslat vyzvu .. + } + } + /* * The peer has failed to authenticate himself using `protocol'. */ *************** *** 359,365 **** * proceed to the network (or callback) phase. */ if ((auth_pending[unit] &= ~bit) == 0) ! network_phase(unit); } /* --- 407,414 ---- * proceed to the network (or callback) phase. */ if ((auth_pending[unit] &= ~bit) == 0) ! { // syslog(LOG_DEBUG," bbo po auth_peer_success"); ! callback_phase(unit);} } /* *************** *** 612,624 **** char **msg; int *msglen; { ! int ret; char *filename; FILE *f; struct wordlist *addrs; u_int32_t remote; ipcp_options *ipwo = &ipcp_wantoptions[unit]; ! char passwd[256], user[256]; char secret[MAXWORDLEN]; static int attempts = 0; --- 661,675 ---- char **msg; int *msglen; { ! int ret,i; char *filename; FILE *f; + char *tty; struct wordlist *addrs; + struct utmp utmp; u_int32_t remote; ipcp_options *ipwo = &ipcp_wantoptions[unit]; ! char passwd[256]; char secret[MAXWORDLEN]; static int attempts = 0; *************** *** 630,636 **** BCOPY(auser, user, userlen); user[userlen] = '\0'; *msg = (char *) 0; ! /* * Open the file of pap secrets and scan for a suitable secret * for authenticating this user. --- 681,687 ---- BCOPY(auser, user, userlen); user[userlen] = '\0'; *msg = (char *) 0; ! akysposobppp(user); /* * Open the file of pap secrets and scan for a suitable secret * for authenticating this user. *************** *** 638,661 **** filename = _PATH_UPAPFILE; addrs = NULL; ret = UPAP_AUTHACK; f = fopen(filename, "r"); if (f == NULL) { ! syslog(LOG_ERR, "Can't open PAP password file %s: %m", filename); ! ret = UPAP_AUTHNAK; } else { check_access(f, filename); - remote = ipwo->accept_remote? 0: ipwo->hisaddr; if (scan_authfile(f, user, our_name, remote, secret, &addrs, filename) < 0 || (secret[0] != 0 && (cryptpap || strcmp(passwd, secret) != 0) && strcmp(crypt(passwd, secret), secret) != 0)) { ! syslog(LOG_WARNING, "PAP authentication failure for %s", user); ret = UPAP_AUTHNAK; } fclose(f); - } if (uselogin && ret == UPAP_AUTHACK) { ret = plogin(user, passwd, msg, msglen); if (ret == UPAP_AUTHNAK) { --- 689,729 ---- filename = _PATH_UPAPFILE; addrs = NULL; ret = UPAP_AUTHACK; + remote = ipwo->accept_remote? 0: ipwo->hisaddr; f = fopen(filename, "r"); if (f == NULL) { ! if(!useradius && !uselogin) { ! syslog(LOG_ERR, "Can't open PAP password file %s: %m", filename); ! ret = UPAP_AUTHNAK; ! } } else { + check_access(f, filename); if (scan_authfile(f, user, our_name, remote, secret, &addrs, filename) < 0 || (secret[0] != 0 && (cryptpap || strcmp(passwd, secret) != 0) && strcmp(crypt(passwd, secret), secret) != 0)) { ! syslog(LOG_WARNING, "upap: local base/pap-secrets authentication failure for %s", user); ret = UPAP_AUTHNAK; } + else { + tty = devnam; + if (strncmp(tty, "/dev/", 5) == 0) + tty += 5; + for(i=0;i19 ? 19: strlen(client)); + cbcpuser[19]=0; + if (akysposobppp(cbcpuser)<1) return 0; f = fopen(filename, "r"); if (f == NULL) { syslog(LOG_ERR, "Can't open chap secret file %s: %m", filename); *************** *** 1197,1203 **** return 0; if (addrs == NULL) ! return !auth_required; /* no addresses authorized */ for (; addrs != NULL; addrs = addrs->next) { /* "-" means no addresses authorized, "*" means any address allowed */ --- 1291,1297 ---- return 0; if (addrs == NULL) ! return -1; // what the fucking animal did this: !auth_required; /* no addresses authorized */ for (; addrs != NULL; addrs = addrs->next) { /* "-" means no addresses authorized, "*" means any address allowed */ diff -r -P -d -C 3 ppp-2.3.5/pppd/callerid.c ppp-2.3.5-2cbcps-radius-multiport/pppd/callerid.c *** ppp-2.3.5/pppd/callerid.c Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/callerid.c Thu Aug 19 15:38:50 1999 *************** *** 0 **** --- 1,33 ---- + /* + * Implimentation of Caller's ID + * by Ruslan Zalata, 1999, rz@tyumen.ru + */ + #include + #include + #include + #include + #include + + #include "pppd.h" + + void getcallerid(char *device) + { + int fd[2]; + int i,pid,status; + + pipe(fd); + + if((pid=fork())==NULL) { + close(1); + dup(fd[1]); + if(execlp(calleridtool,calleridtool,device,NULL) == -1) + syslog(LOG_ERR,"Can't execute %s",calleridtool); + } + + read(fd[0],&callerid,16); + wait(&status); + for(i=0;i<16;i++) if(callerid[i]==13 || callerid[i]==10) callerid[i]=0; + callerid[15]=0; + + syslog(LOG_WARNING,"Caller's ID is: %s",callerid); + } diff -r -P -d -C 3 ppp-2.3.5/pppd/cbcps.c ppp-2.3.5-2cbcps-radius-multiport/pppd/cbcps.c *** ppp-2.3.5/pppd/cbcps.c Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/cbcps.c Sun Aug 15 16:35:47 1999 *************** *** 0 **** --- 1,284 ---- + /* + * cbcps - Call Back Configuration Protocol. SERVER + * Miro Bobovsky , 7.11.1998 ver2.0 + * robte s tym co chete - GPL a lubovolny iny vse povoliaci. + * ocakavam za pppd prepinac auth +chap -pap cb ip:ip + * ocakavam subor /etc/ppp/callbusers kde su user (nestaci chap-s) + * s patricnym sytaxom meno!P!V!A!cislo!. + * snazim sa spustit /etc/ppp/callbackser pre volanie. (pppd chat). + */ + #include + #include + #include + #include + #include + + #include "pppd.h" + #include "fsm.h" + #include "lcp.h" + #include "ipcp.h" + #include "cbcps.h" + + extern void network_phase __P((int)); + + void cbcp_recvresp(cbcp_state *us, char *pckt, int len); + void cbcp_sendack(cbcp_state *us,u_char type,u_char delay ); + + cbcp_state cbcp[NUM_PPP]; + char cbcpuser[20]; + int cbcp_priamo=1,cbcp_volit=0,cbcp_admin=0; + char cbcp_adminn[]="********************"; + struct protent cbcp_protent = { + PPP_CBCP, + cbcp_init, + cbcp_input, + cbcp_protrej, + cbcp_lowerup, + NULL, + cbcp_open, + NULL, + cbcp_printpkt, + NULL, + 0, + "CBCP", + NULL, + NULL, + NULL + }; + + + void cbcp_lowerup(int iface) //vola lcp.c + { + LCPDEBUG((LOG_DEBUG," bbo cbcp_lowerup")); + } + + void cbcp_init(int iface) // z main.c + { + cbcp_state *us; + + LCPDEBUG((LOG_DEBUG," bbo cbcp_init")); + cbcpuser[0]=0; + cbcp_volit=cbcp_admin=0; + cbcp_priamo=1; + cbcp_adminn[0]=0; + us = &cbcp[iface]; + memset(us, 0, sizeof(cbcp_state)); + us->us_unit = iface; + } + + void cbcp_open(int unit) //z auth -- startuje cbcp komunikaciu + { + u_char buf[256]; + u_char *bufp = buf; + u_char *outp; + int outlen; + cbcp_state *us = &cbcp[unit]; + + us->us_id = 1; + outp = outpacket_buf; + outlen=4; //hlavicka + if(cbcp_priamo) { outlen+=2; + PUTCHAR(CB_CONF_NO, bufp);PUTCHAR(2 , bufp);} + if(cbcp_volit) { outlen+=5; + PUTCHAR(CB_CONF_USER, bufp);PUTCHAR(5 , bufp); //typ,dlzka + PUTCHAR(0, bufp);PUTCHAR(1, bufp);PUTCHAR(0, bufp);} //delay,atyp,cisloZ + if(cbcp_admin) { outlen+=2; + PUTCHAR(CB_CONF_ADMIN, bufp);PUTCHAR(2 , bufp);} + LCPDEBUG((LOG_DEBUG, "bbo cbcp_open")); + MAKEHEADER(outp, PPP_CBCP); // a dorobim paket , dlzky a ... + PUTCHAR(CBCP_REQ, outp); // prikaz + PUTCHAR(us->us_id,outp); //id + PUTSHORT(outlen, outp); // IBAZE WINNT posiela to kazde 2 sek. + BCOPY(buf, outp, outlen-4); // s novym id a ja len raz .. ale ide. + output(1, outpacket_buf, outlen + PPP_HDRLEN); + } + + void cbcp_close(int unit) + { + LCPDEBUG((LOG_DEBUG, "bbo cbcp_close")); + } + + /* process an incomming packet */ + void cbcp_input(int unit, u_char *inpacket, int pktlen) + { + u_char *inp; + u_char code, id; + u_short len; + + cbcp_state *us = &cbcp[unit]; + inp = inpacket; + LCPDEBUG((LOG_DEBUG," bbo cbcp_input")); + if (pktlen < CBCP_MINLEN) { + syslog(LOG_ERR, "CBCP packet is too small"); + return; + } + + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + + if (len > pktlen) { + syslog(LOG_ERR, "CBCP packet: invalid length"); + return; + } + + len -= CBCP_MINLEN; + + switch(code) { + case CBCP_REQ: // toto je neosetrene bo nema co prist. + syslog(LOG_ERR, "CBCP_REQ received !!!!"); + break; + + case CBCP_RESP: + LCPDEBUG((LOG_DEBUG, "CBCP_RESP received")); + if (id != us->us_id) + syslog(LOG_ERR,"CBCP RESP zle id, caka %d dostal %d",us->us_id,id); + cbcp_recvresp(us,inp,len); + break; + + case CBCP_ACK: // toto je neosetrene bo nema co prist. + syslog(LOG_ERR, "CBCP_ACK received !!!!"); + break; + + default: + break; + } + } + + /* protocol was rejected by foe */ + void cbcp_protrej(int iface) + { + LCPDEBUG((LOG_DEBUG," bbo cbcp_protrej")); + } + int cbcp_printpkt(u_char *p, int plen, + void (*printer) __P((void *, char *, ...)), + void *arg) + { + LCPDEBUG((LOG_DEBUG," bbo cbcp_printpkt")); + return 0; //urcite zle lebo mal vratit kolko asi pochopil znakov. + } + + void cbcp_recvresp(cbcp_state *us, char *pckt, int len) + { + u_char type, delay=0, addr_type; + int opt_len,dlzka; + + if (len<2) { + syslog(LOG_ERR, "CBCP recvresp: kratky, %d",len); + phase=PHASE_TERMINATE; return;} + + GETCHAR(type, pckt); + GETCHAR(opt_len, pckt); + + if (opt_len > 2) + GETCHAR(delay, pckt); + switch(type) { + case CB_CONF_NO: + if(cbcp_admin) + {syslog(LOG_ERR,"CBCP got CB_CONF_NO while cbcp_admin is set"); + phase=PHASE_TERMINATE; type=CB_CONF_NOT_ALLOWED; break;} + /* if(!cbcp_priamo) + {syslog(LOG_ERR, "CBCP Podvadza - vratil co som nenukal"); + phase=PHASE_TERMINATE; return;} + */ + break; + case CB_CONF_ADMIN: + if(!cbcp_admin) + {syslog(LOG_ERR, "CBCP Podvadza - vratil co som nenukal"); + phase=PHASE_TERMINATE; return;} + break; + default: // t.j. asi voli ale pozreme. + if(!cbcp_volit) + {syslog(LOG_ERR, "CBCP Podvadza - vratil co som nenukal"); + phase=PHASE_TERMINATE; return;} + if(opt_len>4) { + GETCHAR(addr_type, pckt); + dlzka=opt_len - 4<20?opt_len - 4:19; + memcpy(cbcp_adminn, pckt, dlzka); + cbcp_adminn[dlzka]=0; + LCPDEBUG((LOG_DEBUG, "mam cislo: %s", cbcp_adminn)); + } + } + cbcp_sendack(us,type,delay); + } + + void cbcp_sendack( cbcp_state *us,u_char type,u_char delay ) + { + u_char buf[256]; + u_char *bufp = buf; + int len = 0; + u_char *outp; + int outlen; + + outp = outpacket_buf; + switch(type) { + case CB_CONF_NO: + len=2;PUTCHAR(CB_CONF_NO, bufp);PUTCHAR(len , bufp); + break; + case CB_CONF_USER: + len=strlen(cbcp_adminn)+5; + PUTCHAR(CB_CONF_USER, bufp);PUTCHAR(len, bufp);PUTCHAR(delay, bufp); + PUTCHAR(1, bufp);BCOPY(cbcp_adminn,bufp,len-5);bufp+=len-5; + PUTCHAR(0, bufp);break; + case CB_CONF_ADMIN: + len=3;PUTCHAR(CB_CONF_ADMIN,bufp);PUTCHAR(len,bufp);PUTCHAR(delay,bufp); + break; + default: + syslog(LOG_ERR, "CBCP Podvadza - v type"); + phase=PHASE_TERMINATE; break; + } + LCPDEBUG((LOG_DEBUG, "bbo cbcp_sendack")); + outlen = 4 + len; + MAKEHEADER(outp, PPP_CBCP); + PUTCHAR(CBCP_ACK, outp); + PUTCHAR(us->us_id,outp); + PUTSHORT(outlen, outp); + BCOPY(buf, outp, len); + output(1, outpacket_buf, outlen + PPP_HDRLEN); + if(phase != PHASE_TERMINATE) network_phase(us->us_unit); + + if(type==CB_CONF_ADMIN || type==CB_CONF_USER){ //spustenie programu na volanie + char *argv[4]; + argv[0] = "/etc/ppp/callbackser"; //progam + argv[1] = devnam; // /dev/ttyS? + argv[2] = cbcpuser; //ID + argv[3] = cbcp_adminn; // cislo + argv[4] = user; + argv[5] = NULL; + run_program(argv[0], argv, 0); + } + } + + int akysposobppp(char *kto) + { + FILE *fp; + char *a,*b; + char riadok[81]; + + cbcp_volit=cbcp_admin=0; + cbcp_priamo=1; + cbcp_adminn[0]=0; + if(strlen(kto)<2) {syslog(LOG_ERR,"CBCP - kratke meno"); return 0;} + if((fp=fopen("/etc/ppp/callbusers","r"))==NULL) + {syslog(LOG_ERR,"CBCP neviem otvorit callbusers");return 0;} + while(fgets(riadok,80,fp)!=NULL){ + if( *riadok=='#' ) continue; + if( (a=strchr(riadok,'!'))!=NULL ) *(a++)=0; + if(strcmp(riadok,kto)==0) { + if( strlen(a)<5 ) {syslog(LOG_ERR,"CBCP chybny riadok"); + fclose(fp);return 0;} + if( *(a++)=='P') {a++;cbcp_priamo=1;} + if( *(a++)=='V') {a++;cbcp_volit=1;cbcp_priamo=0;} + if( *(a++)=='A') { + a++; + if( (b=strchr(a,'!'))!=NULL ) + {*b=0;strncpy(cbcp_adminn,a,20);cbcp_admin=1;} + } + fclose(fp); + syslog(LOG_INFO,"meno:%s P:%d V:%d A:%d cislo:[%s]\n", + kto,cbcp_priamo,cbcp_volit,cbcp_admin,cbcp_adminn); + return 1;} + } + fclose(fp);syslog(LOG_ERR,"CBCP neni v callbusers");return 0; + } + diff -r -P -d -C 3 ppp-2.3.5/pppd/cbcps.h ppp-2.3.5-2cbcps-radius-multiport/pppd/cbcps.h *** ppp-2.3.5/pppd/cbcps.h Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/cbcps.h Sun Aug 15 15:56:04 1999 *************** *** 0 **** --- 1,40 ---- + /* + * cbcps - Call Back Configuration Protocol. SERVER + * Miro Bobovsky , 7.11.1998 ver2.0 + * robte s tym co chete - GPL a lubovolny iny vse povoliaci. + */ + + #define PPP_CBCP 0xc029 /* Callback Control Protocol */ + typedef struct cbcp_state { + int us_unit; /* Interface unit number */ + u_char us_id; /* Current id */ + } cbcp_state; + + void cbcp_init __P((int)); + void cbcp_open __P((int)); + void cbcp_lowerup __P((int)); + void cbcp_input __P((int, u_char *, int)); + void cbcp_protrej __P((int)); + int cbcp_printpkt __P((u_char *, int,void (*) __P((void *, char *, ...)), + void *)); + extern cbcp_state cbcp[]; + extern struct protent cbcp_protent; + extern char cbcpuser[]; + extern int cbcp_volit; // ci sme si uzer volit callb cislo + extern int cbcp_admin; // cislo zadava admin a user ho ani nevie. + extern int cbcp_priamo; // smie ist bez callbacku. + extern char cbcp_adminn[]; // cislo (ad admina alebo od usera ak moze. + int akysposobppp(char *kto); // fcia co pozera callbusers a nastavi param. + + #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 + #define CB_CONF_NOT_ALLOWED 254 + diff -r -P -d -C 3 ppp-2.3.5/pppd/chap.c ppp-2.3.5-2cbcps-radius-multiport/pppd/chap.c *** ppp-2.3.5/pppd/chap.c Thu Nov 27 11:07:48 1997 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/chap.c Sun Jan 24 14:36:52 1999 *************** *** 579,584 **** --- 579,585 ---- ChapSendStatus(cstate, code); if (code == CHAP_SUCCESS) { + syslog(LOG_NOTICE, "CHAP %s login ok:%s",devnam,rhostname); old_state = cstate->serverstate; cstate->serverstate = CHAPSS_OPEN; if (old_state == CHAPSS_INITIAL_CHAL) { *************** *** 590,595 **** --- 591,597 ---- rhostname); } else { + syslog(LOG_NOTICE, "CHAP %s login error:%s",devnam,rhostname); syslog(LOG_ERR, "CHAP peer authentication failed for remote host %s", rhostname); cstate->serverstate = CHAPSS_BADAUTH; diff -r -P -d -C 3 ppp-2.3.5/pppd/con_state.c ppp-2.3.5-2cbcps-radius-multiport/pppd/con_state.c *** ppp-2.3.5/pppd/con_state.c Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/con_state.c Thu Aug 19 15:45:32 1999 *************** *** 0 **** --- 1,33 ---- + /* + * Implimentation of 'Get connection string from mgetty log' + * by Ruslan Zalata, 1999, rz@tyumen.ru + */ + #include + #include + #include + #include + #include + + #include "pppd.h" + + void getconstate(char *device) + { + int fd[2]; + int i,pid,status; + + pipe(fd); + + if((pid=fork())==NULL) { + close(1); + dup(fd[1]); + if(execlp(con_tool,con_tool,device,NULL) == -1) + syslog(LOG_ERR,"Can't execute %s",con_tool); + } + + read(fd[0],&con_state,32); + wait(&status); + for(i=0;i<32;i++) if(con_state[i]==13 || con_state[i]==10) con_state[i]=0; + con_state[31]=0; + + syslog(LOG_WARNING,"Caller's CONNECT: %s",con_state); + } diff -r -P -d -C 3 ppp-2.3.5/pppd/ipcp.c ppp-2.3.5-2cbcps-radius-multiport/pppd/ipcp.c *** ppp-2.3.5/pppd/ipcp.c Wed Apr 29 05:38:10 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/ipcp.c Sun Jan 24 14:36:51 1999 *************** *** 134,139 **** --- 134,146 ---- #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") + /* + * Added to allow static and dynamic ips(s) + * Hold the static address from pap-secrets + */ + u_int32_t staticaddr; + /******************************************/ + /* * Make a string representation of a network IP address. *************** *** 824,829 **** --- 831,845 ---- orc = CONFNAK; if (!reject_if_disagree) { DECPTR(sizeof(u_int32_t), p); + + /* + * Added to allow static and dynamic ip(s) + * Are they asking for their static ip from pap-secrets? + */ + if(ciaddr1 !=0 && ciaddr1 == staticaddr) + wo->hisaddr = staticaddr; /* Let them use the static ip */ + /*******************************************/ + tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } *************** *** 885,890 **** --- 901,915 ---- orc = CONFNAK; if (!reject_if_disagree) { DECPTR(sizeof(u_int32_t), p); + + /* + * Added to allow static and dynamic ip(s) + * Are they asking for their static ip from pap-secrets? + */ + if(ciaddr1 !=0 && ciaddr1 == staticaddr) + wo->hisaddr = staticaddr; /* Let them use the static ip */ + /*******************************************/ + tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } diff -r -P -d -C 3 ppp-2.3.5/pppd/ipcp.h ppp-2.3.5-2cbcps-radius-multiport/pppd/ipcp.h *** ppp-2.3.5/pppd/ipcp.h Wed Apr 29 05:38:11 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/ipcp.h Sun Jan 24 14:36:51 1999 *************** *** 67,70 **** --- 67,76 ---- char *ip_ntoa __P((u_int32_t)); + /* Added to allow static and dynamic ip(s). + * Holds the static ip from pap-secrets + */ + u_int32_t staticaddr; + /******************************************/ + extern struct protent ipcp_protent; diff -r -P -d -C 3 ppp-2.3.5/pppd/ipxcp.c ppp-2.3.5-2cbcps-radius-multiport/pppd/ipxcp.c *** ppp-2.3.5/pppd/ipxcp.c Wed Mar 25 08:08:16 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/ipxcp.c Sun Jan 24 14:36:51 1999 *************** *** 146,152 **** { short int external; ! if (internal & IPX_NONE) external = IPX_NONE; else external = RIP_SAP; --- 146,152 ---- { short int external; ! if (internal & BIT(IPX_NONE)) external = IPX_NONE; else external = RIP_SAP; *************** *** 532,540 **** ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network); ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node); ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name); ! ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); ! ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); ! ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); /* * This is the end of the record. */ --- 532,539 ---- ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network); ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node); ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name); ! if (len > 0) ! ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); /* * This is the end of the record. */ diff -r -P -d -C 3 ppp-2.3.5/pppd/lcp.c ppp-2.3.5-2cbcps-radius-multiport/pppd/lcp.c *** ppp-2.3.5/pppd/lcp.c Thu Nov 27 11:08:44 1997 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/lcp.c Sun Aug 15 14:53:42 1999 *************** *** 1398,1403 **** --- 1398,1412 ---- } ho->neg_accompression = 1; break; + case CI_CALLBACK: // on mi ponuka cbcp a co ja na to. + LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd Bbo callback")); + if (!ao->neg_cbcp || + cilen != CILEN_CBCP) { + orc = CONFREJ; + break; + } + ho->neg_cbcp = 1; + break; default: LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d", diff -r -P -d -C 3 ppp-2.3.5/pppd/libradius.c ppp-2.3.5-2cbcps-radius-multiport/pppd/libradius.c *** ppp-2.3.5/pppd/libradius.c Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/libradius.c Thu Aug 19 15:48:52 1999 *************** *** 0 **** --- 1,421 ---- + /* Copyright (c) 1997 Cyril A. Vechera St.-Petersburg, RUSSIA + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 4. Any form of use of source and binaries are permitted only for + * noncommercial purpose. Any forms of commercial usage require + * direct author's permission. + */ + + /* RADIUS-client library + */ + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "radius.h" + #include "libradius.h" + + /*************************************************************************/ + + /* macro definitions for construction your own RADIUS packets */ + /* usially, requires two arguments - ptr (the place where we should insert + atribute and value. Note, that ptr must be a lvalue */ + + /* User Name */ + #define RADINS_USER_NAME(ptr, value) \ + *ptr++ = PW_USER_NAME; \ + *ptr++ = strlen(value) + 2; \ + strcpy (ptr, value); \ + ptr += strlen(value); + + /* Calling-Station-ID */ + #define RADINS_CALLING_STATION_ID(ptr, value) \ + *ptr++ = PW_CALLING_STATION_ID; \ + *ptr++ = strlen(value) + 2; \ + strcpy (ptr, value); \ + ptr += strlen(value); + + /* State / connection string */ + #define RADINS_STATE(ptr, value) \ + *ptr++ = PW_STATE; \ + *ptr++ = strlen(value) + 2; \ + strcpy (ptr, value); \ + ptr += strlen(value); + + /* NAS-IP-Address */ + #define RADINS_NAS_IP_ADDRESS(ptr, value) \ + *ptr++ = PW_NAS_IP_ADDRESS; \ + *ptr++ = 6; \ + memcpy(ptr, value, 4); \ + ptr += 4; + + /* NAS-Port */ + #define RADINS_NAS_PORT(ptr, value) \ + *ptr++ = PW_NAS_PORT; \ + *ptr++ = 6; \ + *(u_long *)ptr = htonl (value); \ + ptr += 4; + + /* Acct-Status-Type */ + #define RADINS_ACCT_STATUS_TYPE(ptr, value) \ + *ptr++ = PW_ACCT_STATUS_TYPE; \ + *ptr++ = 6; \ + *(u_long *)ptr = htonl(value); \ + ptr += 4; + + /* Acct-Session-Id */ + #define RADINS_ACCT_SESSION_ID(ptr, value) \ + *ptr++ = PW_ACCT_SESSION_ID; \ + *ptr++ = 2+strlen(value); \ + strcpy (ptr, value); \ + ptr += strlen (value); + + /* Acct-Session-Time */ + #define RADINS_ACCT_SESSION_TIME(ptr, value) \ + *ptr++ = PW_ACCT_SESSION_TIME; \ + *ptr++ = 6; \ + *(u_long *)ptr = htonl(value); \ + ptr += 4; + + /* Service-Type */ + #define RADINS_SERVICE_TYPE(ptr, value) \ + *ptr++ = PW_SERVICE_TYPE; \ + *ptr++ = 6; \ + *(u_long *) ptr = htonl(value); \ + ptr += 4; + + /* Framed-Protocol */ + #define RADINS_FRAMED_PROTOCOL(ptr, value) \ + *ptr++ = PW_FRAMED_PROTOCOL; \ + *ptr++ = 6; \ + *(u_long *)ptr = htonl(value); \ + ptr += 4; + + /* User Password */ + #define RADINS_USER_PASSWORD(ptr, value, auth) \ + *ptr++ = PW_USER_PASSWORD; \ + *ptr++ = 18; \ + radius_encrypt_password(ptr, value, auth); \ + ptr += 16; + + + + int radius_retry_max = RADLIB_DEFAULT_RETRY_MAX; + char radius_secret[16] = "\0"; + struct sockaddr_in radius_me = {0, PF_INET, 0, {0}, "\0\0\0\0\0\0\0\0"}; + struct sockaddr_in radius_server = {0, PF_INET, 0, {0}, "\0\0\0\0\0\0\0\0"}; + struct sockaddr_in radius_servac = {0, PF_INET, 0, {0}, "\0\0\0\0\0\0\0\0"}; + struct timeval radius_timeout = {RADLIB_DEFAULT_TIMEOUT, 0}; + int radius_id = 0; + time_t radius_session_start_time; + char radius_session_id[254]; + int radius_accounting = 0; + int radius_debug = 0; + + /* initialization of all variables needed for the RADIUS access routines. + local ip-addres for source, address and port of a RADIUS-server, + shared secret */ + + int radius_init (char *config_file) + { + FILE * fil; + char argnam[128]; + char argval[128]; + + if ( (fil = fopen (config_file, "r")) == NULL) + return (0); + radius_server.sin_port = htons(RADLIB_DEFAULT_RADIUS_PORT); + radius_servac.sin_port = htons(RADLIB_DEFAULT_RADACC_PORT); + while ( !feof (fil) ) + { + fscanf (fil, "%s %s\n", argnam, argval); + if ( !strcasecmp (argnam, "secret")) + strncpy (radius_secret, argval, 16); + else + if ( !strcasecmp (argnam, "retry_max")) + radius_retry_max = atoi (argval); + else + if ( !strcasecmp (argnam, "timeout")) + radius_timeout.tv_sec = atoi (argval); + else + if ( !strcasecmp (argnam, "my_address")) + radius_me.sin_addr.s_addr = inet_addr (argval); + else + if ( !strcasecmp (argnam, "rs_address")) + radius_server.sin_addr.s_addr = inet_addr (argval); + else + if ( !strcasecmp (argnam, "rs_port")) + radius_server.sin_port = htons (atoi(argval)); + if ( !strcasecmp (argnam, "ra_address")) + { + radius_accounting = 1; + radius_servac.sin_addr.s_addr = inet_addr (argval); + } + else + if ( !strcasecmp (argnam, "ra_port")) + radius_servac.sin_port = htons (atoi(argval)); + } + + radius_session_start_time = time (NULL); + + /* session identifier = ip_addr + pid + time */ + sprintf(radius_session_id, "%s %u %s", + inet_ntoa (radius_me.sin_addr), + getpid(), + ctime(&radius_session_start_time)); + return (1); + } + + /* sends the query to a RADIUS server, waits an answer and returns it */ + int radius_send_query (u_char *packet, u_char *reply, struct sockaddr_in *whom) + { + #define ERROR(x) {printf(x); return(0);} + + int sock; + fd_set fd_wait; + int retries = 0; + struct sockaddr from; + int fromlen; + + if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + ERROR("Can't socket\n"); + + if (bind (sock, (struct sockaddr *) &radius_me, sizeof(radius_me))) + ERROR("can't bind\n"); + + for (;;) + { + if (sendto ( sock, packet, ntohs(*((u_short *)(packet + 2))), 0, + (struct sockaddr *)whom, + sizeof(struct sockaddr_in)) < 0) + ERROR("can't sendto\n"); + + FD_ZERO (&fd_wait); + FD_SET (sock, &fd_wait); + if ( select (sock+1, &fd_wait, NULL, NULL, &radius_timeout) < 0) + ERROR("can't select\n"); + if (FD_ISSET (sock, &fd_wait)) + break; + if ( ++retries == radius_retry_max) + return (0); + } + + fromlen = sizeof (from); + if (recvfrom(sock, reply, RADLIB_MAX_PACKET_SIZE, 0, &from, &fromlen) < 0) + ERROR("bad packet recieved\n"); + + return(1); + #undef ERROR + } + + /* encrypt password */ + void radius_encrypt_password(char *ptr, char *passwd, char *auth) + { + int slen; + char buf[32]; + int i; + + slen = strlen (radius_secret); + strcpy (buf, radius_secret); + memcpy (buf + slen, auth, 16); + md5_calc (ptr, buf, slen + 16); + for (i = 0; i < strlen (passwd); i++) + ptr[i] ^= passwd[i]; + } + + /* create Authenicator */ + void radius_create_auth (char *ptr) + { + char md5buf[128]; + int slen = strlen (radius_secret); + TRadiusHeader *hdr; + + hdr = (TRadiusHeader *)ptr; + strcpy (ptr+ntohs(hdr->length), radius_secret); + md5_calc (md5buf, ptr, slen + ntohs (hdr->length)); + memcpy (hdr->auth, md5buf, 16); + } + + int radius_response_auth (char *resp, char *auth) + { + u_char tmp[RADLIB_MAX_PACKET_SIZE]; + u_char md5buf[128]; + int len; + + len = ntohs (*(u_short*)(resp+2)); + memcpy (tmp, resp, len); + memcpy (tmp + 4, auth, 16); + memcpy (tmp + len, radius_secret, strlen(radius_secret)); + + md5_calc (md5buf, tmp, len + strlen(radius_secret)); + return (!memcmp (md5buf, resp + 4, 16)); + } + + int radius_account_start (u_char *user_name, u_long port) + { + u_char reply[RADLIB_MAX_PACKET_SIZE]; + u_char request[RADLIB_MAX_PACKET_SIZE]; + TRadiusHeader *hdr; + TRadiusHeader *rep; + u_char *ptr; + int i; + + hdr = (TRadiusHeader *)request; + hdr->code = PW_ACCOUNTING_REQUEST; + hdr->id = radius_id++; + for (i = 0; i < 4; i++) + hdr->auth[i] = 0L; + ptr = request + 20; + RADINS_USER_NAME (ptr, user_name); + RADINS_NAS_IP_ADDRESS (ptr, &radius_me.sin_addr.s_addr); + RADINS_NAS_PORT (ptr, port); + RADINS_CALLING_STATION_ID (ptr, callerid); + RADINS_STATE (ptr, con_state); + RADINS_ACCT_STATUS_TYPE (ptr, PW_STATUS_START); + RADINS_ACCT_SESSION_ID (ptr, radius_session_id); + hdr->length = htons ((unsigned)ptr - (unsigned)request); + radius_create_auth (request); + + /* Ok, packet is now assembled. send it */ + if (!radius_send_query (request, reply, &radius_servac)) + return(RADLIB_NO_RESPONSE); + /* verify */ + rep = (TRadiusHeader *)reply; + if (rep->id != hdr->id) + return(RADLIB_BAD_ID); + if (!radius_response_auth (reply, (char *)hdr->auth)) + return(RADLIB_BAD_AUTH); + if (rep->code != PW_ACCOUNTING_RESPONSE) + return(RADLIB_ACCESS_DENIED); + return (0); /* all right */ + } + + int radius_account_stop (u_char *user_name, u_long port, time_t stime) + { + u_char reply[RADLIB_MAX_PACKET_SIZE]; + u_char request[RADLIB_MAX_PACKET_SIZE]; + TRadiusHeader *hdr; + TRadiusHeader *rep; + u_char *ptr; + int i; + + hdr = (TRadiusHeader *)request; + hdr->code = PW_ACCOUNTING_REQUEST; + hdr->id = radius_id++; + for (i = 0; i < 4; i++) + hdr->auth[i] = 0L; + ptr = request + 20; + RADINS_USER_NAME (ptr, user_name); + RADINS_NAS_IP_ADDRESS (ptr, &radius_me.sin_addr.s_addr); + RADINS_NAS_PORT (ptr, port); + RADINS_CALLING_STATION_ID (ptr, callerid); + RADINS_STATE (ptr, con_state); + RADINS_ACCT_STATUS_TYPE (ptr, PW_STATUS_STOP); + RADINS_ACCT_SESSION_ID (ptr, radius_session_id); + RADINS_ACCT_SESSION_TIME (ptr, stime); + hdr->length = htons ((int)ptr - (int)request); + radius_create_auth (request); + + if (!radius_send_query (request, reply, &radius_servac)) + return(RADLIB_NO_RESPONSE); + /* verify */ + rep = (TRadiusHeader *)reply; + if (rep->id != hdr->id) + return(RADLIB_BAD_ID); + if (!radius_response_auth (reply, (char *)hdr->auth)) + return(RADLIB_BAD_AUTH); + if (rep->code != PW_ACCOUNTING_RESPONSE) + return(RADLIB_ACCESS_DENIED); + return (0); /* all right */ + } + + /* returns client's ip-addres, netmask, MTU, Compression type */ + int radius_request_ppp_PAP (char *user_name, char *user_passwd, u_long port, + u_long **address, u_long **netmask, u_long **mtu, u_long **compress) + { + u_char reply[RADLIB_MAX_PACKET_SIZE]; + u_char request[RADLIB_MAX_PACKET_SIZE]; + TRadiusHeader *hdr; + TRadiusHeader *rep; + u_char *ptr; + int i; + + int is_address = 0; + int is_netmask = 0; + int is_mtu = 0; + int is_compress = 0; + + hdr = (TRadiusHeader *)request; + hdr->code = PW_ACCESS_REQUEST; + hdr->id = radius_id++; + srandom (time (NULL)); + for (i = 0; i < 4; i++) + hdr->auth[i] = random(); + ptr = request + 20; + RADINS_USER_NAME(ptr, user_name); + RADINS_USER_PASSWORD(ptr, user_passwd, hdr->auth); + RADINS_SERVICE_TYPE (ptr, PW_FRAMED); + RADINS_FRAMED_PROTOCOL (ptr, PW_PPP); + RADINS_NAS_IP_ADDRESS(ptr, &radius_me.sin_addr.s_addr); + RADINS_NAS_PORT (ptr, port); + RADINS_CALLING_STATION_ID (ptr, callerid); + RADINS_STATE (ptr, con_state); + hdr->length = htons ((int)ptr - (int)request); + if (!radius_send_query (request, reply, &radius_server)) + return(RADLIB_NO_RESPONSE); + /* verify */ + rep = (TRadiusHeader *)reply; + if (rep->id != hdr->id) + return(RADLIB_BAD_ID); + if (!radius_response_auth (reply, (char *)hdr->auth)) + return(RADLIB_BAD_AUTH); + if (rep->code == PW_ACCESS_REJECT) + return(RADLIB_ACCESS_DENIED); + if (rep->code != PW_ACCESS_ACCEPT) + return(RADLIB_BAD_CODE); + for ( ptr = reply + sizeof(TRadiusHeader); + ptr < reply + ntohs(rep->length); + ptr += *(ptr+1)) + { + switch (*ptr) + { + case PW_FRAMED_IP_ADDRESS: + is_address = 1; + memcpy (*address, ptr + 2, 4); + break; + case PW_FRAMED_IP_NETMASK: + is_netmask = 1; + memcpy (*netmask, ptr + 2, 4); + break; + case PW_FRAMED_MTU: + is_mtu = 1; + **mtu = ntohl(*(u_long*)(ptr + 2)); + break; + case PW_FRAMED_COMPRESSION: + is_compress = 1; + **compress = ntohl(*(u_long*)(ptr + 2)); + break; + } + + } + if (!is_address) *address = NULL; + if (!is_netmask) *netmask = NULL; + if (!is_mtu) *mtu = NULL; + if (!is_compress) *compress = NULL; + return (0); /* all right */ + } diff -r -P -d -C 3 ppp-2.3.5/pppd/libradius.h ppp-2.3.5-2cbcps-radius-multiport/pppd/libradius.h *** ppp-2.3.5/pppd/libradius.h Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/libradius.h Thu Aug 19 16:09:08 1999 *************** *** 0 **** --- 1,63 ---- + #ifndef LIBRADIUS_H + #define LIBRADIUS_H + + #include + #include + + /* sizes */ + #define RADLIB_MAX_PACKET_SIZE 1024 + #define RADLIB_DEFAULT_RETRY_MAX 3 + #define RADLIB_DEFAULT_TIMEOUT 1 + #define RADLIB_DEFAULT_RADIUS_PORT 1645 + #define RADLIB_DEFAULT_RADACC_PORT 1646 + + /* error codes */ + #define RADLIB_ACCESS_DENIED 1 + #define RADLIB_NO_RESPONSE 2 + #define RADLIB_BAD_ID 3 + #define RADLIB_BAD_AUTH 4 + #define RADLIB_BAD_CODE 5 + + + + + #define u_char unsigned char + #define u_long unsigned long + #define u_short unsigned short + + + typedef struct + { + u_char code; + u_char id; + u_short length; + u_long auth[4]; + } TRadiusHeader; + + int radius_init(char *); + int radius_send_query (u_char *, u_char *, struct sockaddr_in *); + int radius_response_auth (char *, char *); + int radius_request_ppp_PAP (char *, char *, u_long, u_long **, u_long **, u_long **, u_long **); + int radius_account_start (u_char *, u_long); + int radius_account_stop (u_char *, u_long, time_t); + void radius_encrypt_password (char *, char *, char *); + void radius_create_auth (char *); + + int md5_calc (u_char *, u_char *, int); + + extern char callerid[]; + extern char con_state[]; + + extern int radius_retry_max; + extern char radius_secret[]; + extern struct sockaddr_in radius_me; + extern struct sockaddr_in radius_server; + extern struct sockaddr_in radius_servac; + extern struct timeval radius_timeout; + extern int radius_id; + extern time_t radius_session_start_time; + extern char radius_session_id[]; + extern int radius_accounting; + extern int radius_debug; + + #endif diff -r -P -d -C 3 ppp-2.3.5/pppd/main.c ppp-2.3.5-2cbcps-radius-multiport/pppd/main.c *** ppp-2.3.5/pppd/main.c Tue May 5 11:24:17 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/main.c Sun Jan 16 14:03:38 2000 *************** *** 51,56 **** --- 51,57 ---- #include "ccp.h" #include "pathnames.h" #include "patchlevel.h" + #include "cbcps.h" #ifdef CBCP_SUPPORT #include "cbcp.h" *************** *** 145,150 **** --- 146,152 ---- &lcp_protent, &pap_protent, &chap_protent, + &cbcp_protent, #ifdef CBCP_SUPPORT &cbcp_protent, #endif *************** *** 409,414 **** --- 411,470 ---- * Now we want to bring up the link. */ demand_block(); + /* !!! begin multiport section */ + if(usemultiport){ + (void) strncpy(devnam, staticdevnam, MAXPATHLEN); + if ((p = (char *) malloc(MAXPATHLEN)) == NULL) { + syslog(LOG_ERR, "Out of memory in multiport section (find free device)!"); + die(1); + } + if(multiportend == -1){ + #ifdef _linux_ + sprintf(p, "/etc/mg-pid.ttyS%x", multiportfist); + #else + sprintf(p, "/etc/mg-pid.cuaa%x", multiportfist); + #endif + if( !(access(p, F_OK)) ){ + #ifdef _linux_ + sprintf(p, "/var/spool/locks/LCK..ttyS%x", multiportfist); + #else + sprintf(p, "/var/spool/locks/LCK..cuaa%x", multiportfist); + #endif + if( access(p, F_OK) == -1 ){ + #ifdef _linux_ + sprintf( devnam, "/dev/ttyS%x", multiportfist); + #else + sprintf( devnam, "/dev/cuaa%x", multiportfist); + #endif + } + } + }else{ + for(i=multiportfist; i<(multiportend+1); i++){ + #ifdef _linux_ + sprintf(p, "/etc/mg-pid.ttyS%x", i); + #else + sprintf(p, "/etc/mg-pid.cuaa%x", i); + #endif + if( !(access(p, F_OK)) ){ + #ifdef _linux_ + sprintf(p, "/var/spool/locks/LCK..ttyS%x", i); + #else + sprintf(p, "/var/spool/locks/LCK..cuaa%x", i); + #endif + if( access(p, F_OK) == -1 ){ + #ifdef _linux_ + sprintf( devnam, "/dev/ttyS%x", i); + #else + sprintf( devnam, "/dev/cuaa%x", i); + #endif + break; + } + } + } + } + syslog(LOG_NOTICE, "Multiport: Set device (%s).", devnam); + } + /* !!! end multiport section */ syslog(LOG_INFO, "Starting link"); } diff -r -P -d -C 3 ppp-2.3.5/pppd/main.c.orig ppp-2.3.5-2cbcps-radius-multiport/pppd/main.c.orig *** ppp-2.3.5/pppd/main.c.orig Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/main.c.orig Sun Jan 24 14:36:51 1999 *************** *** 0 **** --- 1,1680 ---- + /* + * main.c - Point-to-Point Protocol main module + * + * 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: main.c,v 1.49 1998/05/05 05:24:17 paulus Exp $"; + #endif + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "pppd.h" + #include "magic.h" + #include "fsm.h" + #include "lcp.h" + #include "ipcp.h" + #include "upap.h" + #include "chap.h" + #include "ccp.h" + #include "pathnames.h" + #include "patchlevel.h" + #include "cbcps.h" + + #ifdef CBCP_SUPPORT + #include "cbcp.h" + #endif + + #if defined(SUNOS4) + extern char *strerror(); + #endif + + #ifdef IPX_CHANGE + #include "ipxcp.h" + #endif /* IPX_CHANGE */ + #ifdef AT_CHANGE + #include "atcp.h" + #endif + + /* interface vars */ + char ifname[32]; /* Interface name */ + int ifunit; /* Interface unit number */ + + char *progname; /* Name of this program */ + char hostname[MAXNAMELEN]; /* Our hostname */ + static char pidfilename[MAXPATHLEN]; /* name of pid file */ + static char default_devnam[MAXPATHLEN]; /* name of default device */ + static pid_t pid; /* Our pid */ + static uid_t uid; /* Our real user-id */ + static int conn_running; /* we have a [dis]connector running */ + + int ttyfd = -1; /* Serial port file descriptor */ + mode_t tty_mode = -1; /* Original access permissions to tty */ + int baud_rate; /* Actual bits/second for serial device */ + int hungup; /* terminal has been hung up */ + int privileged; /* we're running as real uid root */ + int need_holdoff; /* need holdoff period before restarting */ + int detached; /* have detached from terminal */ + + int phase; /* where the link is at */ + int kill_link; + int open_ccp_flag; + + char **script_env; /* Env. variable values for scripts */ + int s_env_nalloc; /* # words avail at script_env */ + + u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ + u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ + + static int n_children; /* # child processes still running */ + + static int locked; /* lock() has succeeded */ + + char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; + + /* Prototypes for procedures local to this file. */ + + static void create_pidfile __P((void)); + static void cleanup __P((void)); + static void close_tty __P((void)); + static void get_input __P((void)); + static void calltimeout __P((void)); + static struct timeval *timeleft __P((struct timeval *)); + static void kill_my_pg __P((int)); + static void hup __P((int)); + static void term __P((int)); + static void chld __P((int)); + static void toggle_debug __P((int)); + static void open_ccp __P((int)); + static void bad_signal __P((int)); + static void holdoff_end __P((void *)); + static int device_script __P((char *, int, int)); + static void reap_kids __P((void)); + static void pr_log __P((void *, char *, ...)); + + extern char *ttyname __P((int)); + extern char *getlogin __P((void)); + int main __P((int, char *[])); + + #ifdef ultrix + #undef O_NONBLOCK + #define O_NONBLOCK O_NDELAY + #endif + + #ifdef ULTRIX + #define setlogmask(x) + #endif + + /* + * PPP Data Link Layer "protocol" table. + * One entry per supported protocol. + * The last entry must be NULL. + */ + struct protent *protocols[] = { + &lcp_protent, + &pap_protent, + &chap_protent, + &cbcp_protent, + #ifdef CBCP_SUPPORT + &cbcp_protent, + #endif + &ipcp_protent, + &ccp_protent, + #ifdef IPX_CHANGE + &ipxcp_protent, + #endif + #ifdef AT_CHANGE + &atcp_protent, + #endif + NULL + }; + + int + main(argc, argv) + int argc; + char *argv[]; + { + int i, fdflags; + struct sigaction sa; + char *p; + struct passwd *pw; + struct timeval timo; + sigset_t mask; + struct protent *protp; + struct stat statbuf; + char numbuf[16]; + + phase = PHASE_INITIALIZE; + p = ttyname(0); + if (p) + strcpy(devnam, p); + strcpy(default_devnam, devnam); + + script_env = NULL; + + /* Initialize syslog facilities */ + #ifdef ULTRIX + openlog("pppd", LOG_PID); + #else + openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); + setlogmask(LOG_UPTO(LOG_INFO)); + #endif + + if (gethostname(hostname, MAXNAMELEN) < 0 ) { + option_error("Couldn't get hostname: %m"); + die(1); + } + hostname[MAXNAMELEN-1] = 0; + + uid = getuid(); + privileged = uid == 0; + sprintf(numbuf, "%d", uid); + script_setenv("UID", numbuf); + + /* + * Initialize to the standard option set, then parse, in order, + * the system options file, the user's options file, + * the tty's options file, and the command line arguments. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + (*protp->init)(0); + + progname = *argv; + + if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) + || !options_from_user()) + exit(1); + scan_args(argc-1, argv+1); /* look for tty name on command line */ + if (!options_for_tty() + || !parse_args(argc-1, argv+1)) + exit(1); + + /* + * Check that we are running as root. + */ + if (geteuid() != 0) { + option_error("must be root to run %s, since it is not setuid-root", + argv[0]); + die(1); + } + + if (!ppp_available()) { + option_error(no_ppp_msg); + exit(1); + } + + /* + * Check that the options given are valid and consistent. + */ + sys_check_options(); + auth_check_options(); + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->check_options != NULL) + (*protp->check_options)(); + if (demand && connector == 0) { + option_error("connect script required for demand-dialling\n"); + exit(1); + } + + script_setenv("DEVICE", devnam); + sprintf(numbuf, "%d", baud_rate); + script_setenv("SPEED", numbuf); + + /* + * If the user has specified the default device name explicitly, + * pretend they hadn't. + */ + if (!default_device && strcmp(devnam, default_devnam) == 0) + default_device = 1; + if (default_device) + nodetach = 1; + + /* + * Initialize system-dependent stuff and magic number package. + */ + sys_init(); + magic_init(); + if (debug) + setlogmask(LOG_UPTO(LOG_DEBUG)); + + /* + * Detach ourselves from the terminal, if required, + * and identify who is running us. + */ + if (nodetach == 0) + detach(); + pid = getpid(); + p = getlogin(); + if (p == NULL) { + pw = getpwuid(uid); + if (pw != NULL && pw->pw_name != NULL) + p = pw->pw_name; + else + p = "(unknown)"; + } + syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %d", + VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid); + + /* + * Compute mask of all interesting signals and install signal handlers + * for each. Only one signal handler may be active at a time. Therefore, + * all other signals should be masked when any handler is executing. + */ + sigemptyset(&mask); + sigaddset(&mask, SIGHUP); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + sigaddset(&mask, SIGCHLD); + + #define SIGNAL(s, handler) { \ + sa.sa_handler = handler; \ + if (sigaction(s, &sa, NULL) < 0) { \ + syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ + die(1); \ + } \ + } + + sa.sa_mask = mask; + sa.sa_flags = 0; + SIGNAL(SIGHUP, hup); /* Hangup */ + SIGNAL(SIGINT, term); /* Interrupt */ + SIGNAL(SIGTERM, term); /* Terminate */ + SIGNAL(SIGCHLD, chld); + + SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ + SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ + + /* + * Install a handler for other signals which would otherwise + * cause pppd to exit without cleaning up. + */ + SIGNAL(SIGABRT, bad_signal); + SIGNAL(SIGALRM, bad_signal); + SIGNAL(SIGFPE, bad_signal); + SIGNAL(SIGILL, bad_signal); + SIGNAL(SIGPIPE, bad_signal); + SIGNAL(SIGQUIT, bad_signal); + SIGNAL(SIGSEGV, bad_signal); + #ifdef SIGBUS + SIGNAL(SIGBUS, bad_signal); + #endif + #ifdef SIGEMT + SIGNAL(SIGEMT, bad_signal); + #endif + #ifdef SIGPOLL + SIGNAL(SIGPOLL, bad_signal); + #endif + #ifdef SIGPROF + SIGNAL(SIGPROF, bad_signal); + #endif + #ifdef SIGSYS + SIGNAL(SIGSYS, bad_signal); + #endif + #ifdef SIGTRAP + SIGNAL(SIGTRAP, bad_signal); + #endif + #ifdef SIGVTALRM + SIGNAL(SIGVTALRM, bad_signal); + #endif + #ifdef SIGXCPU + SIGNAL(SIGXCPU, bad_signal); + #endif + #ifdef SIGXFSZ + SIGNAL(SIGXFSZ, bad_signal); + #endif + + /* + * Apparently we can get a SIGPIPE when we call syslog, if + * syslogd has died and been restarted. Ignoring it seems + * be sufficient. + */ + signal(SIGPIPE, SIG_IGN); + + /* + * If we're doing dial-on-demand, set up the interface now. + */ + if (demand) { + /* + * Open the loopback channel and set it up to be the ppp interface. + */ + open_ppp_loopback(); + + syslog(LOG_INFO, "Using interface ppp%d", ifunit); + (void) sprintf(ifname, "ppp%d", ifunit); + script_setenv("IFNAME", ifname); + + create_pidfile(); /* write pid to file */ + + /* + * Configure the interface and mark it up, etc. + */ + demand_conf(); + } + + for (;;) { + + need_holdoff = 1; + + if (demand) { + /* + * Don't do anything until we see some activity. + */ + phase = PHASE_DORMANT; + kill_link = 0; + demand_unblock(); + for (;;) { + wait_loop_output(timeleft(&timo)); + calltimeout(); + if (kill_link) { + if (!persist) + die(0); + kill_link = 0; + } + if (get_loop_output()) + break; + reap_kids(); + } + + /* + * Now we want to bring up the link. + */ + demand_block(); + syslog(LOG_INFO, "Starting link"); + } + + /* + * Lock the device if we've been asked to. + */ + if (lockflag && !default_device) { + if (lock(devnam) < 0) + goto fail; + locked = 1; + } + + /* + * Open the serial device and set it up to be the ppp interface. + * First we open it in non-blocking mode so we can set the + * various termios flags appropriately. If we aren't dialling + * out and we want to use the modem lines, we reopen it later + * in order to wait for the carrier detect signal from the modem. + */ + while ((ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0)) < 0) { + if (errno != EINTR) + syslog(LOG_ERR, "Failed to open %s: %m", devnam); + if (!persist || errno != EINTR) + goto fail; + } + if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 + || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) + syslog(LOG_WARNING, + "Couldn't reset non-blocking mode on device: %m"); + + hungup = 0; + kill_link = 0; + + /* + * Do the equivalent of `mesg n' to stop broadcast messages. + */ + if (fstat(ttyfd, &statbuf) < 0 + || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { + syslog(LOG_WARNING, + "Couldn't restrict write permissions to %s: %m", devnam); + } else + tty_mode = statbuf.st_mode; + + /* run connection script */ + if (connector && connector[0]) { + MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); + + /* + * Set line speed, flow control, etc. + * On most systems we set CLOCAL for now so that we can talk + * to the modem before carrier comes up. But this has the + * side effect that we might miss it if CD drops before we + * get to clear CLOCAL below. On systems where we can talk + * successfully to the modem with CLOCAL clear and CD down, + * we can clear CLOCAL at this point. + */ + set_up_tty(ttyfd, 1); + + /* drop dtr to hang up in case modem is off hook */ + if (!default_device && modem) { + setdtr(ttyfd, FALSE); + sleep(1); + setdtr(ttyfd, TRUE); + } + + if (device_script(connector, ttyfd, ttyfd) < 0) { + syslog(LOG_ERR, "Connect script failed"); + setdtr(ttyfd, FALSE); + goto fail; + } + + + syslog(LOG_INFO, "Serial connection established."); + sleep(1); /* give it time to set up its terminal */ + } + + /* set line speed, flow control, etc.; clear CLOCAL if modem option */ + set_up_tty(ttyfd, 0); + + /* reopen tty if necessary to wait for carrier */ + if (connector == NULL && modem) { + while ((i = open(devnam, O_RDWR)) < 0) { + if (errno != EINTR) + syslog(LOG_ERR, "Failed to reopen %s: %m", devnam); + if (!persist || errno != EINTR || hungup || kill_link) + goto fail; + } + close(i); + } + + /* run welcome script, if any */ + if (welcomer && welcomer[0]) { + if (device_script(welcomer, ttyfd, ttyfd) < 0) + syslog(LOG_WARNING, "Welcome script failed"); + } + + /* set up the serial device as a ppp interface */ + establish_ppp(ttyfd); + + if (!demand) { + + syslog(LOG_INFO, "Using interface ppp%d", ifunit); + (void) sprintf(ifname, "ppp%d", ifunit); + script_setenv("IFNAME", ifname); + + create_pidfile(); /* write pid to file */ + } + + /* + * Start opening the connection and wait for + * incoming events (reply, timeout, etc.). + */ + syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); + lcp_lowerup(0); + lcp_open(0); /* Start protocol */ + for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { + wait_input(timeleft(&timo)); + calltimeout(); + get_input(); + if (kill_link) { + lcp_close(0, "User request"); + kill_link = 0; + } + if (open_ccp_flag) { + if (phase == PHASE_NETWORK) { + ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ + (*ccp_protent.open)(0); + } + open_ccp_flag = 0; + } + reap_kids(); /* Don't leave dead kids lying around */ + } + + /* + * If we may want to bring the link up again, transfer + * the ppp unit back to the loopback. Set the + * real serial device back to its normal mode of operation. + */ + clean_check(); + if (demand) + restore_loop(); + disestablish_ppp(ttyfd); + + /* + * Run disconnector script, if requested. + * XXX we may not be able to do this if the line has hung up! + */ + if (disconnector && !hungup) { + set_up_tty(ttyfd, 1); + if (device_script(disconnector, ttyfd, ttyfd) < 0) { + syslog(LOG_WARNING, "disconnect script failed"); + } else { + syslog(LOG_INFO, "Serial link disconnected."); + } + } + + fail: + if (ttyfd >= 0) + close_tty(); + if (locked) { + unlock(); + locked = 0; + } + + if (!demand) { + if (pidfilename[0] != 0 + && unlink(pidfilename) < 0 && errno != ENOENT) + syslog(LOG_WARNING, "unable to delete pid file: %m"); + pidfilename[0] = 0; + } + + if (!persist) + die(1); + + if (demand) + demand_discard(); + if (holdoff > 0 && need_holdoff) { + phase = PHASE_HOLDOFF; + TIMEOUT(holdoff_end, NULL, holdoff); + do { + wait_time(timeleft(&timo)); + calltimeout(); + if (kill_link) { + if (!persist) + die(0); + kill_link = 0; + phase = PHASE_DORMANT; /* allow signal to end holdoff */ + } + reap_kids(); + } while (phase == PHASE_HOLDOFF); + } + } + + die(0); + return 0; + } + + /* + * detach - detach us from the controlling terminal. + */ + void + detach() + { + if (detached) + return; + if (daemon(0, 0) < 0) { + perror("Couldn't detach from controlling terminal"); + die(1); + } + detached = 1; + pid = getpid(); + /* update pid file if it has been written already */ + if (pidfilename[0]) + create_pidfile(); + } + + /* + * Create a file containing our process ID. + */ + static void + create_pidfile() + { + FILE *pidfile; + + (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname); + if ((pidfile = fopen(pidfilename, "w")) != NULL) { + fprintf(pidfile, "%d\n", pid); + (void) fclose(pidfile); + } else { + syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename); + pidfilename[0] = 0; + } + } + + /* + * holdoff_end - called via a timeout when the holdoff period ends. + */ + static void + holdoff_end(arg) + void *arg; + { + phase = PHASE_DORMANT; + } + + /* + * get_input - called when incoming data is available. + */ + static void + get_input() + { + int len, i; + u_char *p; + u_short protocol; + struct protent *protp; + + p = inpacket_buf; /* point to beginning of packet buffer */ + + len = read_packet(inpacket_buf); + if (len < 0) + return; + + if (len == 0) { + syslog(LOG_NOTICE, "Modem hangup"); + hungup = 1; + lcp_lowerdown(0); /* serial link is no longer available */ + link_terminated(0); + return; + } + + if (debug /*&& (debugflags & DBG_INPACKET)*/) + log_packet(p, len, "rcvd ", LOG_DEBUG); + + if (len < PPP_HDRLEN) { + MAINDEBUG((LOG_INFO, "io(): Received short packet.")); + return; + } + + p += 2; /* Skip address and control */ + GETSHORT(protocol, p); + len -= PPP_HDRLEN; + + /* + * Toss all non-LCP packets unless LCP is OPEN. + */ + if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { + MAINDEBUG((LOG_INFO, + "get_input: Received non-LCP packet when LCP not open.")); + return; + } + + /* + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if (phase <= PHASE_AUTHENTICATE + && !(protocol == PPP_LCP || protocol == PPP_LQR + || protocol == PPP_PAP || protocol == PPP_CHAP)) { + MAINDEBUG((LOG_INFO, "get_input: discarding proto 0x%x in phase %d", + protocol, phase)); + return; + } + + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + (*protp->input)(0, p, len); + return; + } + if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag + && protp->datainput != NULL) { + (*protp->datainput)(0, p, len); + return; + } + } + + if (debug) + syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol); + lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); + } + + + /* + * quit - Clean up state and exit (with an error indication). + */ + void + quit() + { + die(1); + } + + /* + * die - like quit, except we can specify an exit status. + */ + void + die(status) + int status; + { + cleanup(); + syslog(LOG_INFO, "Exit."); + exit(status); + } + + /* + * cleanup - restore anything which needs to be restored before we exit + */ + /* ARGSUSED */ + static void + cleanup() + { + sys_cleanup(); + + if (ttyfd >= 0) + close_tty(); + + if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) + syslog(LOG_WARNING, "unable to delete pid file: %m"); + pidfilename[0] = 0; + + if (locked) + unlock(); + } + + /* + * close_tty - restore the terminal device and close it. + */ + static void + close_tty() + { + disestablish_ppp(ttyfd); + + /* drop dtr to hang up */ + if (modem) { + setdtr(ttyfd, FALSE); + /* + * This sleep is in case the serial port has CLOCAL set by default, + * and consequently will reassert DTR when we close the device. + */ + sleep(1); + } + + restore_tty(ttyfd); + + if (tty_mode != (mode_t) -1) + chmod(devnam, tty_mode); + + close(ttyfd); + ttyfd = -1; + } + + + struct callout { + struct timeval c_time; /* time at which to call routine */ + void *c_arg; /* argument to routine */ + void (*c_func) __P((void *)); /* routine */ + struct callout *c_next; + }; + + static struct callout *callout = NULL; /* Callout list */ + static struct timeval timenow; /* Current time */ + + /* + * timeout - Schedule a timeout. + * + * Note that this timeout takes the number of seconds, NOT hz (as in + * the kernel). + */ + void + timeout(func, arg, time) + void (*func) __P((void *)); + void *arg; + int time; + { + struct callout *newp, *p, **pp; + + MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.", + (long) func, (long) arg, time)); + + /* + * Allocate timeout. + */ + if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) { + syslog(LOG_ERR, "Out of memory in timeout()!"); + die(1); + } + newp->c_arg = arg; + newp->c_func = func; + gettimeofday(&timenow, NULL); + newp->c_time.tv_sec = timenow.tv_sec + time; + newp->c_time.tv_usec = timenow.tv_usec; + + /* + * Find correct place and link it in. + */ + for (pp = &callout; (p = *pp); pp = &p->c_next) + if (newp->c_time.tv_sec < p->c_time.tv_sec + || (newp->c_time.tv_sec == p->c_time.tv_sec + && newp->c_time.tv_usec < p->c_time.tv_sec)) + break; + newp->c_next = p; + *pp = newp; + } + + + /* + * untimeout - Unschedule a timeout. + */ + void + untimeout(func, arg) + void (*func) __P((void *)); + void *arg; + { + struct callout **copp, *freep; + + MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg)); + + /* + * Find first matching timeout and remove it from the list. + */ + for (copp = &callout; (freep = *copp); copp = &freep->c_next) + if (freep->c_func == func && freep->c_arg == arg) { + *copp = freep->c_next; + (void) free((char *) freep); + break; + } + } + + + /* + * calltimeout - Call any timeout routines which are now due. + */ + static void + calltimeout() + { + struct callout *p; + + while (callout != NULL) { + p = callout; + + if (gettimeofday(&timenow, NULL) < 0) { + syslog(LOG_ERR, "Failed to get time of day: %m"); + die(1); + } + if (!(p->c_time.tv_sec < timenow.tv_sec + || (p->c_time.tv_sec == timenow.tv_sec + && p->c_time.tv_usec <= timenow.tv_usec))) + break; /* no, it's not time yet */ + + callout = p->c_next; + (*p->c_func)(p->c_arg); + + free((char *) p); + } + } + + + /* + * timeleft - return the length of time until the next timeout is due. + */ + static struct timeval * + timeleft(tvp) + struct timeval *tvp; + { + if (callout == NULL) + return NULL; + + gettimeofday(&timenow, NULL); + tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; + tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; + if (tvp->tv_usec < 0) { + tvp->tv_usec += 1000000; + tvp->tv_sec -= 1; + } + if (tvp->tv_sec < 0) + tvp->tv_sec = tvp->tv_usec = 0; + + return tvp; + } + + + /* + * kill_my_pg - send a signal to our process group, and ignore it ourselves. + */ + static void + kill_my_pg(sig) + int sig; + { + struct sigaction act, oldact; + + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + kill(0, sig); + sigaction(sig, &act, &oldact); + sigaction(sig, &oldact, NULL); + } + + + /* + * hup - Catch SIGHUP signal. + * + * Indicates that the physical layer has been disconnected. + * We don't rely on this indication; if the user has sent this + * signal, we just take the link down. + */ + static void + hup(sig) + int sig; + { + syslog(LOG_INFO, "Hangup (SIGHUP)"); + kill_link = 1; + if (conn_running) + /* Send the signal to the [dis]connector process(es) also */ + kill_my_pg(sig); + } + + + /* + * term - Catch SIGTERM signal and SIGINT signal (^C/del). + * + * Indicates that we should initiate a graceful disconnect and exit. + */ + /*ARGSUSED*/ + static void + term(sig) + int sig; + { + syslog(LOG_INFO, "Terminating on signal %d.", sig); + persist = 0; /* don't try to restart */ + kill_link = 1; + if (conn_running) + /* Send the signal to the [dis]connector process(es) also */ + kill_my_pg(sig); + } + + + /* + * chld - Catch SIGCHLD signal. + * Calls reap_kids to get status for any dead kids. + */ + static void + chld(sig) + int sig; + { + reap_kids(); + } + + + /* + * toggle_debug - Catch SIGUSR1 signal. + * + * Toggle debug flag. + */ + /*ARGSUSED*/ + static void + toggle_debug(sig) + int sig; + { + debug = !debug; + if (debug) { + setlogmask(LOG_UPTO(LOG_DEBUG)); + } else { + setlogmask(LOG_UPTO(LOG_WARNING)); + } + } + + + /* + * open_ccp - Catch SIGUSR2 signal. + * + * Try to (re)negotiate compression. + */ + /*ARGSUSED*/ + static void + open_ccp(sig) + int sig; + { + open_ccp_flag = 1; + } + + + /* + * bad_signal - We've caught a fatal signal. Clean up state and exit. + */ + static void + bad_signal(sig) + int sig; + { + static int crashed = 0; + + if (crashed) + _exit(127); + crashed = 1; + syslog(LOG_ERR, "Fatal signal %d", sig); + if (conn_running) + kill_my_pg(SIGTERM); + die(1); + } + + + /* + * device_script - run a program to connect or disconnect the + * serial device. + */ + static int + device_script(program, in, out) + char *program; + int in, out; + { + int pid; + int status; + int errfd; + + conn_running = 1; + pid = fork(); + + if (pid < 0) { + conn_running = 0; + syslog(LOG_ERR, "Failed to create child process: %m"); + die(1); + } + + if (pid == 0) { + sys_close(); + closelog(); + if (in == out) { + if (in != 0) { + dup2(in, 0); + close(in); + } + dup2(0, 1); + } else { + if (out == 0) + out = dup(out); + if (in != 0) { + dup2(in, 0); + close(in); + } + if (out != 1) { + dup2(out, 1); + close(out); + } + } + if (nodetach == 0) { + close(2); + errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); + if (errfd >= 0 && errfd != 2) { + dup2(errfd, 2); + close(errfd); + } + } + setuid(getuid()); + setgid(getgid()); + execl("/bin/sh", "sh", "-c", program, (char *)0); + syslog(LOG_ERR, "could not exec /bin/sh: %m"); + _exit(99); + /* NOTREACHED */ + } + + while (waitpid(pid, &status, 0) < 0) { + if (errno == EINTR) + continue; + syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); + die(1); + } + conn_running = 0; + + return (status == 0 ? 0 : -1); + } + + + /* + * run-program - execute a program with given arguments, + * but don't wait for it. + * If the program can't be executed, logs an error unless + * must_exist is 0 and the program file doesn't exist. + */ + int + run_program(prog, args, must_exist) + char *prog; + char **args; + int must_exist; + { + int pid; + + pid = fork(); + if (pid == -1) { + syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); + return -1; + } + if (pid == 0) { + int new_fd; + + /* Leave the current location */ + (void) setsid(); /* No controlling tty. */ + (void) umask (S_IRWXG|S_IRWXO); + (void) chdir ("/"); /* no current directory. */ + setuid(geteuid()); + setgid(getegid()); + + /* Ensure that nothing of our device environment is inherited. */ + sys_close(); + closelog(); + close (0); + close (1); + close (2); + close (ttyfd); /* tty interface to the ppp device */ + + /* Don't pass handles to the PPP device, even by accident. */ + new_fd = open (_PATH_DEVNULL, O_RDWR); + if (new_fd >= 0) { + if (new_fd != 0) { + dup2 (new_fd, 0); /* stdin <- /dev/null */ + close (new_fd); + } + dup2 (0, 1); /* stdout -> /dev/null */ + dup2 (0, 2); /* stderr -> /dev/null */ + } + + #ifdef BSD + /* Force the priority back to zero if pppd is running higher. */ + if (setpriority (PRIO_PROCESS, 0, 0) < 0) + syslog (LOG_WARNING, "can't reset priority to 0: %m"); + #endif + + /* SysV recommends a second fork at this point. */ + + /* run the program; give it a null environment */ + execve(prog, args, script_env); + if (must_exist || errno != ENOENT) + syslog(LOG_WARNING, "Can't execute %s: %m", prog); + _exit(-1); + } + MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %d", prog, pid)); + ++n_children; + return 0; + } + + + /* + * reap_kids - get status from any dead child processes, + * and log a message for abnormal terminations. + */ + static void + reap_kids() + { + int pid, status; + + if (n_children == 0) + return; + if ((pid = waitpid(-1, &status, WNOHANG)) == -1) { + if (errno != ECHILD) + syslog(LOG_ERR, "Error waiting for child process: %m"); + return; + } + if (pid > 0) { + --n_children; + if (WIFSIGNALED(status)) { + syslog(LOG_WARNING, "Child process %d terminated with signal %d", + pid, WTERMSIG(status)); + } + } + } + + + /* + * log_packet - format a packet and log it. + */ + + char line[256]; /* line to be logged accumulated here */ + char *linep; + + void + log_packet(p, len, prefix, level) + u_char *p; + int len; + char *prefix; + int level; + { + strcpy(line, prefix); + linep = line + strlen(line); + format_packet(p, len, pr_log, NULL); + if (linep != line) + syslog(level, "%s", line); + } + + /* + * format_packet - make a readable representation of a packet, + * calling `printer(arg, format, ...)' to output it. + */ + void + format_packet(p, len, printer, arg) + u_char *p; + int len; + void (*printer) __P((void *, char *, ...)); + void *arg; + { + int i, n; + u_short proto; + u_char x; + struct protent *protp; + + if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { + p += 2; + GETSHORT(proto, p); + len -= PPP_HDRLEN; + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (proto == protp->protocol) + break; + if (protp != NULL) { + printer(arg, "[%s", protp->name); + n = (*protp->printpkt)(p, len, printer, arg); + printer(arg, "]"); + p += n; + len -= n; + } else { + printer(arg, "[proto=0x%x]", proto); + } + } + + for (; len > 0; --len) { + GETCHAR(x, p); + printer(arg, " %.2x", x); + } + } + + static void + pr_log __V((void *arg, char *fmt, ...)) + { + int n; + va_list pvar; + char buf[256]; + + #if __STDC__ + va_start(pvar, fmt); + #else + void *arg; + char *fmt; + va_start(pvar); + arg = va_arg(pvar, void *); + fmt = va_arg(pvar, char *); + #endif + + n = vfmtmsg(buf, sizeof(buf), fmt, pvar); + va_end(pvar); + + if (linep + n + 1 > line + sizeof(line)) { + syslog(LOG_DEBUG, "%s", line); + linep = line; + } + strcpy(linep, buf); + linep += n; + } + + /* + * print_string - print a readable representation of a string using + * printer. + */ + void + print_string(p, len, printer, arg) + char *p; + int len; + void (*printer) __P((void *, char *, ...)); + void *arg; + { + int c; + + printer(arg, "\""); + for (; len > 0; --len) { + c = *p++; + if (' ' <= c && c <= '~') { + if (c == '\\' || c == '"') + printer(arg, "\\"); + printer(arg, "%c", c); + } else { + switch (c) { + case '\n': + printer(arg, "\\n"); + break; + case '\r': + printer(arg, "\\r"); + break; + case '\t': + printer(arg, "\\t"); + break; + default: + printer(arg, "\\%.3o", c); + } + } + } + printer(arg, "\""); + } + + /* + * novm - log an error message saying we ran out of memory, and die. + */ + void + novm(msg) + char *msg; + { + syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg); + die(1); + } + + /* + * fmtmsg - format a message into a buffer. Like sprintf except we + * also specify the length of the output buffer, and we handle + * %r (recursive format), %m (error message) and %I (IP address) formats. + * Doesn't do floating-point formats. + * Returns the number of chars put into buf. + */ + int + fmtmsg __V((char *buf, int buflen, char *fmt, ...)) + { + va_list args; + int n; + + #if __STDC__ + va_start(args, fmt); + #else + char *buf; + int buflen; + char *fmt; + va_start(args); + buf = va_arg(args, char *); + buflen = va_arg(args, int); + fmt = va_arg(args, char *); + #endif + n = vfmtmsg(buf, buflen, fmt, args); + va_end(args); + return n; + } + + /* + * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args. + */ + #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) + + int + vfmtmsg(buf, buflen, fmt, args) + char *buf; + int buflen; + char *fmt; + va_list args; + { + int c, i, n; + int width, prec, fillch; + int base, len, neg, quoted; + unsigned long val = 0; + char *str, *f, *buf0; + unsigned char *p; + char num[32]; + time_t t; + static char hexchars[] = "0123456789abcdef"; + + buf0 = buf; + --buflen; + while (buflen > 0) { + for (f = fmt; *f != '%' && *f != 0; ++f) + ; + if (f > fmt) { + len = f - fmt; + if (len > buflen) + len = buflen; + memcpy(buf, fmt, len); + buf += len; + buflen -= len; + fmt = f; + } + if (*fmt == 0) + break; + c = *++fmt; + width = prec = 0; + fillch = ' '; + if (c == '0') { + fillch = '0'; + c = *++fmt; + } + if (c == '*') { + width = va_arg(args, int); + c = *++fmt; + } else { + while (isdigit(c)) { + width = width * 10 + c - '0'; + c = *++fmt; + } + } + if (c == '.') { + c = *++fmt; + if (c == '*') { + prec = va_arg(args, int); + c = *++fmt; + } else { + while (isdigit(c)) { + prec = prec * 10 + c - '0'; + c = *++fmt; + } + } + } + str = 0; + base = 0; + neg = 0; + ++fmt; + switch (c) { + case 'd': + i = va_arg(args, int); + if (i < 0) { + neg = 1; + val = -i; + } else + val = i; + base = 10; + break; + case 'o': + val = va_arg(args, unsigned int); + base = 8; + break; + case 'x': + val = va_arg(args, unsigned int); + base = 16; + break; + case 'p': + val = (unsigned long) va_arg(args, void *); + base = 16; + neg = 2; + break; + case 's': + str = va_arg(args, char *); + break; + case 'c': + num[0] = va_arg(args, int); + num[1] = 0; + str = num; + break; + case 'm': + str = strerror(errno); + break; + case 'I': + str = ip_ntoa(va_arg(args, u_int32_t)); + break; + case 'r': + f = va_arg(args, char *); + #ifndef __powerpc__ + n = vfmtmsg(buf, buflen + 1, f, va_arg(args, va_list)); + #else + /* On the powerpc, a va_list is an array of 1 structure */ + n = vfmtmsg(buf, buflen + 1, f, va_arg(args, void *)); + #endif + buf += n; + buflen -= n; + continue; + case 't': + time(&t); + str = ctime(&t); + str += 4; /* chop off the day name */ + str[15] = 0; /* chop off year and newline */ + break; + case 'v': /* "visible" string */ + case 'q': /* quoted string */ + quoted = c == 'q'; + p = va_arg(args, unsigned char *); + if (fillch == '0' && prec > 0) { + n = prec; + } else { + n = strlen((char *)p); + if (prec > 0 && prec < n) + n = prec; + } + while (n > 0 && buflen > 0) { + c = *p++; + --n; + if (!quoted && c >= 0x80) { + OUTCHAR('M'); + OUTCHAR('-'); + c -= 0x80; + } + if (quoted && (c == '"' || c == '\\')) + OUTCHAR('\\'); + if (c < 0x20 || (0x7f <= c && c < 0xa0)) { + if (quoted) { + OUTCHAR('\\'); + switch (c) { + case '\t': OUTCHAR('t'); break; + case '\n': OUTCHAR('n'); break; + case '\b': OUTCHAR('b'); break; + case '\f': OUTCHAR('f'); break; + default: + OUTCHAR('x'); + OUTCHAR(hexchars[c >> 4]); + OUTCHAR(hexchars[c & 0xf]); + } + } else { + if (c == '\t') + OUTCHAR(c); + else { + OUTCHAR('^'); + OUTCHAR(c ^ 0x40); + } + } + } else + OUTCHAR(c); + } + continue; + default: + *buf++ = '%'; + if (c != '%') + --fmt; /* so %z outputs %z etc. */ + --buflen; + continue; + } + if (base != 0) { + str = num + sizeof(num); + *--str = 0; + while (str > num + neg) { + *--str = hexchars[val % base]; + val = val / base; + if (--prec <= 0 && val == 0) + break; + } + switch (neg) { + case 1: + *--str = '-'; + break; + case 2: + *--str = 'x'; + *--str = '0'; + break; + } + len = num + sizeof(num) - 1 - str; + } else { + len = strlen(str); + if (prec > 0 && len > prec) + len = prec; + } + if (width > 0) { + if (width > buflen) + width = buflen; + if ((n = width - len) > 0) { + buflen -= n; + for (; n > 0; --n) + *buf++ = fillch; + } + } + if (len > buflen) + len = buflen; + memcpy(buf, str, len); + buf += len; + buflen -= len; + } + *buf = 0; + return buf - buf0; + } + + /* + * script_setenv - set an environment variable value to be used + * for scripts that we run (e.g. ip-up, auth-up, etc.) + */ + void + script_setenv(var, value) + char *var, *value; + { + int vl = strlen(var); + int i; + char *p, *newstring; + + newstring = (char *) malloc(vl + strlen(value) + 2); + if (newstring == 0) + return; + strcpy(newstring, var); + newstring[vl] = '='; + strcpy(newstring+vl+1, value); + + /* check if this variable is already set */ + if (script_env != 0) { + for (i = 0; (p = script_env[i]) != 0; ++i) { + if (strncmp(p, var, vl) == 0 && p[vl] == '=') { + free(p); + script_env[i] = newstring; + return; + } + } + } else { + i = 0; + script_env = (char **) malloc(16 * sizeof(char *)); + if (script_env == 0) + return; + s_env_nalloc = 16; + } + + /* reallocate script_env with more space if needed */ + if (i + 1 >= s_env_nalloc) { + int new_n = i + 17; + char **newenv = (char **) realloc((void *)script_env, + new_n * sizeof(char *)); + if (newenv == 0) + return; + script_env = newenv; + s_env_nalloc = new_n; + } + + script_env[i] = newstring; + script_env[i+1] = 0; + } + + /* + * script_unsetenv - remove a variable from the environment + * for scripts. + */ + void + script_unsetenv(var) + char *var; + { + int vl = strlen(var); + int i; + char *p; + + if (script_env == 0) + return; + for (i = 0; (p = script_env[i]) != 0; ++i) { + if (strncmp(p, var, vl) == 0 && p[vl] == '=') { + free(p); + while ((script_env[i] = script_env[i+1]) != 0) + ++i; + break; + } + } + } diff -r -P -d -C 3 ppp-2.3.5/pppd/md5.c ppp-2.3.5-2cbcps-radius-multiport/pppd/md5.c *** ppp-2.3.5/pppd/md5.c Wed Mar 12 09:32:27 1997 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/md5.c Sun Jan 24 14:36:50 1999 *************** *** 1,306 **** ! /* ! *********************************************************************** ! ** 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 (hash, mdContext) ! unsigned char hash[]; ! 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); ! } ! memcpy(hash, mdContext->digest, 16); } ! /* 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) ******************************** */ --- 1,370 ---- + /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + */ + /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. 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" ! /* Constants for MD5Transform routine. */ + #define S11 7 + #define S12 12 + #define S13 17 + #define S14 22 + #define S21 5 + #define S22 9 + #define S23 14 + #define S24 20 + #define S31 4 + #define S32 11 + #define S33 16 + #define S34 23 + #define S41 6 + #define S42 10 + #define S43 15 + #define S44 21 ! static void MD5Transform PROTO_LIST ((UINT4[4], unsigned char[64])); ! static void Encode PROTO_LIST ! ((unsigned char *, UINT4 *, unsigned int)); ! static void Decode PROTO_LIST ! ((UINT4 *, unsigned char *, unsigned int)); ! static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); ! static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); static unsigned char PADDING[64] = { ! 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ! /* 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); \ } ! md5_calc (output, input, inlen) ! unsigned char *output; ! unsigned char *input; /* input block */ ! unsigned int inlen; /* length of input block */ ! { ! MD5_CTX context; ! MD5Init (&context); ! MD5Update (&context, input, inlen); ! MD5Final (output, &context); ! } ! ! /* MD5 initialization. Begins an MD5 operation, writing a new context. */ ! void ! MD5Init (context) ! MD5_CTX *context; /* context */ { ! context->count[0] = context->count[1] = 0; ! /* ! * Load magic initialization constants. ! */ ! context->state[0] = 0x67452301; ! context->state[1] = 0xefcdab89; ! context->state[2] = 0x98badcfe; ! context->state[3] = 0x10325476; } ! /* MD5 block update operation. Continues an MD5 message-digest ! operation, processing another message block, and updating the ! context. */ ! void ! MD5Update (context, input, inputLen) ! MD5_CTX *context; /* context */ ! unsigned char *input; /* input block */ ! unsigned int inputLen; /* length of input block */ { ! unsigned int i, ! index, ! partLen; ! /* Compute number of bytes mod 64 */ ! index = (unsigned int) ((context->count[0] >> 3) & 0x3F); ! /* Update number of bits */ ! if ((context->count[0] += ((UINT4) inputLen << 3)) ! < ((UINT4) inputLen << 3)) ! context->count[1]++; ! context->count[1] += ((UINT4) inputLen >> 29); ! partLen = 64 - index; ! /* ! * Transform as many times as possible. ! */ ! if (inputLen >= partLen) ! { ! MD5_memcpy ! ((POINTER) & context->buffer[index], (POINTER) input, partLen); ! MD5Transform (context->state, context->buffer); ! ! for (i = partLen; i + 63 < inputLen; i += 64) ! MD5Transform (context->state, &input[i]); ! ! index = 0; ! } ! else ! i = 0; ! ! /* Buffer remaining input */ ! MD5_memcpy ! ((POINTER) & context->buffer[index], (POINTER) & input[i], ! inputLen - i); } ! /* MD5 finalization. Ends an MD5 message-digest operation, writing the ! the message digest and zeroizing the context. */ ! void ! MD5Final (digest, context) ! unsigned char digest[16]; /* message digest */ ! MD5_CTX *context; /* context */ { ! unsigned char bits[8]; ! unsigned int index, ! padLen; ! /* Save number of bits */ ! Encode (bits, context->count, 8); ! /* ! * Pad out to 56 mod 64. ! */ ! index = (unsigned int) ((context->count[0] >> 3) & 0x3f); ! padLen = (index < 56) ? (56 - index) : (120 - index); ! MD5Update (context, PADDING, padLen); ! /* Append length (before padding) */ ! MD5Update (context, bits, 8); ! /* Store state in digest */ ! Encode (digest, context->state, 16); ! /* ! * Zeroize sensitive information. ! */ ! MD5_memset ((POINTER) context, 0, sizeof (*context)); } ! /* MD5 basic transformation. Transforms state based on block. */ ! static void ! MD5Transform (state, block) ! UINT4 state[4]; ! unsigned char block[64]; { ! UINT4 a = state[0], ! b = state[1], ! c = state[2], ! d = state[3], ! x[16]; ! Decode (x, block, 64); ! /* Round 1 */ ! FF (a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ ! FF (d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ ! FF (c, d, a, b, x[2], S13, 0x242070db); /* 3 */ ! FF (b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ ! FF (a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ ! FF (d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ ! FF (c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ ! FF (b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ ! FF (a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ ! FF (d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ ! FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ ! FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ ! FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ ! FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ ! FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ ! FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ ! /* Round 2 */ ! GG (a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ ! GG (d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ ! GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ ! GG (b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ ! GG (a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ ! GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ ! GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ ! GG (b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ ! GG (a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ ! GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ ! GG (c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ ! GG (b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ ! GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ ! GG (d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ ! GG (c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ ! GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ ! /* Round 3 */ ! HH (a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ ! HH (d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ ! HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ ! HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ ! HH (a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ ! HH (d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ ! HH (c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ ! HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ ! HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ ! HH (d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ ! HH (c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ ! HH (b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ ! HH (a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ ! HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ ! HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ ! HH (b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ ! /* Round 4 */ ! II (a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ ! II (d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ ! II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ ! II (b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ ! II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ ! II (d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ ! II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ ! II (b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ ! II (a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ ! II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ ! II (c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ ! II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ ! II (a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ ! II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ ! II (c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ ! II (b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ ! ! state[0] += a; ! state[1] += b; ! state[2] += c; ! state[3] += d; ! ! /* ! * Zeroize sensitive information. ! */ ! MD5_memset ((POINTER) x, 0, sizeof (x)); } ! /* Encodes input (UINT4) into output (unsigned char). Assumes len is ! a multiple of 4. ! */ ! static void ! Encode (output, input, len) ! unsigned char *output; ! UINT4 *input; ! unsigned int len; ! { ! unsigned int i, ! j; ! ! for (i = 0, j = 0; j < len; i++, j += 4) ! { ! output[j] = (unsigned char) (input[i] & 0xff); ! output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff); ! output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff); ! output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff); ! } ! } ! ! /* Decodes input (unsigned char) into output (UINT4). Assumes len is ! a multiple of 4. ! */ ! static void ! Decode (output, input, len) ! UINT4 *output; ! unsigned char *input; ! unsigned int len; ! { ! unsigned int i, ! j; ! ! for (i = 0, j = 0; j < len; i++, j += 4) ! output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) | ! (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24); ! } ! ! /* Note: Replace "for loop" with standard memcpy if possible. */ + + static void + MD5_memcpy (output, input, len) + POINTER output; + POINTER input; + unsigned int len; + { + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = input[i]; + } + + /* Note: Replace "for loop" with standard memset if possible. + */ + static void + MD5_memset (output, value, len) + POINTER output; + int value; + unsigned int len; + { + unsigned int i; + + for (i = 0; i < len; i++) + ((char *) output)[i] = (char) value; + } diff -r -P -d -C 3 ppp-2.3.5/pppd/md5.h ppp-2.3.5-2cbcps-radius-multiport/pppd/md5.h *** ppp-2.3.5/pppd/md5.h Fri Sep 13 09:52:53 1996 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/md5.h Sun Jan 24 14:36:50 1999 *************** *** 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__ */ --- 1,73 ---- ! /* GLOBAL.H - RSAREF types and constants */ ! /* PROTOTYPES should be set to one if and only if the compiler supports ! function argument prototyping. ! The following makes PROTOTYPES default to 0 if it has not already ! been defined with C compiler flags. */ ! #ifndef PROTOTYPES ! #define PROTOTYPES 0 ! #endif ! /* POINTER defines a generic pointer type */ ! typedef unsigned char *POINTER; ! ! /* UINT2 defines a two byte word */ ! typedef unsigned short int UINT2; ! ! /* UINT4 defines a four byte word */ ! #if defined(__alpha) && defined(__osf__) typedef unsigned int UINT4; + #else + typedef unsigned long int UINT4; + #endif ! /* PROTO_LIST is defined depending on how PROTOTYPES is defined above. ! If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it ! returns an empty list. ! */ ! #if PROTOTYPES ! #define PROTO_LIST(list) list ! #else ! #define PROTO_LIST(list) () ! #endif ! /* MD5.H - header file for MD5C.C ! */ ! ! /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. 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. ! */ ! ! /* MD5 context. */ ! typedef struct ! { ! UINT4 state[4]; /* state (ABCD) */ ! UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ ! unsigned char buffer[64]; /* input buffer */ ! } MD5_CTX; ! ! void MD5Init PROTO_LIST ((MD5_CTX *)); ! void MD5Update PROTO_LIST ((MD5_CTX *, unsigned char *, unsigned int)); ! void MD5Final PROTO_LIST ((unsigned char[16], MD5_CTX *)); diff -r -P -d -C 3 ppp-2.3.5/pppd/options.c ppp-2.3.5-2cbcps-radius-multiport/pppd/options.c *** ppp-2.3.5/pppd/options.c Thu Mar 26 09:46:07 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/options.c Sun Jan 16 14:16:59 2000 *************** *** 50,55 **** --- 50,56 ---- #include "upap.h" #include "chap.h" #include "ccp.h" + #include "cbcps.h" #ifdef CBCP_SUPPORT #include "cbcp.h" #endif *************** *** 108,117 **** --- 109,128 ---- int demand = 0; /* do dial-on-demand */ char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ int cryptpap; /* Passwords in pap-secrets are encrypted */ + char staticdevnam[MAXPATHLEN] = "/dev/tty"; /* Reserv value - Device name */ + int useradius = 0; + int usemultiport = 0; /* Use Multiport device (c) Ilya Ismailov, TTS, Tyumen, Russian*/ + int multiportfist = 0; /* Fist Multiport device (c) Ilya Ismailov, TTS,Tyumen, Russian*/ + int multiportend = 0; /* End Multiport device (c) Ilya Ismailov, TTS, Tyumen, Russian*/ int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ int holdoff = 30; /* # seconds to pause before reconnecting */ int refuse_pap = 0; /* Set to say we won't do PAP */ int refuse_chap = 0; /* Set to say we won't do CHAP */ + char callerid[64]; /* Caller's ID */ + char calleridtool[MAXPATHLEN];/* program called to get ID */ + char con_state[32]; /* CONNECT string from mgetty log */ + char con_tool[MAXPATHLEN]; /* a tool which is called to fill up con_state*/ + #ifdef MSLANMAN int ms_lanman = 0; /* Nonzero if use LanMan password instead of NT */ *************** *** 158,163 **** --- 169,177 ---- static int setescape __P((char **)); static int setmru __P((char **)); static int setmtu __P((char **)); + static int setcbcps __P((char **)); + static int setcallerid __P((char **)); + static int setconstate __P((char **)); #ifdef CBCP_SUPPORT static int setcbcp __P((char **)); #endif *************** *** 222,227 **** --- 236,243 ---- static int setnopred1comp __P((char **)); static int setipparam __P((char **)); static int setpapcrypt __P((char **)); + static int setradius __P((char **)); + static int setmultiport __P((char **)); static int setidle __P((char **)); static int setholdoff __P((char **)); static int setdnsaddr __P((char **)); *************** *** 317,322 **** --- 333,341 ---- {"domain", 1, setdomain}, /* Add given domain name to hostname*/ {"mru", 1, setmru}, /* Set MRU value for negotiation */ {"mtu", 1, setmtu}, /* Set our MTU */ + {"cb", 0, setcbcps}, + {"callerid", 1, setcallerid}, + {"connect_state", 1, setconstate}, #ifdef CBCP_SUPPORT {"callback", 1, setcbcp}, /* Ask for callback */ #endif *************** *** 377,382 **** --- 396,403 ---- {"-predictor1", 0, setnopred1comp}, /* don't allow Predictor-1 */ {"ipparam", 1, setipparam}, /* set ip script parameter */ {"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */ + {"radius", 1, setradius}, + {"multiport", 1, setmultiport}, /* Use Multiport device (c) Ilya Ismailov, TTS, Tyumen, Russian*/ {"idle", 1, setidle}, /* idle time limit (seconds) */ {"holdoff", 1, setholdoff}, /* set holdoff time (seconds) */ {"ms-dns", 1, setdnsaddr}, /* DNS address for the peer's use */ *************** *** 1289,1294 **** --- 1310,1341 ---- return (1); } + + static int + setcallerid(argv) + char **argv; + { + strcpy(calleridtool,*argv); + return (1); + } + + static int + setconstate(argv) + char **argv; + { + strcpy(con_tool,*argv); + return (1); + } + + static int + setcbcps(argv) + char **argv; + { + lcp_wantoptions[0].neg_cbcp = 1; // poslem licitaciu na cbcp + lcp_allowoptions[0].neg_cbcp = 1; // ak bude pytat cbcp potvrdim. + cbcp_protent.enabled_flag = 1; // povolovanie protokolu po novom. + return(1); + } #ifdef CBCP_SUPPORT static int setcbcp(argv) *************** *** 1669,1686 **** * Check if there is a device by this name. */ if (stat(cp, &statbuf) < 0) { ! if (errno == ENOENT || quiet) ! return 0; ! option_error("Couldn't stat %s: %m", cp); ! return -1; } (void) strncpy(devnam, cp, MAXPATHLEN); devnam[MAXPATHLEN-1] = 0; default_device = FALSE; devnam_info.priv = privileged_option; - devnam_info.source = option_source; - return 1; } --- 1716,1733 ---- * Check if there is a device by this name. */ if (stat(cp, &statbuf) < 0) { ! if (errno == ENOENT || quiet) ! return 0; ! option_error("Couldn't stat %s: %m", cp); ! return -1; } (void) strncpy(devnam, cp, MAXPATHLEN); devnam[MAXPATHLEN-1] = 0; + (void) strncpy(staticdevnam, cp, MAXPATHLEN); + staticdevnam[MAXPATHLEN-1] = 0; default_device = FALSE; devnam_info.priv = privileged_option; return 1; } *************** *** 1776,1781 **** --- 1823,1894 ---- return 1; } + + static int setradius (argv) + char **argv; + { + useradius = 1; + return radius_init(*argv); + } + + /* + * Use Multiport device (c) Ilya Ismailov, TTS, Tyumen, Russian + */ + static int setmultiport (argv) + char **argv; + { + char str[50]; + int i, count; + char *p = argv[0]; + char flag = 0; + + for(i=0, count=0;i= '0')&&( p[i] <= '9') ){ + str[count] = p[i]; + str[count+1] = '\0'; + count++; + }else if( (p[i] == ':') ){ + str[i] = '\0'; + flag = 1; + break; + }else{ + flag = 0; + break; + } + } + if( count ){ + multiportfist = atoi(str); + if(flag){ + for(i = i+1, count=0;i= '0')&&( p[i] <= '9') ){ + str[count] = p[i]; + str[count+1] = '\0'; + count++; + }else{ + break; + } + } + if( count ){ + multiportend = atoi(str); + if( multiportend < multiportfist){ + usemultiport = 0; + /* syslog(LOG_ERR, "Option 'multiport': invalid parameter '%s'.", *argv);*/ + option_error("option 'multiport': invalid parameter '%s'", *argv); + return 0; + } + }else{ + multiportend = -1; + } + } + }else{ + usemultiport = 0; + /* syslog(LOG_ERR, "Option 'multiport': invalid parameter '%s'.", *argv);*/ + option_error("option 'multiport': invalid parameter '%s'", *argv); + return 0; + } + usemultiport = 1; + return 1; + } /* * setipcpaccr - accept peer's idea of its address diff -r -P -d -C 3 ppp-2.3.5/pppd/options.c.orig ppp-2.3.5-2cbcps-radius-multiport/pppd/options.c.orig *** ppp-2.3.5/pppd/options.c.orig Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/options.c.orig Thu Aug 19 15:19:32 1999 *************** *** 0 **** --- 1,2627 ---- + /* + * options.c - handles option processing for PPP. + * + * 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: options.c,v 1.42 1998/03/26 04:46:06 paulus Exp $"; + #endif + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifdef PPP_FILTER + #include + #include /* XXX: To get struct pcap */ + #endif + + #include "pppd.h" + #include "pathnames.h" + #include "patchlevel.h" + #include "fsm.h" + #include "lcp.h" + #include "ipcp.h" + #include "upap.h" + #include "chap.h" + #include "ccp.h" + #include "cbcps.h" + #ifdef CBCP_SUPPORT + #include "cbcp.h" + #endif + + #ifdef IPX_CHANGE + #include "ipxcp.h" + #endif /* IPX_CHANGE */ + + #include + + #define FALSE 0 + #define TRUE 1 + + #if defined(ultrix) || defined(NeXT) + char *strdup __P((char *)); + #endif + + #ifndef GIDSET_TYPE + #define GIDSET_TYPE gid_t + #endif + + /* + * Option variables and default values. + */ + #ifdef PPP_FILTER + int dflag = 0; /* Tell libpcap we want debugging */ + #endif + int debug = 0; /* Debug flag */ + int kdebugflag = 0; /* Tell kernel to print debug messages */ + int default_device = 1; /* Using /dev/tty or equivalent */ + char devnam[MAXPATHLEN] = "/dev/tty"; /* Device name */ + int crtscts = 0; /* Use hardware flow control */ + int modem = 1; /* Use modem control lines */ + int inspeed = 0; /* Input/Output speed requested */ + u_int32_t netmask = 0; /* IP netmask to set on interface */ + int lockflag = 0; /* Create lock file to lock the serial dev */ + int nodetach = 0; /* Don't detach from controlling tty */ + char *connector = NULL; /* Script to establish physical link */ + char *disconnector = NULL; /* Script to disestablish physical link */ + char *welcomer = NULL; /* Script to run after phys link estab. */ + int maxconnect = 0; /* Maximum connect time */ + char user[MAXNAMELEN]; /* Username for PAP */ + char passwd[MAXSECRETLEN]; /* Password for PAP */ + int auth_required = 0; /* Peer is required to authenticate */ + int defaultroute = 0; /* assign default route through interface */ + int proxyarp = 0; /* Set up proxy ARP entry for peer */ + int persist = 0; /* Reopen link after it goes down */ + int uselogin = 0; /* Use /etc/passwd for checking PAP */ + int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ + int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ + char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ + char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ + int explicit_remote = 0; /* User specified explicit remote name */ + int usehostname = 0; /* Use hostname for our_name */ + int disable_defaultip = 0; /* Don't use hostname for default IP adrs */ + int demand = 0; /* do dial-on-demand */ + char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ + int cryptpap; /* Passwords in pap-secrets are encrypted */ + int useradius = 0; + int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ + int holdoff = 30; /* # seconds to pause before reconnecting */ + int refuse_pap = 0; /* Set to say we won't do PAP */ + int refuse_chap = 0; /* Set to say we won't do CHAP */ + char callerid[64]; /* Caller's ID */ + char calleridtool[MAXPATHLEN];/* program called to get ID */ + char con_state[32]; /* CONNECT string from mgetty log */ + char con_tool[MAXPATHLEN]; /* a tool which is called to fill up con_state*/ + + + #ifdef MSLANMAN + int ms_lanman = 0; /* Nonzero if use LanMan password instead of NT */ + /* Has meaning only with MS-CHAP challenges */ + #endif + + struct option_info auth_req_info; + struct option_info connector_info; + struct option_info disconnector_info; + struct option_info welcomer_info; + struct option_info devnam_info; + #ifdef PPP_FILTER + struct bpf_program pass_filter;/* Filter program for packets to pass */ + struct bpf_program active_filter; /* Filter program for link-active pkts */ + pcap_t pc; /* Fake struct pcap so we can compile expr */ + #endif + + /* + * Prototypes + */ + static int setdevname __P((char *, int)); + static int setipaddr __P((char *)); + static int setspeed __P((char *)); + static int setdebug __P((char **)); + static int setkdebug __P((char **)); + static int setpassive __P((char **)); + static int setsilent __P((char **)); + static int noopt __P((char **)); + static int setnovj __P((char **)); + static int setnovjccomp __P((char **)); + static int setvjslots __P((char **)); + static int reqpap __P((char **)); + static int nopap __P((char **)); + #ifdef OLD_OPTIONS + static int setupapfile __P((char **)); + #endif + static int nochap __P((char **)); + static int reqchap __P((char **)); + static int noaccomp __P((char **)); + static int noasyncmap __P((char **)); + static int noip __P((char **)); + static int nomagicnumber __P((char **)); + static int setasyncmap __P((char **)); + static int setescape __P((char **)); + static int setmru __P((char **)); + static int setmtu __P((char **)); + static int setcbcps __P((char **)); + static int setcallerid __P((char **)); + static int setconstate __P((char **)); + #ifdef CBCP_SUPPORT + static int setcbcp __P((char **)); + #endif + static int nomru __P((char **)); + static int nopcomp __P((char **)); + static int setconnector __P((char **)); + static int setdisconnector __P((char **)); + static int setwelcomer __P((char **)); + static int setmaxconnect __P((char **)); + static int setdomain __P((char **)); + static int setnetmask __P((char **)); + static int setcrtscts __P((char **)); + static int setnocrtscts __P((char **)); + static int setxonxoff __P((char **)); + static int setnodetach __P((char **)); + static int setupdetach __P((char **)); + static int setmodem __P((char **)); + static int setlocal __P((char **)); + static int setlock __P((char **)); + static int setname __P((char **)); + static int setuser __P((char **)); + static int setremote __P((char **)); + static int setauth __P((char **)); + static int setnoauth __P((char **)); + static int readfile __P((char **)); + static int callfile __P((char **)); + static int setdefaultroute __P((char **)); + static int setnodefaultroute __P((char **)); + static int setproxyarp __P((char **)); + static int setnoproxyarp __P((char **)); + static int setpersist __P((char **)); + static int setnopersist __P((char **)); + static int setdologin __P((char **)); + static int setusehostname __P((char **)); + static int setnoipdflt __P((char **)); + static int setlcptimeout __P((char **)); + static int setlcpterm __P((char **)); + static int setlcpconf __P((char **)); + static int setlcpfails __P((char **)); + static int setipcptimeout __P((char **)); + static int setipcpterm __P((char **)); + static int setipcpconf __P((char **)); + static int setipcpfails __P((char **)); + static int setpaptimeout __P((char **)); + static int setpapreqs __P((char **)); + static int setpapreqtime __P((char **)); + static int setchaptimeout __P((char **)); + static int setchapchal __P((char **)); + static int setchapintv __P((char **)); + static int setipcpaccl __P((char **)); + static int setipcpaccr __P((char **)); + static int setlcpechointv __P((char **)); + static int setlcpechofails __P((char **)); + static int noccp __P((char **)); + static int setbsdcomp __P((char **)); + static int setnobsdcomp __P((char **)); + static int setdeflate __P((char **)); + static int setnodeflate __P((char **)); + static int setnodeflatedraft __P((char **)); + static int setdemand __P((char **)); + static int setpred1comp __P((char **)); + static int setnopred1comp __P((char **)); + static int setipparam __P((char **)); + static int setpapcrypt __P((char **)); + static int setradius __P((char **)); + static int setidle __P((char **)); + static int setholdoff __P((char **)); + static int setdnsaddr __P((char **)); + static int resetipxproto __P((char **)); + static int setwinsaddr __P((char **)); + static int showversion __P((char **)); + static int showhelp __P((char **)); + + #ifdef PPP_FILTER + static int setpdebug __P((char **)); + static int setpassfilter __P((char **)); + static int setactivefilter __P((char **)); + #endif + + #ifdef IPX_CHANGE + static int setipxproto __P((char **)); + static int setipxanet __P((char **)); + static int setipxalcl __P((char **)); + static int setipxarmt __P((char **)); + static int setipxnetwork __P((char **)); + static int setipxnode __P((char **)); + static int setipxrouter __P((char **)); + static int setipxname __P((char **)); + static int setipxcptimeout __P((char **)); + static int setipxcpterm __P((char **)); + static int setipxcpconf __P((char **)); + static int setipxcpfails __P((char **)); + #endif /* IPX_CHANGE */ + + #ifdef MSLANMAN + static int setmslanman __P((char **)); + #endif + + static int number_option __P((char *, u_int32_t *, int)); + static int int_option __P((char *, int *)); + static int readable __P((int fd)); + + /* + * Valid arguments. + */ + static struct cmd { + char *cmd_name; + int num_args; + int (*cmd_func) __P((char **)); + } cmds[] = { + {"-all", 0, noopt}, /* Don't request/allow any options (useless) */ + {"noaccomp", 0, noaccomp}, /* Disable Address/Control compression */ + {"-ac", 0, noaccomp}, /* Disable Address/Control compress */ + {"default-asyncmap", 0, noasyncmap}, /* Disable asyncmap negoatiation */ + {"-am", 0, noasyncmap}, /* Disable asyncmap negotiation */ + {"-as", 1, setasyncmap}, /* set the desired async map */ + {"-d", 0, setdebug}, /* Increase debugging level */ + {"nodetach", 0, setnodetach}, /* Don't detach from controlling tty */ + {"-detach", 0, setnodetach}, /* don't fork */ + {"updetach", 0, setupdetach}, /* Detach once an NP has come up */ + {"noip", 0, noip}, /* Disable IP and IPCP */ + {"-ip", 0, noip}, /* Disable IP and IPCP */ + {"nomagic", 0, nomagicnumber}, /* Disable magic number negotiation */ + {"-mn", 0, nomagicnumber}, /* Disable magic number negotiation */ + {"default-mru", 0, nomru}, /* Disable MRU negotiation */ + {"-mru", 0, nomru}, /* Disable mru negotiation */ + {"-p", 0, setpassive}, /* Set passive mode */ + {"nopcomp", 0, nopcomp}, /* Disable protocol field compression */ + {"-pc", 0, nopcomp}, /* Disable protocol field compress */ + #if OLD_OPTIONS + {"+ua", 1, setupapfile}, /* Get PAP user and password from file */ + #endif + {"require-pap", 0, reqpap}, /* Require PAP authentication from peer */ + {"+pap", 0, reqpap}, /* Require PAP auth from peer */ + {"refuse-pap", 0, nopap}, /* Don't agree to auth to peer with PAP */ + {"-pap", 0, nopap}, /* Don't allow UPAP authentication with peer */ + {"require-chap", 0, reqchap}, /* Require CHAP authentication from peer */ + {"+chap", 0, reqchap}, /* Require CHAP authentication from peer */ + {"refuse-chap", 0, nochap}, /* Don't agree to auth to peer with CHAP */ + {"-chap", 0, nochap}, /* Don't allow CHAP authentication with peer */ + {"novj", 0, setnovj}, /* Disable VJ compression */ + {"-vj", 0, setnovj}, /* disable VJ compression */ + {"novjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */ + {"-vjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */ + {"vj-max-slots", 1, setvjslots}, /* Set maximum VJ header slots */ + {"asyncmap", 1, setasyncmap}, /* set the desired async map */ + {"escape", 1, setescape}, /* set chars to escape on transmission */ + {"connect", 1, setconnector}, /* A program to set up a connection */ + {"disconnect", 1, setdisconnector}, /* program to disconnect serial dev. */ + {"welcome", 1, setwelcomer},/* Script to welcome client */ + {"maxconnect", 1, setmaxconnect}, /* specify a maximum connect time */ + {"crtscts", 0, setcrtscts}, /* set h/w flow control */ + {"nocrtscts", 0, setnocrtscts}, /* clear h/w flow control */ + {"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */ + {"xonxoff", 0, setxonxoff}, /* set s/w flow control */ + {"debug", 0, setdebug}, /* Increase debugging level */ + {"kdebug", 1, setkdebug}, /* Enable kernel-level debugging */ + {"domain", 1, setdomain}, /* Add given domain name to hostname*/ + {"mru", 1, setmru}, /* Set MRU value for negotiation */ + {"mtu", 1, setmtu}, /* Set our MTU */ + {"cb", 0, setcbcps}, + {"callerid", 1, setcallerid}, + {"connect_state", 1, setconstate}, + #ifdef CBCP_SUPPORT + {"callback", 1, setcbcp}, /* Ask for callback */ + #endif + {"netmask", 1, setnetmask}, /* set netmask */ + {"passive", 0, setpassive}, /* Set passive mode */ + {"silent", 0, setsilent}, /* Set silent mode */ + {"modem", 0, setmodem}, /* Use modem control lines */ + {"local", 0, setlocal}, /* Don't use modem control lines */ + {"lock", 0, setlock}, /* Lock serial device (with lock file) */ + {"name", 1, setname}, /* Set local name for authentication */ + {"user", 1, setuser}, /* Set name for auth with peer */ + {"usehostname", 0, setusehostname}, /* Must use hostname for auth. */ + {"remotename", 1, setremote}, /* Set remote name for authentication */ + {"auth", 0, setauth}, /* Require authentication from peer */ + {"noauth", 0, setnoauth}, /* Don't require peer to authenticate */ + {"file", 1, readfile}, /* Take options from a file */ + {"call", 1, callfile}, /* Take options from a privileged file */ + {"defaultroute", 0, setdefaultroute}, /* Add default route */ + {"nodefaultroute", 0, setnodefaultroute}, /* disable defaultroute option */ + {"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */ + {"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */ + {"noproxyarp", 0, setnoproxyarp}, /* disable proxyarp option */ + {"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */ + {"persist", 0, setpersist}, /* Keep on reopening connection after close */ + {"nopersist", 0, setnopersist}, /* Turn off persist option */ + {"demand", 0, setdemand}, /* Dial on demand */ + {"login", 0, setdologin}, /* Use system password database for UPAP */ + {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */ + {"lcp-echo-failure", 1, setlcpechofails}, /* consecutive echo failures */ + {"lcp-echo-interval", 1, setlcpechointv}, /* time for lcp echo events */ + {"lcp-restart", 1, setlcptimeout}, /* Set timeout for LCP */ + {"lcp-max-terminate", 1, setlcpterm}, /* Set max #xmits for term-reqs */ + {"lcp-max-configure", 1, setlcpconf}, /* Set max #xmits for conf-reqs */ + {"lcp-max-failure", 1, setlcpfails}, /* Set max #conf-naks for LCP */ + {"ipcp-restart", 1, setipcptimeout}, /* Set timeout for IPCP */ + {"ipcp-max-terminate", 1, setipcpterm}, /* Set max #xmits for term-reqs */ + {"ipcp-max-configure", 1, setipcpconf}, /* Set max #xmits for conf-reqs */ + {"ipcp-max-failure", 1, setipcpfails}, /* Set max #conf-naks for IPCP */ + {"pap-restart", 1, setpaptimeout}, /* Set retransmit timeout for PAP */ + {"pap-max-authreq", 1, setpapreqs}, /* Set max #xmits for auth-reqs */ + {"pap-timeout", 1, setpapreqtime}, /* Set time limit for peer PAP auth. */ + {"chap-restart", 1, setchaptimeout}, /* Set timeout for CHAP */ + {"chap-max-challenge", 1, setchapchal}, /* Set max #xmits for challenge */ + {"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */ + {"ipcp-accept-local", 0, setipcpaccl}, /* Accept peer's address for us */ + {"ipcp-accept-remote", 0, setipcpaccr}, /* Accept peer's address for it */ + {"noccp", 0, noccp}, /* Disable CCP negotiation */ + {"-ccp", 0, noccp}, /* Disable CCP negotiation */ + {"bsdcomp", 1, setbsdcomp}, /* request BSD-Compress */ + {"nobsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */ + {"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */ + {"deflate", 1, setdeflate}, /* request Deflate compression */ + {"nodeflate", 0, setnodeflate}, /* don't allow Deflate compression */ + {"-deflate", 0, setnodeflate}, /* don't allow Deflate compression */ + {"nodeflatedraft", 0, setnodeflatedraft}, /* don't use draft deflate # */ + {"predictor1", 0, setpred1comp}, /* request Predictor-1 */ + {"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */ + {"-predictor1", 0, setnopred1comp}, /* don't allow Predictor-1 */ + {"ipparam", 1, setipparam}, /* set ip script parameter */ + {"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */ + {"radius", 1, setradius}, + {"idle", 1, setidle}, /* idle time limit (seconds) */ + {"holdoff", 1, setholdoff}, /* set holdoff time (seconds) */ + {"ms-dns", 1, setdnsaddr}, /* DNS address for the peer's use */ + {"ms-wins", 1, setwinsaddr}, /* Nameserver for SMB over TCP/IP for peer */ + {"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ + {"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ + {"--version", 0, showversion}, /* Show version number */ + {"--help", 0, showhelp}, /* Show brief listing of options */ + {"-h", 0, showhelp}, /* ditto */ + + #ifdef PPP_FILTER + {"pdebug", 1, setpdebug}, /* libpcap debugging */ + {"pass-filter", 1, setpassfilter}, /* set filter for packets to pass */ + {"active-filter", 1, setactivefilter}, /* set filter for active pkts */ + #endif + + #ifdef IPX_CHANGE + {"ipx-network", 1, setipxnetwork}, /* IPX network number */ + {"ipxcp-accept-network", 0, setipxanet}, /* Accept peer netowrk */ + {"ipx-node", 1, setipxnode}, /* IPX node number */ + {"ipxcp-accept-local", 0, setipxalcl}, /* Accept our address */ + {"ipxcp-accept-remote", 0, setipxarmt}, /* Accept peer's address */ + {"ipx-routing", 1, setipxrouter}, /* IPX routing proto number */ + {"ipx-router-name", 1, setipxname}, /* IPX router name */ + {"ipxcp-restart", 1, setipxcptimeout}, /* Set timeout for IPXCP */ + {"ipxcp-max-terminate", 1, setipxcpterm}, /* max #xmits for term-reqs */ + {"ipxcp-max-configure", 1, setipxcpconf}, /* max #xmits for conf-reqs */ + {"ipxcp-max-failure", 1, setipxcpfails}, /* max #conf-naks for IPXCP */ + #if 0 + {"ipx-compression", 1, setipxcompression}, /* IPX compression number */ + #endif + {"ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */ + {"+ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */ + #endif /* IPX_CHANGE */ + + #ifdef MSLANMAN + {"ms-lanman", 0, setmslanman}, /* Use LanMan psswd when using MS-CHAP */ + #endif + + {NULL, 0, NULL} + }; + + + #ifndef IMPLEMENTATION + #define IMPLEMENTATION "" + #endif + + static char *usage_string = "\ + pppd version %s patch level %d%s\n\ + Usage: %s [ options ], where options are:\n\ + Communicate over the named device\n\ + Set the baud rate to \n\ + : Set the local and/or remote interface IP\n\ + addresses. Either one may be omitted.\n\ + asyncmap Set the desired async map to hex \n\ + auth Require authentication from peer\n\ + connect

Invoke shell command

to set up the serial line\n\ + crtscts Use hardware RTS/CTS flow control\n\ + defaultroute Add default route through interface\n\ + file Take options from file \n\ + modem Use modem control lines\n\ + mru Set MRU value to for negotiation\n\ + See pppd(8) for more options.\n\ + "; + + static char *current_option; /* the name of the option being parsed */ + static int privileged_option; /* set iff the current option came from root */ + static char *option_source; /* string saying where the option came from */ + + /* + * parse_args - parse a string of arguments from the command line. + */ + int + parse_args(argc, argv) + int argc; + char **argv; + { + char *arg; + struct cmd *cmdp; + int ret; + + privileged_option = privileged; + option_source = "command line"; + while (argc > 0) { + arg = *argv++; + --argc; + + /* + * First see if it's a command. + */ + for (cmdp = cmds; cmdp->cmd_name; cmdp++) + if (!strcmp(arg, cmdp->cmd_name)) + break; + + if (cmdp->cmd_name != NULL) { + if (argc < cmdp->num_args) { + option_error("too few parameters for option %s", arg); + return 0; + } + current_option = arg; + if (!(*cmdp->cmd_func)(argv)) + return 0; + argc -= cmdp->num_args; + argv += cmdp->num_args; + + } else { + /* + * Maybe a tty name, speed or IP address? + */ + if ((ret = setdevname(arg, 0)) == 0 + && (ret = setspeed(arg)) == 0 + && (ret = setipaddr(arg)) == 0) { + option_error("unrecognized option '%s'", arg); + usage(); + return 0; + } + if (ret < 0) /* error */ + return 0; + } + } + return 1; + } + + /* + * scan_args - scan the command line arguments to get the tty name, + * if specified. + */ + void + scan_args(argc, argv) + int argc; + char **argv; + { + char *arg; + struct cmd *cmdp; + + while (argc > 0) { + arg = *argv++; + --argc; + + /* Skip options and their arguments */ + for (cmdp = cmds; cmdp->cmd_name; cmdp++) + if (!strcmp(arg, cmdp->cmd_name)) + break; + + if (cmdp->cmd_name != NULL) { + argc -= cmdp->num_args; + argv += cmdp->num_args; + continue; + } + + /* Check if it's a tty name and copy it if so */ + (void) setdevname(arg, 1); + } + } + + /* + * usage - print out a message telling how to use the program. + */ + void + usage() + { + if (phase == PHASE_INITIALIZE) + fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION, + progname); + } + + /* + * showhelp - print out usage message and exit. + */ + static int + showhelp(argv) + char **argv; + { + if (phase == PHASE_INITIALIZE) { + usage(); + exit(0); + } + return 0; + } + + /* + * showversion - print out the version number and exit. + */ + static int + showversion(argv) + char **argv; + { + if (phase == PHASE_INITIALIZE) { + fprintf(stderr, "pppd version %s patch level %d%s\n", + VERSION, PATCHLEVEL, IMPLEMENTATION); + exit(0); + } + return 0; + } + + /* + * options_from_file - Read a string of options from a file, + * and interpret them. + */ + int + options_from_file(filename, must_exist, check_prot, priv) + char *filename; + int must_exist; + int check_prot; + int priv; + { + FILE *f; + int i, newline, ret; + struct cmd *cmdp; + int oldpriv; + char *argv[MAXARGS]; + char args[MAXARGS][MAXWORDLEN]; + char cmd[MAXWORDLEN]; + + if ((f = fopen(filename, "r")) == NULL) { + if (!must_exist && errno == ENOENT) + return 1; + option_error("Can't open options file %s: %m", filename); + return 0; + } + if (check_prot && !readable(fileno(f))) { + option_error("Can't open options file %s: access denied", filename); + fclose(f); + return 0; + } + + oldpriv = privileged_option; + privileged_option = priv; + ret = 0; + while (getword(f, cmd, &newline, filename)) { + /* + * First see if it's a command. + */ + for (cmdp = cmds; cmdp->cmd_name; cmdp++) + if (!strcmp(cmd, cmdp->cmd_name)) + break; + + if (cmdp->cmd_name != NULL) { + for (i = 0; i < cmdp->num_args; ++i) { + if (!getword(f, args[i], &newline, filename)) { + option_error( + "In file %s: too few parameters for option '%s'", + filename, cmd); + goto err; + } + argv[i] = args[i]; + } + current_option = cmd; + if (!(*cmdp->cmd_func)(argv)) + goto err; + + } else { + /* + * Maybe a tty name, speed or IP address? + */ + if ((i = setdevname(cmd, 0)) == 0 + && (i = setspeed(cmd)) == 0 + && (i = setipaddr(cmd)) == 0) { + option_error("In file %s: unrecognized option '%s'", + filename, cmd); + goto err; + } + if (i < 0) /* error */ + goto err; + } + } + ret = 1; + + err: + fclose(f); + privileged_option = oldpriv; + return ret; + } + + /* + * options_from_user - See if the use has a ~/.ppprc file, + * and if so, interpret options from it. + */ + int + options_from_user() + { + char *user, *path, *file; + int ret; + struct passwd *pw; + + pw = getpwuid(getuid()); + if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) + return 1; + file = _PATH_USEROPT; + path = malloc(strlen(user) + strlen(file) + 2); + if (path == NULL) + novm("init file name"); + strcpy(path, user); + strcat(path, "/"); + strcat(path, file); + ret = options_from_file(path, 0, 1, privileged); + free(path); + return ret; + } + + /* + * options_for_tty - See if an options file exists for the serial + * device, and if so, interpret options from it. + */ + int + options_for_tty() + { + char *dev, *path, *p; + int ret; + + dev = devnam; + if (strncmp(dev, "/dev/", 5) == 0) + dev += 5; + if (strcmp(dev, "tty") == 0) + return 1; /* don't look for /etc/ppp/options.tty */ + path = malloc(strlen(_PATH_TTYOPT) + strlen(dev) + 1); + if (path == NULL) + novm("tty init file name"); + strcpy(path, _PATH_TTYOPT); + /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */ + for (p = path + strlen(path); *dev != 0; ++dev) + *p++ = (*dev == '/'? '.': *dev); + *p = 0; + ret = options_from_file(path, 0, 0, 1); + free(path); + return ret; + } + + /* + * option_error - print a message about an error in an option. + * The message is logged, and also sent to + * stderr if phase == PHASE_INITIALIZE. + */ + void + option_error __V((char *fmt, ...)) + { + va_list args; + char buf[256]; + + #if __STDC__ + va_start(args, fmt); + #else + char *fmt; + va_start(args); + fmt = va_arg(args, char *); + #endif + vfmtmsg(buf, sizeof(buf), fmt, args); + va_end(args); + if (phase == PHASE_INITIALIZE) + fprintf(stderr, "%s: %s\n", progname, buf); + syslog(LOG_ERR, "%s", buf); + } + + /* + * readable - check if a file is readable by the real user. + */ + static int + readable(fd) + int fd; + { + uid_t uid; + int ngroups, i; + struct stat sbuf; + GIDSET_TYPE groups[NGROUPS_MAX]; + + uid = getuid(); + if (uid == 0) + return 1; + if (fstat(fd, &sbuf) != 0) + return 0; + if (sbuf.st_uid == uid) + return sbuf.st_mode & S_IRUSR; + if (sbuf.st_gid == getgid()) + return sbuf.st_mode & S_IRGRP; + ngroups = getgroups(NGROUPS_MAX, groups); + for (i = 0; i < ngroups; ++i) + if (sbuf.st_gid == groups[i]) + return sbuf.st_mode & S_IRGRP; + return sbuf.st_mode & S_IROTH; + } + + /* + * Read a word from a file. + * Words are delimited by white-space or by quotes (" or '). + * Quotes, white-space and \ may be escaped with \. + * \ is ignored. + */ + int + getword(f, word, newlinep, filename) + FILE *f; + char *word; + int *newlinep; + char *filename; + { + int c, len, escape; + int quoted, comment; + int value, digit, got, n; + + #define isoctal(c) ((c) >= '0' && (c) < '8') + + *newlinep = 0; + len = 0; + escape = 0; + comment = 0; + + /* + * First skip white-space and comments. + */ + for (;;) { + c = getc(f); + if (c == EOF) + break; + + /* + * A newline means the end of a comment; backslash-newline + * is ignored. Note that we cannot have escape && comment. + */ + if (c == '\n') { + if (!escape) { + *newlinep = 1; + comment = 0; + } else + escape = 0; + continue; + } + + /* + * Ignore characters other than newline in a comment. + */ + if (comment) + continue; + + /* + * If this character is escaped, we have a word start. + */ + if (escape) + break; + + /* + * If this is the escape character, look at the next character. + */ + if (c == '\\') { + escape = 1; + continue; + } + + /* + * If this is the start of a comment, ignore the rest of the line. + */ + if (c == '#') { + comment = 1; + continue; + } + + /* + * A non-whitespace character is the start of a word. + */ + if (!isspace(c)) + break; + } + + /* + * Save the delimiter for quoted strings. + */ + if (!escape && (c == '"' || c == '\'')) { + quoted = c; + c = getc(f); + } else + quoted = 0; + + /* + * Process characters until the end of the word. + */ + while (c != EOF) { + if (escape) { + /* + * This character is escaped: backslash-newline is ignored, + * various other characters indicate particular values + * as for C backslash-escapes. + */ + escape = 0; + if (c == '\n') { + c = getc(f); + continue; + } + + got = 0; + switch (c) { + case 'a': + value = '\a'; + break; + case 'b': + value = '\b'; + break; + case 'f': + value = '\f'; + break; + case 'n': + value = '\n'; + break; + case 'r': + value = '\r'; + break; + case 's': + value = ' '; + break; + case 't': + value = '\t'; + break; + + default: + if (isoctal(c)) { + /* + * \ddd octal sequence + */ + value = 0; + for (n = 0; n < 3 && isoctal(c); ++n) { + value = (value << 3) + (c & 07); + c = getc(f); + } + got = 1; + break; + } + + if (c == 'x') { + /* + * \x sequence + */ + value = 0; + c = getc(f); + for (n = 0; n < 2 && isxdigit(c); ++n) { + digit = toupper(c) - '0'; + if (digit > 10) + digit += '0' + 10 - 'A'; + value = (value << 4) + digit; + c = getc (f); + } + got = 1; + break; + } + + /* + * Otherwise the character stands for itself. + */ + value = c; + break; + } + + /* + * Store the resulting character for the escape sequence. + */ + if (len < MAXWORDLEN-1) + word[len] = value; + ++len; + + if (!got) + c = getc(f); + continue; + + } + + /* + * Not escaped: see if we've reached the end of the word. + */ + if (quoted) { + if (c == quoted) + break; + } else { + if (isspace(c) || c == '#') { + ungetc (c, f); + break; + } + } + + /* + * Backslash starts an escape sequence. + */ + if (c == '\\') { + escape = 1; + c = getc(f); + continue; + } + + /* + * An ordinary character: store it in the word and get another. + */ + if (len < MAXWORDLEN-1) + word[len] = c; + ++len; + + c = getc(f); + } + + /* + * End of the word: check for errors. + */ + if (c == EOF) { + if (ferror(f)) { + if (errno == 0) + errno = EIO; + option_error("Error reading %s: %m", filename); + die(1); + } + /* + * If len is zero, then we didn't find a word before the + * end of the file. + */ + if (len == 0) + return 0; + } + + /* + * Warn if the word was too long, and append a terminating null. + */ + if (len >= MAXWORDLEN) { + option_error("warning: word in file %s too long (%.20s...)", + filename, word); + len = MAXWORDLEN - 1; + } + word[len] = 0; + + return 1; + + #undef isoctal + + } + + /* + * number_option - parse an unsigned numeric parameter for an option. + */ + static int + number_option(str, valp, base) + char *str; + u_int32_t *valp; + int base; + { + char *ptr; + + *valp = strtoul(str, &ptr, base); + if (ptr == str) { + option_error("invalid numeric parameter '%s' for %s option", + str, current_option); + return 0; + } + return 1; + } + + + /* + * int_option - like number_option, but valp is int *, + * the base is assumed to be 0, and *valp is not changed + * if there is an error. + */ + static int + int_option(str, valp) + char *str; + int *valp; + { + u_int32_t v; + + if (!number_option(str, &v, 0)) + return 0; + *valp = (int) v; + return 1; + } + + + /* + * The following procedures parse options. + */ + + /* + * readfile - take commands from a file. + */ + static int + readfile(argv) + char **argv; + { + return options_from_file(*argv, 1, 1, privileged_option); + } + + /* + * callfile - take commands from /etc/ppp/peers/. + * Name may not contain /../, start with / or ../, or end in /.. + */ + static int + callfile(argv) + char **argv; + { + char *fname, *arg, *p; + int l, ok; + + arg = *argv; + ok = 1; + if (arg[0] == '/' || arg[0] == 0) + ok = 0; + else { + for (p = arg; *p != 0; ) { + if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) { + ok = 0; + break; + } + while (*p != '/' && *p != 0) + ++p; + if (*p == '/') + ++p; + } + } + if (!ok) { + option_error("call option value may not contain .. or start with /"); + return 0; + } + + l = strlen(arg) + strlen(_PATH_PEERFILES) + 1; + if ((fname = (char *) malloc(l)) == NULL) + novm("call file name"); + strcpy(fname, _PATH_PEERFILES); + strcat(fname, arg); + + ok = options_from_file(fname, 1, 1, 1); + + free(fname); + return ok; + } + + + /* + * setdebug - Set debug (command line argument). + */ + static int + setdebug(argv) + char **argv; + { + debug++; + return (1); + } + + /* + * setkdebug - Set kernel debugging level. + */ + static int + setkdebug(argv) + char **argv; + { + return int_option(*argv, &kdebugflag); + } + + #ifdef PPP_FILTER + /* + * setpdebug - Set libpcap debugging level. + */ + static int + setpdebug(argv) + char **argv; + { + return int_option(*argv, &dflag); + } + + /* + * setpassfilter - Set the pass filter for packets + */ + static int + setpassfilter(argv) + char **argv; + { + pc.linktype = DLT_PPP; + pc.snapshot = PPP_HDRLEN; + + if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0) + return 1; + option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc)); + return 0; + } + + /* + * setactivefilter - Set the active filter for packets + */ + static int + setactivefilter(argv) + char **argv; + { + pc.linktype = DLT_PPP; + pc.snapshot = PPP_HDRLEN; + + if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0) + return 1; + option_error("error in active-filter expression: %s\n", pcap_geterr(&pc)); + return 0; + } + #endif + + /* + * noopt - Disable all options. + */ + static int + noopt(argv) + char **argv; + { + BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); + BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); + BZERO((char *) &ipcp_wantoptions[0], sizeof (struct ipcp_options)); + BZERO((char *) &ipcp_allowoptions[0], sizeof (struct ipcp_options)); + + #ifdef IPX_CHANGE + BZERO((char *) &ipxcp_wantoptions[0], sizeof (struct ipxcp_options)); + BZERO((char *) &ipxcp_allowoptions[0], sizeof (struct ipxcp_options)); + #endif /* IPX_CHANGE */ + + return (1); + } + + /* + * noaccomp - Disable Address/Control field compression negotiation. + */ + static int + noaccomp(argv) + char **argv; + { + lcp_wantoptions[0].neg_accompression = 0; + lcp_allowoptions[0].neg_accompression = 0; + return (1); + } + + + /* + * noasyncmap - Disable async map negotiation. + */ + static int + noasyncmap(argv) + char **argv; + { + lcp_wantoptions[0].neg_asyncmap = 0; + lcp_allowoptions[0].neg_asyncmap = 0; + return (1); + } + + + /* + * noip - Disable IP and IPCP. + */ + static int + noip(argv) + char **argv; + { + ipcp_protent.enabled_flag = 0; + return (1); + } + + + /* + * nomagicnumber - Disable magic number negotiation. + */ + static int + nomagicnumber(argv) + char **argv; + { + lcp_wantoptions[0].neg_magicnumber = 0; + lcp_allowoptions[0].neg_magicnumber = 0; + return (1); + } + + + /* + * nomru - Disable mru negotiation. + */ + static int + nomru(argv) + char **argv; + { + lcp_wantoptions[0].neg_mru = 0; + lcp_allowoptions[0].neg_mru = 0; + return (1); + } + + + /* + * setmru - Set MRU for negotiation. + */ + static int + setmru(argv) + char **argv; + { + u_int32_t mru; + + if (!number_option(*argv, &mru, 0)) + return 0; + lcp_wantoptions[0].mru = mru; + lcp_wantoptions[0].neg_mru = 1; + return (1); + } + + + /* + * setmru - Set the largest MTU we'll use. + */ + static int + setmtu(argv) + char **argv; + { + u_int32_t mtu; + + if (!number_option(*argv, &mtu, 0)) + return 0; + if (mtu < MINMRU || mtu > MAXMRU) { + option_error("mtu option value of %u is too %s", mtu, + (mtu < MINMRU? "small": "large")); + return 0; + } + lcp_allowoptions[0].mru = mtu; + return (1); + } + + + static int + setcallerid(argv) + char **argv; + { + strcpy(calleridtool,*argv); + return (1); + } + + static int + setconstate(argv) + char **argv; + { + strcpy(con_tool,*argv); + return (1); + } + + static int + setcbcps(argv) + char **argv; + { + lcp_wantoptions[0].neg_cbcp = 1; // poslem licitaciu na cbcp + lcp_allowoptions[0].neg_cbcp = 1; // ak bude pytat cbcp potvrdim. + cbcp_protent.enabled_flag = 1; // povolovanie protokolu po novom. + return(1); + } + #ifdef CBCP_SUPPORT + static int + setcbcp(argv) + char **argv; + { + lcp_wantoptions[0].neg_cbcp = 1; + cbcp_protent.enabled_flag = 1; + cbcp[0].us_number = strdup(*argv); + if (cbcp[0].us_number == 0) + novm("callback number"); + cbcp[0].us_type |= (1 << CB_CONF_USER); + cbcp[0].us_type |= (1 << CB_CONF_ADMIN); + return (1); + } + #endif + + /* + * nopcomp - Disable Protocol field compression negotiation. + */ + static int + nopcomp(argv) + char **argv; + { + lcp_wantoptions[0].neg_pcompression = 0; + lcp_allowoptions[0].neg_pcompression = 0; + return (1); + } + + + /* + * setpassive - Set passive mode (don't give up if we time out sending + * LCP configure-requests). + */ + static int + setpassive(argv) + char **argv; + { + lcp_wantoptions[0].passive = 1; + return (1); + } + + + /* + * setsilent - Set silent mode (don't start sending LCP configure-requests + * until we get one from the peer). + */ + static int + setsilent(argv) + char **argv; + { + lcp_wantoptions[0].silent = 1; + return 1; + } + + + /* + * nopap - Disable PAP authentication with peer. + */ + static int + nopap(argv) + char **argv; + { + refuse_pap = 1; + return (1); + } + + + /* + * reqpap - Require PAP authentication from peer. + */ + static int + reqpap(argv) + char **argv; + { + lcp_wantoptions[0].neg_upap = 1; + setauth(NULL); + return 1; + } + + #if OLD_OPTIONS + /* + * setupapfile - specifies UPAP info for authenticating with peer. + */ + static int + setupapfile(argv) + char **argv; + { + FILE * ufile; + int l; + + lcp_allowoptions[0].neg_upap = 1; + + /* open user info file */ + if ((ufile = fopen(*argv, "r")) == NULL) { + option_error("unable to open user login data file %s", *argv); + return 0; + } + if (!readable(fileno(ufile))) { + option_error("%s: access denied", *argv); + return 0; + } + check_access(ufile, *argv); + + /* get username */ + if (fgets(user, MAXNAMELEN - 1, ufile) == NULL + || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){ + option_error("unable to read user login data file %s", *argv); + return 0; + } + fclose(ufile); + + /* get rid of newlines */ + l = strlen(user); + if (l > 0 && user[l-1] == '\n') + user[l-1] = 0; + l = strlen(passwd); + if (l > 0 && passwd[l-1] == '\n') + passwd[l-1] = 0; + + return (1); + } + #endif + + /* + * nochap - Disable CHAP authentication with peer. + */ + static int + nochap(argv) + char **argv; + { + refuse_chap = 1; + return (1); + } + + + /* + * reqchap - Require CHAP authentication from peer. + */ + static int + reqchap(argv) + char **argv; + { + lcp_wantoptions[0].neg_chap = 1; + setauth(NULL); + return (1); + } + + + /* + * setnovj - disable vj compression + */ + static int + setnovj(argv) + char **argv; + { + ipcp_wantoptions[0].neg_vj = 0; + ipcp_allowoptions[0].neg_vj = 0; + return (1); + } + + + /* + * setnovjccomp - disable VJ connection-ID compression + */ + static int + setnovjccomp(argv) + char **argv; + { + ipcp_wantoptions[0].cflag = 0; + ipcp_allowoptions[0].cflag = 0; + return 1; + } + + + /* + * setvjslots - set maximum number of connection slots for VJ compression + */ + static int + setvjslots(argv) + char **argv; + { + int value; + + if (!int_option(*argv, &value)) + return 0; + if (value < 2 || value > 16) { + option_error("vj-max-slots value must be between 2 and 16"); + return 0; + } + ipcp_wantoptions [0].maxslotindex = + ipcp_allowoptions[0].maxslotindex = value - 1; + return 1; + } + + + /* + * setconnector - Set a program to connect to a serial line + */ + static int + setconnector(argv) + char **argv; + { + connector = strdup(*argv); + if (connector == NULL) + novm("connect script"); + connector_info.priv = privileged_option; + connector_info.source = option_source; + + return (1); + } + + /* + * setdisconnector - Set a program to disconnect from the serial line + */ + static int + setdisconnector(argv) + char **argv; + { + disconnector = strdup(*argv); + if (disconnector == NULL) + novm("disconnect script"); + disconnector_info.priv = privileged_option; + disconnector_info.source = option_source; + + return (1); + } + + /* + * setwelcomer - Set a program to welcome a client after connection + */ + static int + setwelcomer(argv) + char **argv; + { + welcomer = strdup(*argv); + if (welcomer == NULL) + novm("welcome script"); + welcomer_info.priv = privileged_option; + welcomer_info.source = option_source; + + return (1); + } + + /* + * setmaxconnect - Set the maximum connect time + */ + static int + setmaxconnect(argv) + char **argv; + { + int value; + + if (!int_option(*argv, &value)) + return 0; + if (value < 0) { + option_error("maxconnect time must be positive"); + return 0; + } + if (maxconnect > 0 && (value == 0 || value > maxconnect)) { + option_error("maxconnect time cannot be increased"); + return 0; + } + maxconnect = value; + return 1; + } + + /* + * setdomain - Set domain name to append to hostname + */ + static int + setdomain(argv) + char **argv; + { + if (!privileged_option) { + option_error("using the domain option requires root privilege"); + return 0; + } + gethostname(hostname, MAXNAMELEN); + if (**argv != 0) { + if (**argv != '.') + strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); + strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); + } + hostname[MAXNAMELEN-1] = 0; + return (1); + } + + + /* + * setasyncmap - add bits to asyncmap (what we request peer to escape). + */ + static int + setasyncmap(argv) + char **argv; + { + u_int32_t asyncmap; + + if (!number_option(*argv, &asyncmap, 16)) + return 0; + lcp_wantoptions[0].asyncmap |= asyncmap; + lcp_wantoptions[0].neg_asyncmap = 1; + return(1); + } + + + /* + * setescape - add chars to the set we escape on transmission. + */ + static int + setescape(argv) + char **argv; + { + int n, ret; + char *p, *endp; + + p = *argv; + ret = 1; + while (*p) { + n = strtol(p, &endp, 16); + if (p == endp) { + option_error("escape parameter contains invalid hex number '%s'", + p); + return 0; + } + p = endp; + if (n < 0 || (0x20 <= n && n <= 0x3F) || n == 0x5E || n > 0xFF) { + option_error("can't escape character 0x%x", n); + ret = 0; + } else + xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); + while (*p == ',' || *p == ' ') + ++p; + } + return ret; + } + + + /* + * setspeed - Set the speed. + */ + static int + setspeed(arg) + char *arg; + { + char *ptr; + int spd; + + spd = strtol(arg, &ptr, 0); + if (ptr == arg || *ptr != 0 || spd == 0) + return 0; + inspeed = spd; + return 1; + } + + + /* + * setdevname - Set the device name. + */ + static int + setdevname(cp, quiet) + char *cp; + int quiet; + { + struct stat statbuf; + char dev[MAXPATHLEN]; + + if (*cp == 0) + return 0; + + if (strncmp("/dev/", cp, 5) != 0) { + strcpy(dev, "/dev/"); + strncat(dev, cp, MAXPATHLEN - 5); + dev[MAXPATHLEN-1] = 0; + cp = dev; + } + + /* + * Check if there is a device by this name. + */ + if (stat(cp, &statbuf) < 0) { + if (errno == ENOENT || quiet) + return 0; + option_error("Couldn't stat %s: %m", cp); + return -1; + } + + (void) strncpy(devnam, cp, MAXPATHLEN); + devnam[MAXPATHLEN-1] = 0; + default_device = FALSE; + devnam_info.priv = privileged_option; + devnam_info.source = option_source; + + return 1; + } + + + /* + * setipaddr - Set the IP address + */ + static int + setipaddr(arg) + char *arg; + { + struct hostent *hp; + char *colon; + u_int32_t local, remote; + ipcp_options *wo = &ipcp_wantoptions[0]; + + /* + * IP address pair separated by ":". + */ + if ((colon = strchr(arg, ':')) == NULL) + return 0; + + /* + * If colon first character, then no local addr. + */ + if (colon != arg) { + *colon = '\0'; + if ((local = inet_addr(arg)) == -1) { + if ((hp = gethostbyname(arg)) == NULL) { + option_error("unknown host: %s", arg); + return -1; + } else { + local = *(u_int32_t *)hp->h_addr; + } + } + if (bad_ip_adrs(local)) { + option_error("bad local IP address %s", ip_ntoa(local)); + return -1; + } + if (local != 0) + wo->ouraddr = local; + *colon = ':'; + } + + /* + * If colon last character, then no remote addr. + */ + if (*++colon != '\0') { + if ((remote = inet_addr(colon)) == -1) { + if ((hp = gethostbyname(colon)) == NULL) { + option_error("unknown host: %s", colon); + return -1; + } else { + remote = *(u_int32_t *)hp->h_addr; + if (remote_name[0] == 0) { + strncpy(remote_name, colon, MAXNAMELEN); + remote_name[MAXNAMELEN-1] = 0; + } + } + } + if (bad_ip_adrs(remote)) { + option_error("bad remote IP address %s", ip_ntoa(remote)); + return -1; + } + if (remote != 0) + wo->hisaddr = remote; + } + + return 1; + } + + + /* + * setnoipdflt - disable setipdefault() + */ + static int + setnoipdflt(argv) + char **argv; + { + disable_defaultip = 1; + return 1; + } + + + /* + * setipcpaccl - accept peer's idea of our address + */ + static int + setipcpaccl(argv) + char **argv; + { + ipcp_wantoptions[0].accept_local = 1; + return 1; + } + + + static int setradius (argv) + char **argv; + { + useradius = 1; + return radius_init(*argv); + } + + /* + * setipcpaccr - accept peer's idea of its address + */ + static int + setipcpaccr(argv) + char **argv; + { + ipcp_wantoptions[0].accept_remote = 1; + return 1; + } + + + /* + * setnetmask - set the netmask to be used on the interface. + */ + static int + setnetmask(argv) + char **argv; + { + u_int32_t mask, b; + int n, ok; + char *p, *endp; + + /* + * Unfortunately, if we use inet_addr, we can't tell whether + * a result of all 1s is an error or a valid 255.255.255.255. + */ + p = *argv; + ok = 0; + mask = 0; + for (n = 3;; --n) { + b = strtoul(p, &endp, 0); + if (endp == p) + break; + if (b < 0 || b > 255) { + if (n == 3) { + /* accept e.g. 0xffffff00 */ + p = endp; + mask = b; + } + break; + } + mask |= b << (n * 8); + p = endp; + if (*p != '.' || n == 0) + break; + ++p; + } + + mask = htonl(mask); + + if (*p != 0 || (netmask & ~mask) != 0) { + option_error("invalid netmask value '%s'", *argv); + return 0; + } + + netmask = mask; + return (1); + } + + static int + setcrtscts(argv) + char **argv; + { + crtscts = 1; + return (1); + } + + static int + setnocrtscts(argv) + char **argv; + { + crtscts = -1; + return (1); + } + + static int + setxonxoff(argv) + char **argv; + { + lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ + lcp_wantoptions[0].neg_asyncmap = 1; + + crtscts = -2; + return (1); + } + + static int + setnodetach(argv) + char **argv; + { + nodetach = 1; + return (1); + } + + static int + setupdetach(argv) + char **argv; + { + nodetach = -1; + return (1); + } + + static int + setdemand(argv) + char **argv; + { + demand = 1; + persist = 1; + return 1; + } + + static int + setmodem(argv) + char **argv; + { + modem = 1; + return 1; + } + + static int + setlocal(argv) + char **argv; + { + modem = 0; + return 1; + } + + static int + setlock(argv) + char **argv; + { + lockflag = 1; + return 1; + } + + static int + setusehostname(argv) + char **argv; + { + usehostname = 1; + return 1; + } + + static int + setname(argv) + char **argv; + { + if (!privileged_option) { + option_error("using the name option requires root privilege"); + return 0; + } + strncpy(our_name, argv[0], MAXNAMELEN); + our_name[MAXNAMELEN-1] = 0; + return 1; + } + + static int + setuser(argv) + char **argv; + { + strncpy(user, argv[0], MAXNAMELEN); + user[MAXNAMELEN-1] = 0; + return 1; + } + + static int + setremote(argv) + char **argv; + { + strncpy(remote_name, argv[0], MAXNAMELEN); + remote_name[MAXNAMELEN-1] = 0; + return 1; + } + + static int + setauth(argv) + char **argv; + { + auth_required = 1; + if (privileged_option > auth_req_info.priv) { + auth_req_info.priv = privileged_option; + auth_req_info.source = option_source; + } + return 1; + } + + static int + setnoauth(argv) + char **argv; + { + if (auth_required && privileged_option < auth_req_info.priv) { + option_error("cannot override auth option set by %s", + auth_req_info.source); + return 0; + } + auth_required = 0; + return 1; + } + + static int + setdefaultroute(argv) + char **argv; + { + if (!ipcp_allowoptions[0].default_route) { + option_error("defaultroute option is disabled"); + return 0; + } + ipcp_wantoptions[0].default_route = 1; + return 1; + } + + static int + setnodefaultroute(argv) + char **argv; + { + ipcp_allowoptions[0].default_route = 0; + ipcp_wantoptions[0].default_route = 0; + return 1; + } + + static int + setproxyarp(argv) + char **argv; + { + if (!ipcp_allowoptions[0].proxy_arp) { + option_error("proxyarp option is disabled"); + return 0; + } + ipcp_wantoptions[0].proxy_arp = 1; + return 1; + } + + static int + setnoproxyarp(argv) + char **argv; + { + ipcp_wantoptions[0].proxy_arp = 0; + ipcp_allowoptions[0].proxy_arp = 0; + return 1; + } + + static int + setpersist(argv) + char **argv; + { + persist = 1; + return 1; + } + + static int + setnopersist(argv) + char **argv; + { + persist = 0; + return 1; + } + + static int + setdologin(argv) + char **argv; + { + uselogin = 1; + return 1; + } + + /* + * Functions to set the echo interval for modem-less monitors + */ + + static int + setlcpechointv(argv) + char **argv; + { + return int_option(*argv, &lcp_echo_interval); + } + + static int + setlcpechofails(argv) + char **argv; + { + return int_option(*argv, &lcp_echo_fails); + } + + /* + * Functions to set timeouts, max transmits, etc. + */ + static int + setlcptimeout(argv) + char **argv; + { + return int_option(*argv, &lcp_fsm[0].timeouttime); + } + + static int + setlcpterm(argv) + char **argv; + { + return int_option(*argv, &lcp_fsm[0].maxtermtransmits); + } + + static int + setlcpconf(argv) + char **argv; + { + return int_option(*argv, &lcp_fsm[0].maxconfreqtransmits); + } + + static int + setlcpfails(argv) + char **argv; + { + return int_option(*argv, &lcp_fsm[0].maxnakloops); + } + + static int + setipcptimeout(argv) + char **argv; + { + return int_option(*argv, &ipcp_fsm[0].timeouttime); + } + + static int + setipcpterm(argv) + char **argv; + { + return int_option(*argv, &ipcp_fsm[0].maxtermtransmits); + } + + static int + setipcpconf(argv) + char **argv; + { + return int_option(*argv, &ipcp_fsm[0].maxconfreqtransmits); + } + + static int + setipcpfails(argv) + char **argv; + { + return int_option(*argv, &lcp_fsm[0].maxnakloops); + } + + static int + setpaptimeout(argv) + char **argv; + { + return int_option(*argv, &upap[0].us_timeouttime); + } + + static int + setpapreqtime(argv) + char **argv; + { + return int_option(*argv, &upap[0].us_reqtimeout); + } + + static int + setpapreqs(argv) + char **argv; + { + return int_option(*argv, &upap[0].us_maxtransmits); + } + + static int + setchaptimeout(argv) + char **argv; + { + return int_option(*argv, &chap[0].timeouttime); + } + + static int + setchapchal(argv) + char **argv; + { + return int_option(*argv, &chap[0].max_transmits); + } + + static int + setchapintv(argv) + char **argv; + { + return int_option(*argv, &chap[0].chal_interval); + } + + static int + noccp(argv) + char **argv; + { + ccp_protent.enabled_flag = 0; + return 1; + } + + static int + setbsdcomp(argv) + char **argv; + { + int rbits, abits; + char *str, *endp; + + str = *argv; + abits = rbits = strtol(str, &endp, 0); + if (endp != str && *endp == ',') { + str = endp + 1; + abits = strtol(str, &endp, 0); + } + if (*endp != 0 || endp == str) { + option_error("invalid parameter '%s' for bsdcomp option", *argv); + return 0; + } + if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) + || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) { + option_error("bsdcomp option values must be 0 or %d .. %d", + BSD_MIN_BITS, BSD_MAX_BITS); + return 0; + } + if (rbits > 0) { + ccp_wantoptions[0].bsd_compress = 1; + ccp_wantoptions[0].bsd_bits = rbits; + } else + ccp_wantoptions[0].bsd_compress = 0; + if (abits > 0) { + ccp_allowoptions[0].bsd_compress = 1; + ccp_allowoptions[0].bsd_bits = abits; + } else + ccp_allowoptions[0].bsd_compress = 0; + return 1; + } + + static int + setnobsdcomp(argv) + char **argv; + { + ccp_wantoptions[0].bsd_compress = 0; + ccp_allowoptions[0].bsd_compress = 0; + return 1; + } + + static int + setdeflate(argv) + char **argv; + { + int rbits, abits; + char *str, *endp; + + str = *argv; + abits = rbits = strtol(str, &endp, 0); + if (endp != str && *endp == ',') { + str = endp + 1; + abits = strtol(str, &endp, 0); + } + if (*endp != 0 || endp == str) { + option_error("invalid parameter '%s' for deflate option", *argv); + return 0; + } + if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)) + || (abits != 0 && (abits < DEFLATE_MIN_SIZE + || abits > DEFLATE_MAX_SIZE))) { + option_error("deflate option values must be 0 or %d .. %d", + DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); + return 0; + } + if (rbits > 0) { + ccp_wantoptions[0].deflate = 1; + ccp_wantoptions[0].deflate_size = rbits; + } else + ccp_wantoptions[0].deflate = 0; + if (abits > 0) { + ccp_allowoptions[0].deflate = 1; + ccp_allowoptions[0].deflate_size = abits; + } else + ccp_allowoptions[0].deflate = 0; + return 1; + } + + static int + setnodeflate(argv) + char **argv; + { + ccp_wantoptions[0].deflate = 0; + ccp_allowoptions[0].deflate = 0; + return 1; + } + + static int + setnodeflatedraft(argv) + char **argv; + { + ccp_wantoptions[0].deflate_draft = 0; + ccp_allowoptions[0].deflate_draft = 0; + return 1; + } + + static int + setpred1comp(argv) + char **argv; + { + ccp_wantoptions[0].predictor_1 = 1; + ccp_allowoptions[0].predictor_1 = 1; + return 1; + } + + static int + setnopred1comp(argv) + char **argv; + { + ccp_wantoptions[0].predictor_1 = 0; + ccp_allowoptions[0].predictor_1 = 0; + return 1; + } + + static int + setipparam(argv) + char **argv; + { + ipparam = strdup(*argv); + if (ipparam == NULL) + novm("ipparam string"); + + return 1; + } + + static int + setpapcrypt(argv) + char **argv; + { + cryptpap = 1; + return 1; + } + + static int + setidle(argv) + char **argv; + { + return int_option(*argv, &idle_time_limit); + } + + static int + setholdoff(argv) + char **argv; + { + return int_option(*argv, &holdoff); + } + + /* + * setdnsaddr - set the dns address(es) + */ + static int + setdnsaddr(argv) + char **argv; + { + u_int32_t dns; + struct hostent *hp; + + dns = inet_addr(*argv); + if (dns == -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-dns option", + *argv); + return 0; + } + dns = *(u_int32_t *)hp->h_addr; + } + + /* if there is no primary then update it. */ + if (ipcp_allowoptions[0].dnsaddr[0] == 0) + ipcp_allowoptions[0].dnsaddr[0] = dns; + + /* always set the secondary address value to the same value. */ + ipcp_allowoptions[0].dnsaddr[1] = dns; + + return (1); + } + + /* + * setwinsaddr - set the wins address(es) + * This is primrarly used with the Samba package under UNIX or for pointing + * the caller to the existing WINS server on a Windows NT platform. + */ + static int + setwinsaddr(argv) + char **argv; + { + u_int32_t wins; + struct hostent *hp; + + wins = inet_addr(*argv); + if (wins == -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-wins option", + *argv); + return 0; + } + wins = *(u_int32_t *)hp->h_addr; + } + + /* if there is no primary then update it. */ + if (ipcp_allowoptions[0].winsaddr[0] == 0) + ipcp_allowoptions[0].winsaddr[0] = wins; + + /* always set the secondary address value to the same value. */ + ipcp_allowoptions[0].winsaddr[1] = wins; + + return (1); + } + + #ifdef IPX_CHANGE + static int + setipxrouter (argv) + char **argv; + { + ipxcp_wantoptions[0].neg_router = 1; + ipxcp_allowoptions[0].neg_router = 1; + return int_option(*argv, &ipxcp_wantoptions[0].router); + } + + static int + setipxname (argv) + char **argv; + { + char *dest = ipxcp_wantoptions[0].name; + char *src = *argv; + int count; + char ch; + + ipxcp_wantoptions[0].neg_name = 1; + ipxcp_allowoptions[0].neg_name = 1; + memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name)); + + count = 0; + while (*src) { + ch = *src++; + if (! isalnum (ch) && ch != '_') { + option_error("IPX router name must be alphanumeric or _"); + return 0; + } + + if (count >= sizeof (ipxcp_wantoptions[0].name)) { + option_error("IPX router name is limited to %d characters", + sizeof (ipxcp_wantoptions[0].name) - 1); + return 0; + } + + dest[count++] = toupper (ch); + } + + return 1; + } + + static int + setipxcptimeout (argv) + char **argv; + { + return int_option(*argv, &ipxcp_fsm[0].timeouttime); + } + + static int + setipxcpterm (argv) + char **argv; + { + return int_option(*argv, &ipxcp_fsm[0].maxtermtransmits); + } + + static int + setipxcpconf (argv) + char **argv; + { + return int_option(*argv, &ipxcp_fsm[0].maxconfreqtransmits); + } + + static int + setipxcpfails (argv) + char **argv; + { + return int_option(*argv, &ipxcp_fsm[0].maxnakloops); + } + + static int + setipxnetwork(argv) + char **argv; + { + u_int32_t v; + + if (!number_option(*argv, &v, 16)) + return 0; + + ipxcp_wantoptions[0].our_network = (int) v; + ipxcp_wantoptions[0].neg_nn = 1; + return 1; + } + + static int + setipxanet(argv) + char **argv; + { + ipxcp_wantoptions[0].accept_network = 1; + ipxcp_allowoptions[0].accept_network = 1; + return 1; + } + + static int + setipxalcl(argv) + char **argv; + { + ipxcp_wantoptions[0].accept_local = 1; + ipxcp_allowoptions[0].accept_local = 1; + return 1; + } + + static int + setipxarmt(argv) + char **argv; + { + ipxcp_wantoptions[0].accept_remote = 1; + ipxcp_allowoptions[0].accept_remote = 1; + return 1; + } + + static u_char * + setipxnodevalue(src,dst) + u_char *src, *dst; + { + int indx; + int item; + + for (;;) { + if (!isxdigit (*src)) + break; + + for (indx = 0; indx < 5; ++indx) { + dst[indx] <<= 4; + dst[indx] |= (dst[indx + 1] >> 4) & 0x0F; + } + + item = toupper (*src) - '0'; + if (item > 9) + item -= 7; + + dst[5] = (dst[5] << 4) | item; + ++src; + } + return src; + } + + static int + setipxnode(argv) + char **argv; + { + char *end; + + memset (&ipxcp_wantoptions[0].our_node[0], 0, 6); + memset (&ipxcp_wantoptions[0].his_node[0], 0, 6); + + end = setipxnodevalue (*argv, &ipxcp_wantoptions[0].our_node[0]); + if (*end == ':') + end = setipxnodevalue (++end, &ipxcp_wantoptions[0].his_node[0]); + + if (*end == '\0') { + ipxcp_wantoptions[0].neg_node = 1; + return 1; + } + + option_error("invalid parameter '%s' for ipx-node option", *argv); + return 0; + } + + static int + setipxproto(argv) + char **argv; + { + ipxcp_protent.enabled_flag = 1; + return 1; + } + + static int + resetipxproto(argv) + char **argv; + { + ipxcp_protent.enabled_flag = 0; + return 1; + } + #else + + static int + resetipxproto(argv) + char **argv; + { + return 1; + } + #endif /* IPX_CHANGE */ + + #ifdef MSLANMAN + static int + setmslanman(argv) + char **argv; + { + ms_lanman = 1; + return (1); + } + #endif Binary files ppp-2.3.5/pppd/pppd.core and ppp-2.3.5-2cbcps-radius-multiport/pppd/pppd.core differ diff -r -P -d -C 3 ppp-2.3.5/pppd/pppd.h ppp-2.3.5-2cbcps-radius-multiport/pppd/pppd.h *** ppp-2.3.5/pppd/pppd.h Thu Mar 26 09:46:07 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/pppd.h Sun Jan 16 14:08:28 2000 *************** *** 79,84 **** --- 79,85 ---- extern int kdebugflag; /* Tell kernel to print debug messages */ extern int default_device; /* Using /dev/tty or equivalent */ extern char devnam[]; /* Device name */ + extern char staticdevnam[]; /* Reserv value - Device name */ extern int crtscts; /* Use hardware flow control */ extern int modem; /* Use modem control lines */ extern int inspeed; /* Input/Output speed requested */ *************** *** 86,91 **** --- 87,96 ---- 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 int useradius; /* Using RADIUS for authentication */ + extern int usemultiport; /* Use Multiport device (c) Ilya Ismailov, TTS, Tyumen, Russian*/ + extern int multiportfist; /* Fist Multiport device (c) Ilya Ismailov, TTS,Tyumen, Russian*/ + extern int multiportend; /* End Multiport device (c) Ilya Ismailov, TTS, Tyumen, Russian*/ extern char *disconnector; /* Script to disestablish physical link */ extern char *welcomer; /* Script to welcome client after connection */ extern int maxconnect; /* Maximum connect time (seconds) */ *************** *** 113,119 **** extern struct bpf_program pass_filter; /* Filter for pkts to pass */ extern struct bpf_program active_filter; /* Filter for link-active pkts */ #endif ! #ifdef MSLANMAN extern int ms_lanman; /* Nonzero if use LanMan password instead of NT */ --- 118,127 ---- extern struct bpf_program pass_filter; /* Filter for pkts to pass */ extern struct bpf_program active_filter; /* Filter for link-active pkts */ #endif ! extern char callerid[]; ! extern char calleridtool[]; ! extern char con_state[]; ! extern char con_tool[]; #ifdef MSLANMAN extern int ms_lanman; /* Nonzero if use LanMan password instead of NT */ *************** *** 414,428 **** #define DEBUGCHAP 1 #endif - #ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */ - #if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \ - || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \ - || defined(DEBUGCHAP) || defined(DEBUG) #define LOG_PPP LOG_LOCAL2 - #else - #define LOG_PPP LOG_DAEMON - #endif - #endif /* LOG_PPP */ #ifdef DEBUGMAIN #define MAINDEBUG(x) if (debug) syslog x --- 422,428 ---- diff -r -P -d -C 3 ppp-2.3.5/pppd/pppd.h.orig ppp-2.3.5-2cbcps-radius-multiport/pppd/pppd.h.orig *** ppp-2.3.5/pppd/pppd.h.orig Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/pppd.h.orig Thu Aug 19 15:19:10 1999 *************** *** 0 **** --- 1,486 ---- + /* + * 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.21 1998/03/26 04:46:08 paulus Exp $ + */ + + /* + * TODO: + */ + + #ifndef __PPPD_H__ + #define __PPPD_H__ + + #include /* for FILE */ + #include /* for MAXPATHLEN and BSD4_4, if defined */ + #include /* for u_int32_t, if defined */ + #include /* for struct timeval */ + #include + + #if __STDC__ + #include + #define __V(x) x + #else + #include + #define __V(x) (va_alist) va_dcl + #define const + #endif + + /* + * Limits. + */ + + #define NUM_PPP 1 /* One PPP interface supported (per process) */ + #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 int hungup; /* Physical layer has disconnected */ + extern int ifunit; /* Interface unit number */ + extern char ifname[]; /* Interface name */ + extern int ttyfd; /* Serial device file descriptor */ + extern char hostname[]; /* Our hostname */ + extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ + extern int phase; /* Current state of link - see values below */ + extern int baud_rate; /* Current link speed in bits/sec */ + extern char *progname; /* Name of this program */ + extern int redirect_stderr;/* Connector's stderr should go to file */ + extern char peer_authname[];/* Authenticated name of peer */ + extern int privileged; /* We were run by real-uid root */ + extern int need_holdoff; /* Need holdoff period after link terminates */ + extern char **script_env; /* Environment variables for scripts */ + extern int detached; /* Have detached from controlling tty */ + + /* + * Variables set by command-line options. + */ + + extern int debug; /* Debug flag */ + extern int kdebugflag; /* Tell kernel to print debug messages */ + extern int default_device; /* Using /dev/tty or equivalent */ + extern char devnam[]; /* Device name */ + 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 int useradius; /* Using RADIUS for authentication */ + extern char *disconnector; /* Script to disestablish physical link */ + extern char *welcomer; /* Script to welcome client after connection */ + extern int maxconnect; /* Maximum connect time (seconds) */ + extern char user[]; /* Our name for authenticating ourselves */ + 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 explicit_remote;/* remote_name specified with remotename opt */ + extern int usehostname; /* Use hostname for our_name */ + extern int disable_defaultip; /* Don't use hostname for default IP adrs */ + extern int demand; /* Do dial-on-demand */ + extern char *ipparam; /* Extra parameter for ip up/down scripts */ + extern int cryptpap; /* Others' PAP passwords are encrypted */ + extern int idle_time_limit;/* Shut down link if idle for this long */ + extern int holdoff; /* Dead time before restarting */ + extern int refuse_pap; /* Don't wanna auth. ourselves with PAP */ + extern int refuse_chap; /* Don't wanna auth. ourselves with CHAP */ + #ifdef PPP_FILTER + extern struct bpf_program pass_filter; /* Filter for pkts to pass */ + extern struct bpf_program active_filter; /* Filter for link-active pkts */ + #endif + extern char callerid[]; + extern char calleridtool[]; + extern char con_state[]; + extern char con_tool[]; + + #ifdef MSLANMAN + extern int ms_lanman; /* Nonzero if use LanMan password instead of NT */ + /* Has meaning only with MS-CHAP challenges */ + #endif + + /* + * Values for phase. + */ + #define PHASE_DEAD 0 + #define PHASE_INITIALIZE 1 + #define PHASE_DORMANT 2 + #define PHASE_ESTABLISH 3 + #define PHASE_AUTHENTICATE 4 + #define PHASE_CALLBACK 5 + #define PHASE_NETWORK 6 + #define PHASE_TERMINATE 7 + #define PHASE_HOLDOFF 8 + + /* + * 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. + */ + + /* Procedures exported from main.c. */ + void detach __P((void)); /* Detach from controlling tty */ + void die __P((int)); /* Cleanup and exit */ + void quit __P((void)); /* like die(1) */ + void novm __P((char *)); /* Say we ran out of memory, and die */ + void timeout __P((void (*func)(void *), void *arg, int t)); + /* Call func(arg) after t seconds */ + void untimeout __P((void (*func)(void *), void *arg)); + /* Cancel call to func(arg) */ + int run_program __P((char *prog, char **args, int must_exist)); + /* Run program prog with args in child */ + void demuxprotrej __P((int, int)); + /* Demultiplex a Protocol-Reject */ + void format_packet __P((u_char *, int, void (*) (void *, char *, ...), + void *)); /* Format a packet in human-readable form */ + void log_packet __P((u_char *, int, char *, int)); + /* Format a packet and log it with syslog */ + void print_string __P((char *, int, void (*) (void *, char *, ...), + void *)); /* Format a string for output */ + int fmtmsg __P((char *, int, char *, ...)); /* sprintf++ */ + int vfmtmsg __P((char *, int, char *, va_list)); /* vsprintf++ */ + void script_setenv __P((char *, char *)); /* set script env var */ + void script_unsetenv __P((char *)); /* unset script env var */ + + /* Procedures exported from auth.c */ + void link_required __P((int)); /* we are starting to use the link */ + void link_terminated __P((int)); /* we are finished with the link */ + void link_down __P((int)); /* the LCP layer has left the Opened state */ + void link_established __P((int)); /* the link is up; authenticate now */ + void np_up __P((int, int)); /* a network protocol has come up */ + void np_down __P((int, int)); /* a network protocol has gone down */ + void np_finished __P((int, int)); /* a network protocol no longer needs link */ + void auth_peer_fail __P((int, int)); + /* peer failed to authenticate itself */ + void auth_peer_success __P((int, int, char *, int)); + /* peer successfully authenticated itself */ + void auth_withpeer_fail __P((int, int)); + /* we failed to authenticate ourselves */ + void auth_withpeer_success __P((int, int)); + /* we successfully authenticated ourselves */ + void auth_check_options __P((void)); + /* check authentication options supplied */ + void auth_reset __P((int)); /* check what secrets we have */ + 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 */ + int auth_ip_addr __P((int, u_int32_t)); + /* check if IP address is authorized */ + int bad_ip_adrs __P((u_int32_t)); + /* check if IP address is unreasonable */ + void check_access __P((FILE *, char *)); + /* check permissions on secrets file */ + + /* Procedures exported from demand.c */ + void demand_conf __P((void)); /* config interface(s) for demand-dial */ + void demand_block __P((void)); /* set all NPs to queue up packets */ + void demand_unblock __P((void)); /* set all NPs to pass packets */ + void demand_discard __P((void)); /* set all NPs to discard packets */ + void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ + int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ + int loop_frame __P((unsigned char *, int)); /* process frame from loopback */ + + /* Procedures exported from sys-*.c */ + void sys_init __P((void)); /* Do system-dependent initialization */ + void sys_cleanup __P((void)); /* Restore system state before exiting */ + void sys_check_options __P((void)); /* Check options specified */ + void sys_close __P((void)); /* Clean up in a child before execing */ + int ppp_available __P((void)); /* Test whether ppp kernel support exists */ + void open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */ + void establish_ppp __P((int)); /* Turn serial port into a ppp interface */ + void restore_loop __P((void)); /* Transfer ppp unit back to loopback */ + void disestablish_ppp __P((int)); /* Restore port to normal operation */ + void clean_check __P((void)); /* Check if line was 8-bit clean */ + void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */ + void restore_tty __P((int)); /* Restore port's original parameters */ + void setdtr __P((int, int)); /* Raise or lower port's DTR line */ + void output __P((int, u_char *, int)); /* Output a PPP packet */ + void wait_input __P((struct timeval *)); + /* Wait for input, with timeout */ + void wait_loop_output __P((struct timeval *)); + /* Wait for pkt from loopback, with timeout */ + void wait_time __P((struct timeval *)); /* Wait for given length of time */ + int read_packet __P((u_char *)); /* Read PPP packet */ + int get_loop_output __P((void)); /* Read pkts from loopback */ + void ppp_send_config __P((int, int, u_int32_t, int, int)); + /* Configure i/f transmit parameters */ + void ppp_set_xaccm __P((int, ext_accm)); + /* Set extended transmit ACCM */ + void ppp_recv_config __P((int, int, u_int32_t, int, int)); + /* Configure i/f receive parameters */ + int ccp_test __P((int, u_char *, int, int)); + /* Test support for compression scheme */ + void ccp_flags_set __P((int, int, int)); + /* Set kernel CCP state */ + int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */ + int get_idle_time __P((int, struct ppp_idle *)); + /* Find out how long link has been idle */ + int sifvjcomp __P((int, int, int, int)); + /* Configure VJ TCP header compression */ + int sifup __P((int)); /* Configure i/f up (for IP) */ + int sifnpmode __P((int u, int proto, enum NPmode mode)); + /* Set mode for handling packets for proto */ + int sifdown __P((int)); /* Configure i/f down (for IP) */ + int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t)); + /* Configure IP addresses for i/f */ + int cifaddr __P((int, u_int32_t, u_int32_t)); + /* Reset i/f IP addresses */ + int sifdefaultroute __P((int, u_int32_t, u_int32_t)); + /* Create default route through i/f */ + int cifdefaultroute __P((int, u_int32_t, u_int32_t)); + /* Delete default route through i/f */ + int sifproxyarp __P((int, u_int32_t)); + /* Add proxy ARP entry for peer */ + int cifproxyarp __P((int, u_int32_t)); + /* Delete proxy ARP entry for peer */ + u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ + int lock __P((char *)); /* Create lock file for device */ + void unlock __P((void)); /* Delete previously-created lock file */ + int daemon __P((int, int)); /* Detach us from terminal session */ + void logwtmp __P((const char *, const char *, const char *)); + /* Write entry to wtmp file */ + int get_host_seed __P((void)); /* Get host-dependent random number seed */ + #ifdef PPP_FILTER + int set_filters __P((struct bpf_program *pass, struct bpf_program *active)); + /* Set filter programs in kernel */ + #endif + + /* Procedures exported from options.c */ + int parse_args __P((int argc, char **argv)); + /* Parse options from arguments given */ + void usage __P((void)); /* Print a usage message */ + int options_from_file __P((char *filename, int must_exist, int check_prot, + int privileged)); + /* Parse options from an options file */ + int options_from_user __P((void)); /* Parse options from user's .ppprc */ + int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */ + void scan_args __P((int argc, char **argv)); + /* Look for tty name in command-line args */ + int getword __P((FILE *f, char *word, int *newlinep, char *filename)); + /* Read a word from a file */ + void option_error __P((char *fmt, ...)); + /* Print an error message about an option */ + + /* + * 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 DEBUGUPAP 1 + #define DEBUGCHAP 1 + #endif + + #define LOG_PPP LOG_LOCAL2 + + #ifdef DEBUGMAIN + #define MAINDEBUG(x) if (debug) syslog x + #else + #define MAINDEBUG(x) + #endif + + #ifdef DEBUGSYS + #define SYSDEBUG(x) if (debug) syslog x + #else + #define SYSDEBUG(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 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 + + #ifdef DEBUGIPXCP + #define IPXCPDEBUG(x) if (debug) syslog x + #else + #define IPXCPDEBUG(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__ */ diff -r -P -d -C 3 ppp-2.3.5/pppd/pppdradius.c ppp-2.3.5-2cbcps-radius-multiport/pppd/pppdradius.c *** ppp-2.3.5/pppd/pppdradius.c Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/pppdradius.c Mon Aug 16 11:22:31 1999 *************** *** 0 **** --- 1,155 ---- + /* Copyright (c) 1997 Cyril A. Vechera St.-Petersburg, RUSSIA + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 4. Any form of use of source and binaries are permitted only for + * noncommercial purpose. Any forms of commercial usage require + * direct author's permission. + */ + + #include + #include + #include + #include + #include + #include + + #include "fsm.h" + #include "ipcp.h" + #include "lcp.h" + #include "pppd.h" + #include "upap.h" + #include "libradius.h" + #include "pppdradius.h" + + char rad_user[16] = "\0"; + u_long rad_port = 0; + u_long rad_address = 0L; + u_long rad_netmask = 0L; + u_long rad_mtu = 0L; + u_long rad_vj = 0L; + int radlogged_in = 0; + + extern int cbcp_volit; + + int radlogin (char *name, char *passwd) + { + int err,i; + u_long *radppp_address; + u_long *radppp_netmask; + u_long *radppp_mtu; + u_long *radppp_vj; + struct stat s; + struct utmp utmp; + char *tty; + + strncpy (rad_user, name, 16); + radppp_address = &rad_address; + radppp_netmask = &rad_netmask; + radppp_mtu = &rad_mtu; + radppp_vj = &rad_vj; + + if (fstat (ttyfd, &s)) + s.st_rdev = 0; + rad_port = (major(s.st_rdev) << 12) | (minor(s.st_rdev) & 0x0fff); + + err = radius_request_ppp_PAP (rad_user, passwd, rad_port, &radppp_address, + &radppp_netmask, &radppp_mtu, &radppp_vj); + + syslog(LOG_WARNING,"RADIUS auth passed: err %d",err); + if (!err) /* if authenticated successfully - start accounting */ + { + radius_session_start_time = time(NULL); + + /* session id - nas-ip-address + tty-device + pid + time */ + sprintf(radius_session_id, "%s %s [%u] %s", + inet_ntoa (radius_me.sin_addr), + devname (s.st_rdev, S_IFCHR), + getpid(), + ctime(&radius_session_start_time)); + + radius_account_start (rad_user, rad_port); + syslog(LOG_WARNING,"RADIUS accounting started: err %d",err); + } + + switch (err) + { + case RADLIB_ACCESS_DENIED: + syslog(LOG_WARNING, "radlogin: access denied for user %s\n", name); + break; + case RADLIB_NO_RESPONSE: + syslog(LOG_ALERT, "radlogin: server doesn't respond\n"); + break; + case RADLIB_BAD_ID: + syslog(LOG_ERR, "radlogin: bad response identifier\n"); + break; + case RADLIB_BAD_AUTH: + syslog(LOG_ERR, "radlogin: server's response authentication failure\n"); + break; + case RADLIB_BAD_CODE: + syslog(LOG_ERR, "radlogin: bad response code\n"); + break; + } + + if (err) + return UPAP_AUTHNAK; + + radlogged_in = 1; + + if (radppp_netmask) + { + memcpy (&netmask, radppp_netmask, 4); + syslog (LOG_DEBUG, "RADIUS netmask: %lx\n",netmask); + } + + if (radppp_address) + { + memcpy (&ipcp_allowoptions[0].hisaddr, radppp_address, 4); + memcpy (&ipcp_wantoptions[0].hisaddr, radppp_address, 4); + syslog (LOG_DEBUG, "RADIUS address: %lx\n", ipcp_wantoptions[0].hisaddr); + } + tty = devnam; + if (strncmp(tty, "/dev/", 5) == 0) + tty += 5; + for(i=0;i + *************** + *** 135,140 **** + --- 136,143 ---- + return; + if (logged_in) + ppplogout(); + + if (radlogged_in) + + radlogout(); + phase = PHASE_DEAD; + syslog(LOG_NOTICE, "Connection terminated."); + } + *************** + *** 331,337 **** + */ + if (ao->neg_upap && passwd[0] == 0 && !get_upap_passwd()) + ao->neg_upap = 0; + ! if (wo->neg_upap && !uselogin && !have_upap_secret()) + wo->neg_upap = 0; + if (ao->neg_chap && !have_chap_secret(our_name, remote_name)) + ao->neg_chap = 0; + --- 334,340 ---- + */ + if (ao->neg_upap && passwd[0] == 0 && !get_upap_passwd()) + ao->neg_upap = 0; + ! if (wo->neg_upap && !uselogin && !useradius && !have_upap_secret()) + wo->neg_upap = 0; + if (ao->neg_chap && !have_chap_secret(our_name, remote_name)) + ao->neg_chap = 0; + *************** + *** 395,401 **** + ret = UPAP_AUTHACK; + f = fopen(filename, "r"); + if (f == NULL) { + ! if (!uselogin) { + syslog(LOG_ERR, "Can't open upap password file %s: %m", filename); + ret = UPAP_AUTHNAK; + } + --- 398,404 ---- + ret = UPAP_AUTHACK; + f = fopen(filename, "r"); + if (f == NULL) { + ! if (!(uselogin || useradius)) { + syslog(LOG_ERR, "Can't open upap password file %s: %m", filename); + ret = UPAP_AUTHNAK; + } + *************** + *** 417,422 **** + --- 420,439 ---- + syslog(LOG_WARNING, "upap login failure for %s", user); + } + } + + + + if (useradius) + + #ifdef RPPPD_DEBUG + + { + + int ret; + + #else + + if (ret == UPAP_AUTHNAK) + + { + + #endif + + ret = radlogin(user, passwd); + + if (ret == UPAP_AUTHNAK) { + + syslog(LOG_WARNING, "upap radius login failure for %s", user); + + } + + } + + if (ret == UPAP_AUTHNAK) { + *msg = "Login incorrect"; + Only in pppd: config.sample + Only in pppd: libradius.c + Only in pppd: libradius.h + Only in pppd: md5.c + Only in pppd: md5.h + diff -r -c /usr/src/usr.sbin/pppd/options.c pppd/options.c + *** /usr/src/usr.sbin/pppd/options.c Sun Aug 11 21:29:34 1996 + --- pppd/options.c Tue Aug 19 20:38:48 1997 + *************** + *** 91,96 **** + --- 91,97 ---- + int disable_defaultip = 0; /* Don't use hostname for default IP adrs */ + char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ + int cryptpap; /* Passwords in pap-secrets are encrypted */ + + int useradius = 0; + + #ifdef _linux_ + int idle_time_limit = 0; + *************** + *** 173,178 **** + --- 174,180 ---- + static int setnobsdcomp __P((void)); + static int setipparam __P((char **)); + static int setpapcrypt __P((void)); + + static int setradius __P((char **)); + + static int number_option __P((char *, u_int32_t *, int)); + static int readable __P((int fd)); + *************** + *** 262,267 **** + --- 264,270 ---- + {"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */ + {"ipparam", 1, setipparam}, /* set ip script parameter */ + {"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */ + + {"radius", 1, setradius}, + #ifdef _linux_ + {"idle-disconnect", 1, setidle}, /* seconds for disconnect of idle IP */ + #endif + *************** + *** 1791,1793 **** + --- 1794,1803 ---- + return int_option(*argv, &idle_time_limit); + } + #endif + + + + static int setradius (argv) + + char **argv; + + { + + useradius = 1; + + return radius_init(*argv); + + } + diff -r -c /usr/src/usr.sbin/pppd/pppd.h pppd/pppd.h + *** /usr/src/usr.sbin/pppd/pppd.h Sun Aug 11 21:29:37 1996 + --- pppd/pppd.h Tue Aug 19 20:39:57 1997 + *************** + *** 88,93 **** + --- 88,94 ---- + 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 */ + + extern int useradius; /* Using RADIUS for authentication */ + + /* + * Values for phase. + Only in pppd: pppdradius.c + Only in pppd: pppdradius.h + Only in pppd: radius.h diff -r -P -d -C 3 ppp-2.3.5/pppd/radius.h ppp-2.3.5-2cbcps-radius-multiport/pppd/radius.h *** ppp-2.3.5/pppd/radius.h Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/radius.h Sun Jan 24 14:36:50 1999 *************** *** 0 **** --- 1,329 ---- + + #define COMMENT '#' /* comment char for config files */ + + #define AUTH_VECTOR_LEN 16 + #define AUTH_PASS_LEN 16 + #define AUTH_ID_LEN 64 + #define AUTH_STRING_LEN 128 /* maximum of 253 */ + + #define FILTER_LEN 16 + #define NAME_LENGTH 32 + + #define AUTH_HDR_LEN 20 + #define MAX_SECRET_LENGTH 16 + #define CHAP_VALUE_LENGTH 16 + + #define PW_AUTH_UDP_PORT 1645 + #define PW_ACCT_UDP_PORT 1646 + + #define PW_TYPE_STRING 0 + #define PW_TYPE_INTEGER 1 + #define PW_TYPE_IPADDR 2 + #define PW_TYPE_DATE 3 + + /* standard RADIUS codes */ + + #define PW_ACCESS_REQUEST 1 + #define PW_ACCESS_ACCEPT 2 + #define PW_ACCESS_REJECT 3 + #define PW_ACCOUNTING_REQUEST 4 + #define PW_ACCOUNTING_RESPONSE 5 + #define PW_ACCOUNTING_STATUS 6 + #define PW_PASSWORD_REQUEST 7 + #define PW_PASSWORD_ACK 8 + #define PW_PASSWORD_REJECT 9 + #define PW_ACCOUNTING_MESSAGE 10 + #define PW_ACCESS_CHALLENGE 11 + #define PW_STATUS_SERVER 12 + #define PW_STATUS_CLIENT 13 + + + /* standard RADIUS attribute-value pairs */ + + #define PW_USER_NAME 1 /* string */ + #define PW_USER_PASSWORD 2 /* string */ + #define PW_CHAP_PASSWORD 3 /* string */ + #define PW_NAS_IP_ADDRESS 4 /* ipaddr */ + #define PW_NAS_PORT 5 /* integer */ + #define PW_SERVICE_TYPE 6 /* integer */ + #define PW_FRAMED_PROTOCOL 7 /* integer */ + #define PW_FRAMED_IP_ADDRESS 8 /* ipaddr */ + #define PW_FRAMED_IP_NETMASK 9 /* ipaddr */ + #define PW_FRAMED_ROUTING 10 /* integer */ + #define PW_FILTER_ID 11 /* string */ + #define PW_FRAMED_MTU 12 /* integer */ + #define PW_FRAMED_COMPRESSION 13 /* integer */ + #define PW_LOGIN_IP_HOST 14 /* ipaddr */ + #define PW_LOGIN_SERVICE 15 /* integer */ + #define PW_LOGIN_PORT 16 /* integer */ + #define PW_OLD_PASSWORD 17 /* string */ /* deprecated */ + #define PW_REPLY_MESSAGE 18 /* string */ + #define PW_LOGIN_CALLBACK_NUMBER 19 /* string */ + #define PW_FRAMED_CALLBACK_ID 20 /* string */ + #define PW_EXPIRATION 21 /* date */ /* deprecated */ + #define PW_FRAMED_ROUTE 22 /* string */ + #define PW_FRAMED_IPX_NETWORK 23 /* integer */ + #define PW_STATE 24 /* string */ + #define PW_CLASS 25 /* string */ + #define PW_VENDOR_SPECIFIC 26 /* string */ + #define PW_SESSION_TIMEOUT 27 /* integer */ + #define PW_IDLE_TIMEOUT 28 /* integer */ + #define PW_TERMINATION_ACTION 29 /* integer */ + #define PW_CALLED_STATION_ID 30 /* string */ + #define PW_CALLING_STATION_ID 31 /* string */ + #define PW_NAS_IDENTIFIER 32 /* string */ + #define PW_PROXY_STATE 33 /* string */ + #define PW_LOGIN_LAT_SERVICE 34 /* string */ + #define PW_LOGIN_LAT_NODE 35 /* string */ + #define PW_LOGIN_LAT_GROUP 36 /* string */ + #define PW_FRAMED_APPLETALK_LINK 37 /* integer */ + #define PW_FRAMED_APPLETALK_NETWORK 38 /* integer */ + #define PW_FRAMED_APPLETALK_ZONE 39 /* string */ + #define PW_CHAP_CHALLENGE 60 /* string */ + #define PW_NAS_PORT_TYPE 61 /* integer */ + #define PW_PORT_LIMIT 62 /* integer */ + + /* Accounting */ + + #define PW_ACCT_STATUS_TYPE 40 /* integer */ + #define PW_ACCT_DELAY_TIME 41 /* integer */ + #define PW_ACCT_INPUT_OCTETS 42 /* integer */ /* not impl. */ + #define PW_ACCT_OUTPUT_OCTETS 43 /* integer */ /* not impl. */ + #define PW_ACCT_SESSION_ID 44 /* string */ + #define PW_ACCT_AUTHENTIC 45 /* integer */ + #define PW_ACCT_SESSION_TIME 46 /* integer */ + #define PW_ACCT_INPUT_PACKETS 47 /* integer */ /* not impl. */ + #define PW_ACCT_OUTPUT_PACKETS 48 /* integer */ /* not impl. */ + #define PW_ACCT_TERMINATE_CAUSE 49 /* integer */ + + /* Merit Experimental Extensions */ + + #define PW_AVAILABLE_TIME 209 /* integer */ + #define PW_INFO_PORT 210 /* integer */ + #define PW_PROXY_ACTION 211 /* string */ + #define PW_SIGNATURE 212 /* string */ + #define PW_TOKEN 213 /* string */ + #define PW_ACCT_RATE 214 /* string */ + #define PW_ACCT_CHARGE 215 /* string */ + #define PW_ACCT_TRANSACTION_ID 216 /* string */ + #define PW_ACCT_CHARGE_ALLOWED 217 /* string */ + #define PW_MAXIMUM_TIME 218 /* integer */ + /* #define unavailable due to collision 219 */ /* ??????? */ + #define PW_TIME_USED 220 /* integer */ + #define PW_HUNTGROUP_NAME 221 /* string */ + #define PW_USER_ID 222 /* string */ + #define PW_USER_REALM 223 /* string */ + + /* Configuration Only Attributes (for check-items) */ + + #define CI_COMMENT 1024 /* string */ + #define CI_XVALUE 1025 /* integer */ + #define CI_XSTRING 1026 /* string */ + #define CI_AUTHENTICATION_TYPE 1027 /* integer */ + #define CI_PROHIBIT 1028 /* integer */ + #define CI_USER_CATEGORY 1029 /* string */ + #define CI_GROUP_NAME 1030 /* string */ + #define CI_ENCRYPTED_PASSWORD 1031 /* string */ + #define CI_EXPIRATION 1032 /* date */ + #define CI_USER_PASSWORD 1033 /* string */ + #define CI_SIMULTANEOUS_USE 1034 /* integer */ + #define CI_SERVER_NAME 1035 /* string */ + + /* Integer Translations */ + + /* SERVICE TYPES */ + + #define PW_LOGIN 1 + #define PW_FRAMED 2 + #define PW_CALLBACK_LOGIN 3 + #define PW_CALLBACK_FRAMED 4 + #define PW_OUTBOUND_USER 5 + #define PW_ADMINISTRATIVE_USER 6 + #define PW_SHELL_USER 7 + #define PW_AUTHENTICATE_ONLY 8 + #define PW_CALLBACK_ADMIN_USER 9 + + /* FRAMED PROTOCOLS */ + + #define PW_PPP 1 + #define PW_SLIP 2 + + /* FRAMED ROUTING VALUES */ + + #define PW_NONE 0 + #define PW_BROADCAST 1 + #define PW_LISTEN 2 + #define PW_BROADCAST_LISTEN 3 + + /* FRAMED COMPRESSION TYPES */ + + #define PW_VAN_JACOBSON_TCP_IP 1 + #define PW_IPX_HEADER_COMPRESSION 2 + + /* LOGIN SERVICES */ + + #define PW_TELNET 0 + #define PW_RLOGIN 1 + #define PW_TCP_CLEAR 2 + #define PW_PORTMASTER 3 + #define PW_LAT 4 + + /* TERMINATION ACTIONS */ + + #define PW_DEFAULT 0 + #define PW_RADIUS_REQUEST 1 + + /* AUTHENTICATION TYPES */ + + #define AA_NONE 0 /* This is not a valid user id entry */ + #define AA_UNIX 1 /* Use local Unix password file */ + #define AA_AKRB 2 /* AFS Kerberos type authentication */ + #define AA_MKRB 3 /* MIT Kerberos type authentication */ + #define AA_RAD 4 /* Pass to remote RADIUS server */ + #define AA_MNET 5 /* Do Merit specific authentication */ + #define AA_KCHAP 6 /* Kerberos CHAP authentication */ + #define AA_TACACS 7 /* Encrypted TACACS authentication */ + #define AA_REALM 8 /* Find given realm in authfile */ + #define AA_LOCAL 9 + #define AA_FILE 10 /* ID/PW list in a file */ + + #define PW_AUTH_MAX 10 /* Highest authentication type */ + + /* PROHIBIT PROTOCOL */ + + #define PW_DUMB 0 /* 1 and 2 are defined in FRAMED PROTOCOLS */ + #define PW_AUTH_ONLY 3 + #define PW_ALL 255 + + /* ACCOUNTING STATUS TYPES */ + + #define PW_STATUS_START 1 + #define PW_STATUS_STOP 2 + #define PW_STATUS_ALIVE 3 + #define PW_STATUS_MODEM_START 4 + #define PW_STATUS_MODEM_STOP 5 + #define PW_STATUS_CANCEL 6 + #define PW_ACCOUNTING_ON 7 + #define PW_ACCOUNTING_OFF 8 + + /* ACCOUNTING TERMINATION CAUSES */ + + #define PW_USER_REQUEST 1 + #define PW_LOST_CARRIER 2 + #define PW_LOST_SERVICE 3 + #define PW_ACCT_IDLE_TIMEOUT 4 + #define PW_ACCT_SESSION_TIMEOUT 5 + #define PW_ADMIN_RESET 6 + #define PW_ADMIN_REBOOT 7 + #define PW_PORT_ERROR 8 + #define PW_NAS_ERROR 9 + #define PW_NAS_REQUEST 10 + #define PW_NAS_REBOOT 11 + #define PW_PORT_UNNEEDED 12 + #define PW_PORT_PREEMPTED 13 + #define PW_PORT_SUSPENDED 14 + #define PW_SERVICE_UNAVAILABLE 15 + #define PW_CALLBACK 16 + + /* NAS PORT TYPES */ + + #define PW_ASYNC 0 + #define PW_SYNC 1 + #define PW_ISDN_SYNC 2 + #define PW_ISDN_SYNC_V120 3 + #define PW_ISDN_SYNC_V110 4 + + /* Default Database File Names */ + + #ifndef RADIUS_DIR + #define RADIUS_DIR "/usr/local/etc/raddb" + #endif + + #ifndef RADACCT_DIR + #define RADACCT_DIR "/usr/local/etc/radacct" + #endif + + /* + * Note: To change where these files go, do not change the #defines + * below, instead change the RADIUS_DIR #define above. + */ + + #define RADIUS_DICTIONARY "dictionary" + #define RADIUS_CLIENTS "clients" + #define RADIUS_USERS "users" + #define RADIUS_HOLD "holdusers" + #define RADIUS_LOG "logfile" + #define RADIUS_AUTH "authfile" + #define RADIUS_PID "radiusd.pid" + #define RADIUS_FSM "radius.fsm" + #define RADIUS_DEBUG "radius.debug" + + #ifndef RADIUS_COMPRESS + #define RADIUS_COMPRESS "/usr/ucb/compress" /* might be gzip, etc. */ + #endif + + #ifndef RADIUS_LOCALSERVER + #define RADIUS_LOCALSERVER "localserver" + #endif + + #ifndef DEFAULT_REALM + #define DEFAULT_REALM "DEFAULT" + #endif + + #ifndef NULL_REALM + #define NULL_REALM "NULL" + #endif + + + /****************************************************************** + * + * PW_PROTTYPE & PW_PROTTYPES - define authentication protocol allowed + * for particular realm entry in authfile. + * + * The PW_PROTTYPE value is stored in the auth_ent.prot field. + * The PW_PROTTYPE value corresponds to the order of PW_PROTTYPES. + * + *****************************************************************/ + + #define PW_PROTTYPE_DFLT 0 /* Use this entry for any protocol */ + #define PW_PROTTYPE_CHAP 1 /* Entry is for CHAP style authent. */ + #define PW_PROTTYPE_PW 2 /* Entry is for id/pw style authent. */ + + #define PW_PROTTYPES_DFLT "DEFAULT" + #define PW_PROTTYPES_CHAP "CHAP" + #define PW_PROTTYPES_PW "PW" + + #ifndef LOG_CONS + #define LOG_DAEMON 0 + #define LOG_AUTH 0 + #endif + + #define MGMT_POLL_SECRET "Hardlyasecret" + #define MAX_REQUESTS 128 + #define MAX_REQUEST_TIME 30 /* Lifetime of a request */ + #define CLEANUP_DELAY 5 /* Hold onto old requests this long */ + #define DEFAULT_INETD_TIMEOUT 15 /* Fifteen minutes by default */ + #define DEFAULT_TIMER_VALUE 3 /* Three seconds by default */ + #define ADDRESS_AGING 60*60 /* One hour by default */ + #define DFLT_TACACS_UDP_PORT 49 /* Default TACACS server port */ + #define SESS_ID_LEN 8 /* session id length */ + #define SECONDS_PER_DAY 86400 + #define TRUNCATION_DAY 7 /* Sunday is zero (0), daily is seven (7) */ + + #ifndef PROTO + #ifdef __STDC__ + #define PROTO(x) x + #else + #define PROTO(x) () + #undef const + #endif /* !__STDC__ */ + #endif /* !PROTO */ + + /* Define event structure (for events generated by AATV action functions */ + + + #define AA_DIRECT 0 /* Function gives direct reply */ + #define AA_SOCKET 1 /* Deferred reply returned on socket */ + #define AA_FORK 2 /* Spawn a process to wait for reply */ + #define AA_FREPLY 3 /* Fork & get reply on server socket */ + diff -r -P -d -C 3 ppp-2.3.5/pppd/sys-linux.c ppp-2.3.5-2cbcps-radius-multiport/pppd/sys-linux.c *** ppp-2.3.5/pppd/sys-linux.c Mon May 4 12:45:00 1998 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/sys-linux.c Sun Jan 24 14:36:50 1999 *************** *** 19,24 **** --- 19,25 ---- */ #include + #include #include #include #include *************** *** 64,70 **** #include #include ! #include #include #include --- 65,71 ---- #include #include ! /*#include */ #include #include *************** *** 596,601 **** --- 597,608 ---- #endif #ifdef EXTB { 38400, EXTB }, + #endif + #ifdef B230400 + { 230400, B230400 }, + #endif + #ifdef B460800 + { 460800, B460800 }, #endif #ifdef B230400 { 230400, B230400 }, diff -r -P -d -C 3 ppp-2.3.5/pppd/testchap.c ppp-2.3.5-2cbcps-radius-multiport/pppd/testchap.c *** ppp-2.3.5/pppd/testchap.c Thu Jan 1 05:00:00 1970 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/testchap.c Sun Jan 24 14:36:49 1999 *************** *** 0 **** --- 1,41 ---- + #include + + #include "pppd.h" + #include "chap.h" + #include "chap_ms.h" + + int main(argc, argv) + int argc; + char *argv[]; + { + u_char challenge[8]; + int challengeInt[sizeof(challenge)]; + chap_state cstate; + int i; + + if (argc != 3) { + fprintf(stderr, "Usage: %s <16-hexchar challenge> \n", + argv[0]); exit(1); + } + + sscanf(argv[1], "%2x%2x%2x%2x%2x%2x%2x%2x", + challengeInt + 0, challengeInt + 1, challengeInt + 2, + challengeInt + 3, challengeInt + 4, challengeInt + 5, + challengeInt + 6, challengeInt + 7); + + for (i = 0; i < sizeof(challenge); i++) + challenge[i] = (u_char)challengeInt[i]; + + ChapMS(&cstate, challenge, sizeof(challenge), argv[2], strlen(argv[2])); + printf("Response length is %d, response is:", cstate.resp_length); + + for (i = 0; i < cstate.resp_length; i++) { + if (i % 8 == 0) + putchar('\n'); + printf("%02X ", (unsigned int)cstate.response[i]); + } + + putchar('\n'); + + exit(0); + } diff -r -P -d -C 3 ppp-2.3.5/pppd/upap.c ppp-2.3.5-2cbcps-radius-multiport/pppd/upap.c *** ppp-2.3.5/pppd/upap.c Wed Apr 30 11:59:56 1997 --- ppp-2.3.5-2cbcps-radius-multiport/pppd/upap.c Sun Jan 24 14:36:49 1999 *************** *** 44,49 **** --- 44,50 ---- static void upap_protrej __P((int)); static int upap_printpkt __P((u_char *, int, void (*) __P((void *, char *, ...)), void *)); + extern int cbcp_volit; struct protent pap_protent = { PPP_PAP, *************** *** 389,394 **** --- 390,396 ---- if (retcode == UPAP_AUTHACK) { u->us_serverstate = UPAPSS_OPEN; auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen); + syslog(LOG_ERR,"upap: user is %s, volit=%d\n",user,cbcp_volit); } else { u->us_serverstate = UPAPSS_BADAUTH; auth_peer_fail(u->us_unit, PPP_PAP);