portslave-2010.04.19.1/0000775000000000000000000000000012051676525011167 5ustar portslave-2010.04.19.1/changelog0000664000000000000000000006527112051676525013054 0ustar portslave (2010.04.19.1ubuntu1) raring; urgency=low * Merge from Debian unstable (LP: #1079649). Remaining changes: - Link library with -lcrypt to fix FTBFS. -- Vibhav Pant Fri, 16 Nov 2012 17:39:28 +0530 portslave (2010.04.19.1) unstable; urgency=high * Needs to be recompiled to work with the wheezy pppd. High urgency because it currently entirely fails to work. Closes: #679603 -- Russell Coker Sat, 30 Jun 2012 17:05:33 +1000 portslave (2010.04.19ubuntu1) precise; urgency=low * Link library with -lcrypt to fix FTBFS. -- Ilya Barygin Sat, 31 Dec 2011 11:50:01 +0400 portslave (2010.04.19) unstable; urgency=low * Fixed the "clean" target, should now build on other architectures. -- Russell Coker Mon, 19 Apr 2010 07:25:43 +1000 portslave (2010.03.30) unstable; urgency=low * Update Debhelper compatability to 7. * Don't needlessly link against libcrypt. * Remove postinst code to handle pre-lenny config file upgrades. Closes: #553290 * Built against the latest ppp package. Closes: #473080 * s/it's/its/ in description. Closes: #435680, #268539 * Don't depend on xutils. Closes: #575854 * Fixed all bugs, it's in use and important to some people, let's keep it in Debian. Closes: #559254 -- Russell Coker Tue, 30 Mar 2010 11:21:00 +1100 portslave (2005.04.03.1) unstable; urgency=high * Rebuild to work with the latest pppd. -- Russell Coker Thu, 31 Jul 2008 22:27:41 +1000 portslave (2005.04.03) unstable; urgency=high * Renamed the logcheck config file from portslave.pppd to portslave-pppd to fit with the new naming convention. * Made it build with the latest ppp. -- Russell Coker Sun, 4 Apr 2005 23:40:00 +1000 portslave (2004.03.26) unstable; urgency=low * Build-depends on ppp-dev. Closes: #240156 * Changed the version number as reported by the programs. * Note that the previous version totally disabled CHAP support (the previous changelog entry did not clearly state this). -- Russell Coker Fri, 26 Mar 2004 12:53:00 +1100 portslave (2004.03.21) unstable; urgency=low * Added an option to disable chap as the latest Debian ppp package has changed the CHAP hooks and I can't work out how to get it going again. -- Russell Coker Sun, 21 Mar 2004 22:37:00 +1100 portslave (2002.10.21) unstable; urgency=low * Fixed a bug in ./configure . -- Russell Coker Mon, 21 Oct 2002 06:39:00 +0200 portslave (2002.10.16) unstable; urgency=low * Added support for limiting the answer times. -- Russell Coker Wed, 16 Oct 2002 23:04:00 +0200 portslave (2002.09.17) unstable; urgency=low * New version that depends on libradius1. * Made "ssh" refer to version 2, and "ssh1" be the keyword for ssh V 1.x. * Fixed many trivial warnings about function parameters not being used. * Merged in FIDO support - haven't tested it yet. Author: Andy Pershin Adapted for recent versions by Dmitry Sergienko * Made rlogin use options "-8" and "-E". * Added CHAP support. -- Russell Coker Tue, 17 Sep 2002 00:24:00 +0200 portslave (2002.01.19) unstable; urgency=low * Added "%M" for multilink pppd option. * More changes related to removing support for ppp 2.4.0. -- Russell Coker Sat, 19 Jan 2002 16:33:00 +0100 portslave (2002.01.12) unstable; urgency=low * Remove support for ppp 2.4.0. -- Russell Coker Sat, 12 Jan 2002 21:02:00 +0100 portslave (2002.01.10) unstable; urgency=low * Made it not SEGV when DNS is down. * Changed some variable names to work with the next version of pppd. -- Russell Coker Thu, 10 Jan 2002 21:40:00 +0100 portslave (2001.12.28) unstable; urgency=low * Improved support for setting variables in chat script. -- Russell Coker Fri, 28 Dec 2001 00:10:00 +0100 portslave (2001.12.27) unstable; urgency=low * Added CLI support and changed the way that the initchat is parsed. This breaks old pslave.conf files. * Fixed a bug in ctlportslave so that it will clear old data from memory before displaying the logged on users (necessary for "cshow who"). * Stopped it using spaces in the Acct-Session-Id attribute. -- Russell Coker Thu, 27 Dec 2001 02:10:00 +0100 portslave (2001.12.16) unstable; urgency=low * Tidied up the debian/rules file. * Made it compile with older headers for the sockaddr_in code if you don't enable IPv6. * Made it compile with ppp*.tgz in the current directory as well as in the parent directory. * Fixed the callback patch. It compiles now - I can't test it though... * Added a patch to create potato packages to the docs directory. -- Russell Coker Sun, 16 Dec 2001 14:36:00 +0100 portslave (2001.12.11-1) unstable; urgency=low * Made the programs have the right version number. * Made it depend on the latest ppp Debian package. -- Russell Coker Tue, 11 Dec 2001 11:35:00 +0100 portslave (2001.12.11) unstable; urgency=low * Made the Acct-Session-Id aqttribute be sent in access-request packets as well as accounting. This may make it easier for some people to manage accounting. Made the Acct-Session-Id by default be the system time in seconds * 64K + the low 16bits of the PID in hex. Previously the decimal representation of the PID was merely appended to the decimal representation of the time, this meant that more space was taken up, and the session ids didn't always increase. * Added logcheck files. * Fixed a bug in ctlportslave that caused a buffer overflow on utmp parsing and a SEGV. -- Russell Coker Tue, 11 Dec 2001 10:38:00 +0100 portslave (2001.11.25) unstable; urgency=low * Added a patch from Cyclades for shadow password support. Also added support for MD5 hashed passwords. * Stopped warnings when unused port definitions reference non-existant devices. * Added a real bool type to the source. Makes the code clearer. * Started work on CID. * Added support for gethostbyname2() for IPv6. Not fully tested but works better than the previous code that broke gethostbyname() for IPv4. -- Russell Coker Sun, 25 Nov 2001 13:11:00 +0100 portslave (2001.11.18) unstable; urgency=low * Forced to change the syntax of hostname-service type for IPv6 support. Now use [a.b.c.d]port format. * IPv6 might even work. I have it sending RADIUS packets to ::1, now I need an IPv6 RADIUS server... -- Russell Coker Sun, 18 Nov 2001 21:45:00 +0100 portslave (2001.11.17) unstable; urgency=low * Made location an enum type. * Made the Debian package depend on the latest woody version. * Stopped the double messages about authentication failure. * Added a pppd patch for persistant IPv6 addresses. * Started work on IPv6 support. Use ./configure --enable-ipv6 to compile with it. It currently doesn't compile with IPv6 enabled... * Changed the parsing code to remove the remnants of the old way of doing it. Makes the code more readable. -- Russell Coker Sat, 17 Nov 2001 18:37:00 +0100 portslave (2001.11.11) unstable; urgency=low * Added new config directive for DCD related setting "%d". * Fixed a bug with rlogin/ssh where Portslave tried to connect to 0.0.0.0. -- Russell Coker Sun, 11 Nov 2001 20:18:00 +0100 portslave (2001.11.08) unstable; urgency=low * Adds more serial error checking and streamlined the default config file. * Made the default config file not allow locallogins! Also made the logging clearer. * The last version was broken badly, it never asked as a password (so any account with a password was unusable ;). Also ports were always recognised as port 0 for "portslave -" and by libpsr. It was only a development release anyway. * Made the error message be displayed on authentication failure, and fixed a potential SEGV in the failure message code. * Synchronised the patches with the latest Debian package. -- Russell Coker Thu, 8 Nov 2001 18:31:00 +0100 portslave (2001.11.05) unstable; urgency=low * Ran flawchecker to check for potential security problems. Now use /dev/urandom for random authentication vectors. Also tightened up some potentially nasty code in syslog.c and ctlportslave. The /dev/urandom change fixes a potential attack, the others just prevent SEGVs. * Added a ./configure option for enabling the IP address assignment. Also fixed a couple of minor IP assignment related bugs that crept in when merging the patch. * Removed README.NET and moved the data into portslave(8). * Merged in more code from Cyclades. * Made "s{32-63}.tty tts/C{0-31}" be a valid type of config syntax. -- Russell Coker Mon, 5 Nov 2001 20:03:00 +0100 portslave (2001.11.01) unstable; urgency=low * Started adding TACACS support. * Finished merging the callback support. Run "./configure --enable-callback" to compile it in. I haven't tested it though. * Changed the way patches are applied so the compile will abort immidiately if a patch fails. -- Russell Coker Thu, 1 Nov 2001 17:01:00 +0100 portslave (2001.10.29) unstable; urgency=low * Partial merge of Callback patch from Alexandr D. Kanevskiy . Also added some other minor patched from him. * Merge of IP assignment patch (forgot who that came from - sorry), disabled by default. I haven't tested enabling this! * Made a Framed-Route with a mask of /32 mean "route add -host" instead of "route add -net". Now we can have single IPs in framed routes. * Removed the ./configure option for the number of ports. Make it work with an arbitary large number of ports. NB ctlportslave will run out of memory if you use too high numbers... * Made ctlportslave not display idle ports. Also added an option for continuously updating the display. -- Russell Coker Mon, 29 Oct 2001 17:38:00 +0200 portslave (2001.10.26) unstable; urgency=low * Fix the RADIUS timeout code, made it try both servers in turn, not try server 0.0.0.0, and display the error messages correctly. * Fixed some buggy handling of error messages that could cause SEGV. -- Russell Coker Fri, 26 Oct 2001 22:53:00 +0200 portslave (2001.10.15) unstable; urgency=low * I broke accounting in 2001.10.09, fixed now. This also fixes a problem with utmp writing. It seems that if do_acct is set to false then the utmp record will have the IP address from pslave.conf even if that IP address was over-ruled by the RADIUS server! * Fixed utmpfrom in the default config documentation. Also made the variable in the source consistant with the config file so I don't make that mistake again. * Documented the environment variables used by portslave. -- Russell Coker Mon, 15 Oct 2001 01:18:00 +0200 portslave (2001.10.13) unstable; urgency=low * Improved the error reporting for DNS problems. * Fixed a parsing bug where unexpected tabs confused it. * Fixed a bug in the .spec file. -- Russell Coker Sat, 13 Oct 2001 19:01:00 +0200 portslave (2001.10.09) unstable; urgency=low * Removed some code from the memory management patch that's supposed to be buggy. * Reformatted the code slightly. * Fixed the .spec file to match the removal of the libpsr directory and the creation of an extra shared object. -- Russell Coker Tue, 9 Oct 2001 20:57:00 +0200 portslave (2001.10.06) unstable; urgency=low * Huge changes with this version, needs lots of testing!!! * Removed pppd-radius from the Debian package! Made it use the regular pppd. * Merged in the Cyclades code for local authentication and stub code for TACACS (anyone got some TACACS client code to share with me?). * Added %g to the formatting strings for printing the PID and %H for the target host for login sessions. * Rewrote the error handling for RADIUS packet creation and re-formatted radclient.c. Also added a config option to specify the number of RADIUS retries. * Ignore break on serial port when doing modem negotiation and login prompt. * Added port number specification for telnet service. * Replaced all sleep() and usleep() calls with nanosleep(). * Replaced the ppp 2.4.1 patches with the patches from the Debian pppd package. The Debian package had all our patches and some extras so it makes sense to track them. This also included some callback code! * Implemented the Login-TCP-Port attribute, now need code for MPPP limiting. * Stopped ssh and rlogin from disabling escape character (leave it disabled for telnet because telnet allows "open" command). * Removed hacks supporting Linux kernel < 2.2.0. It should still work on old kernels, just not display stats properly for ppp. * Added new config parameter "radretries". * Made the start time be calculated from RADIUS login time for terminal authentication (used to be from ip-up time). * Removed the libpsr directory and moved the contents to src directory. * Updated to latest debian standards version and follow the latest Debian policy on stripping and debug generation. -- Russell Coker Sat, 6 Oct 2001 19:32:38 +0200 portslave (2001.10.02) unstable; urgency=low * Removed spurious "Detected login for" syslog message on AutoPPP. * Changed ctlportslave code for detecting idle time. Now if it can't open the device it will display idle time as -1. This makes it less painful to run ctlportslave as non-root. * Made ctlportslave not display entries where the process as listed in utmp does not exist. * Updated the default-config document to include the facility and change to the new format of config file. * Changed the default initchat script to use "\c" instead of "" for null send strings. * Merged in a small amount of code from portslave-new. Added location parameter (currently always 0 and unused), also added some new logging for ssh and ssh2. Should be no functional differences because of this, just easier for me to manage my code and easier to add new features in the next release... * Updated chat.c and rwconf.c to new code standards and added better error reporting. * Fixed the Debian config file upgrade code to not match on comments. * Made the default permissions of the config file deny world read. * Finally fixed all the autoconf variable substitution issues. * Made it work with more than one abort string in initchat (previously only the first would work). -- Russell Coker Tue, 2 Oct 2001 18:37:50 +0200 portslave (2001.09.09) unstable; urgency=low * Changed the version number to use dots instead of dashes because too many programs do strange things with dashes in version numbers. * Changed the ./configure script to fix some problems with directories. -- Russell Coker Sun, 09 Sep 2001 13:21:48 +0200 portslave (2001-08-30) unstable; urgency=low * Make it build properly on Debian. Closes: #110627 -- Russell Coker Thu, 30 Aug 2001 15:41:00 +0200 portslave (2001-08-22) unstable; urgency=low * Minor addition to pslave.conf(5) and Debian packaging. * Wrote upgrade script for Debian to convert the format of the config file. -- Russell Coker Wed, 22 Aug 2001 22:02:07 +0200 portslave (2001-08-17) unstable; urgency=low * Changed the configuration in a serious way. Made "all." and "conf." be synonyms (this makes it possible to set every parameter on a per-port basis). As part of this I changed conf.ipno to all.loc_host and all.ipno to all.rem_host. * Updated the documentation and removed some obsolete stuff. * Added new autoconf code based on the work of T. M. Pederson. * Made the number of ports a config option with default 256. * Changed the user-name and password max lengths to 64. * Made many more pointers const in radclient.c. * Removed debian/conffiles because we use DH_COMPAT=3 and it's automatic. * Added a +config-file option to Portslave to allow different ports to have different config files. This is not as necessary as it used to be now that every option can be set on a per-port basis, but will be handy for upgrades. * Added config options for parity, stop-bits, and bits per byte (default 8N1). * Restructured the getty code. * Fixed a config file parsing bug when running "portslave -" with a tty that's not in the config file. * Made failure to lock /var/run/radius.id a fatal error. -- Russell Coker Fri, 17 Aug 2001 01:45:12 +0200 portslave (2001-07-13) unstable; urgency=low * Added the conf.stripnames feature. * Fixed a bug in dynamic ip address (IP address spec ending in '+') parsing. * Now adds framed-route entries AFTER IP is brought up for PAP logins. * Made the chat-script code take up to 126 strings (was 62). * Added the "ABORT" keyword to chat scripts. -- Russell Coker Fri, 13 Jul 2001 15:48:15 +0200 portslave (2001-07-12) unstable; urgency=low * Minor fix to the man page. * Made the Debian package include pppd source. -- Russell Coker Thu, 12 Jul 2001 14:34:52 +0200 portslave (2001-07-11) unstable; urgency=low * Fixed a potential SEGV if you only define the secondary RADIUS server. * Made the config file case-insensitive for key words (still case sensitive for device names etc naturally). * Made the porttype setting an enum. -- Russell Coker Wed, 11 Jul 2001 14:30:16 +0200 portslave (2001-07-10) unstable; urgency=low * Fixed a bug whereby the first line of the config file wouldn't be parsed correctly by libpsr.so. * Fixed a potential buffer overflow parsing radius packets (too many filters, messages, or routes). * Made ctlportslave take 1 character abbreviations for everything. * Made Framed-Route work with terminal authentication. Also added some error logging for when the route command returns an error, made it handle a gateway of 0.0.0.0, and handle no specification of metric. * Added a memory leak patch for pppd 2.4.1. -- Russell Coker Tue, 10 Jul 2001 12:25:47 +0200 portslave (2001-07-09) unstable; urgency=low * Rewrote all the config code to only have the configuration for the line in use in memory. Saves about 500K of resident RAM for each running copy of Portslave. * Removed some cruft from ctlportslave, cut the binary from 30K to 13K. * Changed the maximum number of lines to 1024 (was 512). Could make it larger if necessary. * Made pppd display the correct "started by user" message when using terminal authentication. * Fixed the logging code properly. * Added ppp packet counting (seriously hacking pppd). -- Russell Coker Mon, 9 Jul 2001 17:48:33 +0200 portslave (2001-07-08) unstable; urgency=low * Added per-line option for logging passwords to syslog. * Changed the syslog code to not log to the console all the time. * Documented the utmpfrom field in the config file and fixed the default. * Fixed a potential buffer overflow in ctlportslave (MAXLINES checking). * Did some more work on hacking syslog() and the debug code. Also made the debug config setting an integer not a boolean! * Now SPECIAL_STATUS honors the sysutmp config setting. * The pppopt and autoppp options must use the plugin. pppopt needs the plugin for accounting. * Stopped "make install" from creating a rc.boot directory. * For Debian make DH_COMPAT=3. -- Russell Coker Sun, 8 Jul 2001 18:24:38 +0200 portslave (2001-07-05) unstable; urgency=low * Added "make dep" support. * Added new code for de-referencing sym-links for device names. This will make locking work better regarding /dev/modem and /dev/ttyS* on devfs. Now we use absolute path names for all devices internally and strip the "/dev/" from the start before writing to utmp. -- Russell Coker Thu, 5 Jul 2001 16:10:53 +0200 portslave (2001-07-02) unstable; urgency=low * Added #include in syslog.c, needed for htonl() etc. * Added a .spec file for RPM, don't know if it works. * Added support for specifying port numbers for services. * Changed the accounting service name to "radius-acct" which is the official name (used to be "radacct"). * Changed the default port numbers (used if /etc/services doesn't contain entries for "radius" and "radius-acct") to 1812 and 1813 from 1645 and 1646. * Changed the variable PPPLOGNAME to PORTSLAVELOGNAME to avoid conflicts with the environment variable pppd sets named PPPLOGNAME. * Made it work with ppp-x.x.x.tar.gz * Changed the version number in the RPM spec file to not have hyphens. -- Russell Coker Mon, 2 Jul 2001 16:32:33 +0200 portslave (2001-06-28) unstable; urgency=low * ./configure now checks for the location of rlogin * Fixed the bug where it would send a bogus second accounting-start record. * Made it log bytes and packets sent and received in the accounting-end record (actually the pppd code is missing for packet accounting, but the portslave code is already there). * Re-added pppd 2.4.0 support and included the pppd memory leak patch from "Arthur Naseef" . * Fixed a config parsing bug that resulted in dynamic addresses being reversed. * Tweaked the syslog code some more. Now it logs way too much, which is better than not logging enough. * Fixed the spawn code so that it won't fork() for PPP protocol. * Chat now works! * Added all the docs to the Debian package. * Wrote ctlportslave(1) and documented the chat script format for pslave.conf(5). * Made ctlportslave take the option "q" to quit, saves typing. -- Russell Coker Thu, 28 Jun 2001 17:45:01 +0200 portslave (2001-06-27) unstable; urgency=low * Added some more comments and did some more work on the logging code. * Re-wrote the chat code to try and fix a stack corruption bug (and make the code readable and maintainable. * Added a patch from "Arthur Naseef" to fix memory leaks. * Fixed the shutdown code, so that on error portslave shouldn't ever hang on exit. * Moved rlogin into it's own separate package. -- Russell Coker Wed, 27 Jun 2001 17:16:45 +0200 portslave (2001-06-26) unstable; urgency=low * Added ppp_version to the symbol table for libpsr. * Fixed the logging code, it's not more consistant and the code makes more sense (to me at least). * Removed radinit, it wasn't serving any purpose, it's apparently been dead code for some time. * Audited all strcpy() code and used a few strncmp() calls and other changes to reduce the risk of buffer overflows. * Updated docs/TODO * Made all code compile with lots of gcc warnings turned on and fixed all the problems it reports! * No longer use -I../src on the compiler command line. * Copied some code from Portslave 2.0A, including the %S parameter for format strings (it's the same as our %T but we have both for compatibility). -- Russell Coker Tue, 26 Jun 2001 12:00:00 +0200 portslave (2001-06-24) unstable; urgency=low * Wrote portslave(8). -- Russell Coker Sun, 24 Jun 2001 21:55:42 +0200 portslave (2001-06-22) unstable; urgency=low * Made the integer scanning return error if sscanf() can't get exactly one value. * Added a proper bool type to configuration that accepts 0/no/false or 1/yes/true just like bools in samba, changed the default config file appropriately. * "make clean" will not longer remove pslave_cfg.h * Fixed the logging code to use the regular openlog() and syslog() library calls from libc for local logging instead of the broken AF_UNIX code that was being used before. This makes it work on recent 2.2 kernels. -- Russell Coker Fri, 22 Jun 2001 12:00:00 +0200 portslave (2001-06-21) unstable; urgency=low * Fix lock file generation to only use the last directory componant so it'll work with devfs style names. * Added the -i option to the rlogin.1 man page. * Wrote a man page for pslave.conf(5). * Made more values have sensible defaults. -- Russell Coker Thu, 21 Jun 2001 22:58:11 +0200 portslave (2001-06-20) unstable; urgency=low * Made the PPP source external to the main source for Portslave and made it apply patches from a patch directory. This will make it 100 times easier to migrate Portslave to a new version of PPPD and make it easy to compile the same version for different versions of PPPD. * Changed the macro VERSION to PORTSLAVE_VERSION to avoid conflicts. * Fixed the installation of man pages, amoung other things it won't install wrong man pages on Debian. -- Russell Coker Wed, 20 Jun 2001 12:00:00 +0200 portslave (2001-04-04) unstable; urgency=low * More work on accounting. -- Russell Coker Wed, 4 Apr 2001 14:04:45 +1000 portslave (2001-04-03) unstable; urgency=low * Adds a better description. Closes: #87397 * Changed MAXLINES from 256 to 512 (just in case 256 isn't enough). * Made the included pppd source closer to the upstream. -- Russell Coker Tue, 3 Apr 2001 14:04:45 +1000 portslave (2001-02-20) unstable; urgency=low * Changed spawnit to support up to 254 parameters when executing a program, it used to be 30. * Added accounting patch from "Alexandr D. Kanevskiy" to make it correctly send accounting packets on AutoPPP sessions. * Fixed a bunch of trivial warnings from not including system header files. -- Russell Coker Tue, 20 Feb 2001 10:29:37 +0100 portslave (2000-12-25) unstable; urgency=low * Fixed the version code. -- Russell Coker Mon, 25 Dec 2000 06:14:16 +1100 portslave (2000-12-24) unstable; urgency=low * Initial Release. -- Russell Coker Sun, 24 Dec 2000 09:57:47 +1100 Local variables: mode: debian-changelog End: portslave-2010.04.19.1/configure0000775000000000000000000043146711354242057013107 0ustar #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="src/lib.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS pppsourcedir bigutmp rlogin ssh telnet arp ifconfig route pppdir radclient_cfg rundir EGREP GREP shadow ipv6 no_local_ip assignment fido callback_patch callback stripping pppdradius RANLIB INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC version target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_pppdradius enable_stripping enable_debug enable_callback enable_fido enable_assignment enable_ipv6 enable_shadow with_rundir with_radclient_cfg ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error "unrecognized option: \`$ac_option' Try \`$0 --help' for more information." ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-stripping disables stripping of installed binaries --enable-debug enables debug code generation for binaries --enable-callback enables compilation of callback PPP code --enable-fido enables compilation of Fidonet support code --enable-assignment enables client assignment of IP addresses --enable-ipv6 enables IPv6 --enable-shadow enables shadow password support Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pppdradius=pathname specifies full path to pppd-radius $sbindir/pppd-radius --with-rundir=DIR specifies directory for pid files etc /var/run --with-radclient-cfg=file specifies default radclient config file Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_type # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu version="2010.03.30" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "no acceptable C compiler found in \$PATH See \`config.log' for more details." "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { as_fn_set_status 77 as_fn_error "C compiler cannot create executables See \`config.log' for more details." "$LINENO" 5; }; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of object files: cannot compile See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do for ac_t in install-sh install.sh shtool; do if test -f "$ac_dir/$ac_t"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/$ac_t -c" break 2 fi done done if test -z "$ac_aux_dir"; then as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi if [ "$prefix" = "NONE" ]; then prefix=$ac_default_prefix fi if [ "$exec_prefix" = "NONE" ]; then exec_prefix=$prefix fi if [ "$bindir" = "\${exec_prefix}/bin" ]; then bindir=$exec_prefix/bin fi if [ "$sbindir" = "\${exec_prefix}/sbin" ]; then sbindir=$exec_prefix/sbin fi if [ "$libdir" = "\${exec_prefix}/lib" ]; then libdir=$exec_prefix/lib fi if [ "$sysconfdir" = "\${prefix}/etc" ]; then if [ "$prefix" = "/usr" ]; then sysconfdir=/etc else sysconfdir=$prefix/etc fi fi # Check whether --with-pppdradius was given. if test "${with_pppdradius+set}" = set; then : withval=$with_pppdradius; pppdradius=$withval else pppdradius="$sbindir/pppd-radius" fi # Check whether --enable-stripping was given. if test "${enable_stripping+set}" = set; then : enableval=$enable_stripping; STRIPPING=$strippingval else STRIPPING=no fi if [ ! "$STRIPPING" = "no" ]; then stripping="" else stripping="-s" fi echo $DEB_BUILD_OPTIONS | grep -q nostrip if [ "$?" = "0" ]; then stripping="" fi # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; debug=-g else debug="" fi echo $DEB_BUILD_OPTIONS | grep -q debug if [ "$?" = "0" ]; then debug=-g fi # Check whether --enable-callback was given. if test "${enable_callback+set}" = set; then : enableval=$enable_callback; callback=y else callback="" fi if [ "$callback" = "y" ]; then callback="#define PORTSLAVE_CALLBACK" callback_patch=../patches/ppp-2.4.1-CBCPs.asp.patch fi # Check whether --enable-fido was given. if test "${enable_fido+set}" = set; then : enableval=$enable_fido; fido=y else fido="" fi if [ "$fido" = "y" ]; then fido="#define HAVE_FIDO" fi # Check whether --enable-assignment was given. if test "${enable_assignment+set}" = set; then : enableval=$enable_assignment; assignment=y else assignment="" fi if [ "$assignment" = "y" ]; then assignment="#define PORTSLAVE_CLIENT_IP_RULES" no_local_ip="#define ALLOW_NO_LOCAL_IP" fi # Check whether --enable-ipv6 was given. if test "${enable_ipv6+set}" = set; then : enableval=$enable_ipv6; ipv6=y else ipv6="" fi if [ "$ipv6" = "y" ]; then ipv6="#define HAVE_IPV6" fi # Check whether --enable-shadow was given. if test "${enable_shadow+set}" = set; then : enableval=$enable_shadow; shadow=y else shadow="" fi if [ "$shadow" = "y" ]; then shadow="#define HAS_SHADOW" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " eval as_val=\$$as_ac_Header if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # Check whether --with-rundir was given. if test "${with_rundir+set}" = set; then : withval=$with_rundir; rundir=$withval else rundir="/var/run" fi inst_libdir='${PREFIX}'$libdir # Check whether --with-radclient_cfg was given. if test "${with_radclient_cfg+set}" = set; then : withval=$with_radclient_cfg; radclient_cfg=$withval else radclient_cfg="$sysconfdir/radiusclient.conf" fi pppdir=ppp-2.4.1 # Extract the first word of ""route"", so it can be a program name with args. set dummy "route"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_route+set}" = set; then : $as_echo_n "(cached) " >&6 else case $route in [\\/]* | ?:[\\/]*) ac_cv_path_route="$route" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy=""$PATH:/sbin:/usr/sbin"" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_route="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_route" && ac_cv_path_route=""/sbin/route"" ;; esac fi route=$ac_cv_path_route if test -n "$route"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $route" >&5 $as_echo "$route" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of ""ifconfig"", so it can be a program name with args. set dummy "ifconfig"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_ifconfig+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ifconfig in [\\/]* | ?:[\\/]*) ac_cv_path_ifconfig="$ifconfig" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy=""$PATH:/sbin:/usr/sbin"" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ifconfig="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_ifconfig" && ac_cv_path_ifconfig=""/sbin/ifconfig"" ;; esac fi ifconfig=$ac_cv_path_ifconfig if test -n "$ifconfig"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ifconfig" >&5 $as_echo "$ifconfig" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of ""arp"", so it can be a program name with args. set dummy "arp"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_arp+set}" = set; then : $as_echo_n "(cached) " >&6 else case $arp in [\\/]* | ?:[\\/]*) ac_cv_path_arp="$arp" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy=""$PATH:/sbin:/usr/sbin"" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_arp="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_arp" && ac_cv_path_arp=""/usr/sbin/arp"" ;; esac fi arp=$ac_cv_path_arp if test -n "$arp"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $arp" >&5 $as_echo "$arp" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of ""telnet"", so it can be a program name with args. set dummy "telnet"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_telnet+set}" = set; then : $as_echo_n "(cached) " >&6 else case $telnet in [\\/]* | ?:[\\/]*) ac_cv_path_telnet="$telnet" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in "$PATH" do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_telnet="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_telnet" && ac_cv_path_telnet=""/usr/bin/telnet"" ;; esac fi telnet=$ac_cv_path_telnet if test -n "$telnet"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $telnet" >&5 $as_echo "$telnet" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of ""ssh"", so it can be a program name with args. set dummy "ssh"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_ssh+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ssh in [\\/]* | ?:[\\/]*) ac_cv_path_ssh="$ssh" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in "$PATH" do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ssh="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_ssh" && ac_cv_path_ssh=""/usr/bin/ssh"" ;; esac fi ssh=$ac_cv_path_ssh if test -n "$ssh"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssh" >&5 $as_echo "$ssh" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of ""rlogin"", so it can be a program name with args. set dummy "rlogin"; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_rlogin+set}" = set; then : $as_echo_n "(cached) " >&6 else case $rlogin in [\\/]* | ?:[\\/]*) ac_cv_path_rlogin="$rlogin" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in "$PATH" do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_rlogin="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_rlogin" && ac_cv_path_rlogin=""/usr/bin/rlogin"" ;; esac fi rlogin=$ac_cv_path_rlogin if test -n "$rlogin"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rlogin" >&5 $as_echo "$rlogin" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char foo[UT_HOSTSIZE - 23]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : bigutmp=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if [ "$bigutmp" = "yes" ]; then bigutmp="#define HAVE_BIGUTMP" fi if [ -f $pppdir.t*gz ]; then pppsourcedir="." else pppsourcedir=".." fi CFLAGS="-O2 $debug -Wall -W -Wshadow -Wpointer-arith -Wwrite-strings -pedantic" ac_config_files="$ac_config_files Makefile pslave_cfg.h pslave.conf portslave.8 portslave.spec src/Makefile extract_and_patch" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "pslave_cfg.h") CONFIG_FILES="$CONFIG_FILES pslave_cfg.h" ;; "pslave.conf") CONFIG_FILES="$CONFIG_FILES pslave.conf" ;; "portslave.8") CONFIG_FILES="$CONFIG_FILES portslave.8" ;; "portslave.spec") CONFIG_FILES="$CONFIG_FILES portslave.spec" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "extract_and_patch") CONFIG_FILES="$CONFIG_FILES extract_and_patch" ;; *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || as_fn_error "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit $? fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi portslave-2010.04.19.1/portslave.spec0000664000000000000000000000542711362674247014075 0ustar summary: Terminal server that does PPP and authenticates via RADIUS name: portslave version: 2010.03.30 release: 1 copyright: GPL group: Applications/Communications buildroot: /tmp/portslave-%{version} source0: http://www.sourceforge.net/projects/portslave/portslave_%{version}.tar.gz source1: http://www.sourceforge.net/projects/portslave/ppp-2.4.1.tgz %description This package provides a program named portslave which will use AT commands to answer a modem when it rings. It will then display a login: prompt at which the user can enter a user-name and password. If the user sends PPP data then portslave will run it's own pppd instead and authenticate the user via PAP. When the user-name and password are received they will be verified via a RADIUS server. At the end of the call the accounting data will be written to the RADIUS server. %prep %setup0 -q -c -a1 -n portslave-%{version} cp %{SOURCE1} . %build pushd portslave-%{version} ./configure make popd %install DESTDIR=$RPM_BUILD_ROOT; export DESTDIR [ -n "`echo $DESTDIR | sed -n 's:^/tmp/[^.].*$:OK:p'`" ] && rm -rf $DESTDIR || (echo "Invalid BuildRoot: '$DESTDIR'! Check the spec ..."; exit 1) || exit 1 mkdir -p $DESTDIR/usr/{{s,}bin,lib} mkdir -p $DESTDIR%{_mandir}/man{1,5,8} mkdir -p $DESTDIR/etc/{portslave/filters,/rc.d/init.d} pushd portslave-%{version} install -c -m 644 pslave.conf $DESTDIR/etc/portslave/pslave.conf.sample install -c -m 644 pslave.conf.5 $DESTDIR%{_mandir}/man5 install -c -m 755 src/portslave $DESTDIR/usr/sbin install -c -m 644 portslave.8 $DESTDIR%{_mandir}/man8 install -c -o root -g daemon -m 4750 src/ctlportslave $DESTDIR/usr/sbin install -c -m 644 ctlportslave.1 $DESTDIR%{_mandir}/man1 install -c -m 755 ppp-2.4.1/pppd/pppd $DESTDIR/usr/sbin/pppd-radius install -c -m 644 ppp-2.4.1/pppd/pppd.8 $DESTDIR%{_mandir}/man8/pppd-radius.8 install -c -m 644 src/libpsr.so $DESTDIR/usr/lib install -c -m 644 src/libportslave.so $DESTDIR/usr/lib popd %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %clean DESTDIR=$RPM_BUILD_ROOT;export DESTDIR;[ -n "$UID" ]&&[ "$UID" -gt 0 ]&&exit 0 [ -n "`echo $DESTDIR | sed -n 's:^/tmp/[^.].*$:OK:p'`" ] && rm -rf $DESTDIR || (echo "Invalid BuildRoot: '$DESTDIR'! Check the spec ..."; exit 1) || exit 1 %files %defattr(-,root,root) /usr/sbin/portslave /usr/sbin/ctlportslave /usr/sbin/pppd-radius /usr/lib/libpsr.so /usr/lib/libportslave.so %{_mandir}/man1/ctlportslave.1* %{_mandir}/man5/pslave.conf.5* %{_mandir}/man8/portslave.8* %{_mandir}/man8/pppd-radius.8* /etc/portslave/pslave.conf.sample %dir /etc/portslave %dir /etc/portslave/filters %doc portslave-%{version}/docs/* %changelog * Sat Oct 27 2001 Alexandr D. Kanevskiy - package for ASPLinux 7.2 * Tue Jul 10 2001 Andrew McRory - 2001_07-10.1 - created package for portslave distribution portslave-2010.04.19.1/Makefile.in0000664000000000000000000000352707422044704013235 0ustar .EXPORT_ALL_VARIABLES: CC = @CC@ CFLAGS += @CFLAGS@ LDFLAGS = @LDFLAGS@ RANLIB = @RANLIB@ CPP = $CC -E INSTALL=@INSTALL@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ INSTALL_DATA=@INSTALL_DATA@ prefix=@prefix@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ libdir=@libdir@ sysconfdir=@sysconfdir@ mandir=@mandir@ pppdir=@pppdir@ pppsourcedir=@pppsourcedir@ ALL: chmod 755 extract_and_patch ./extract_and_patch make -C src cd $(pppdir)/pppd && make -f Makefile.linux COPTS="-O2 -pipe -Wall -g -DLOG_PPP=LOG_LOCAL2" deb-install: mkdir -p $(INST_PREFIX)/$(sbindir) $(INST_PREFIX)/$(libdir) $(INST_PREFIX)/$(sysconfdir) $(INSTALL_DATA) -m 644 ./pslave.conf $(INST_PREFIX)/$(sysconfdir)/pslave.conf.sample mkdir -p $(INST_PREFIX)/$(mandir)/man1 $(INST_PREFIX)/$(mandir)/man5 $(INST_PREFIX)/$(mandir)/man8 $(INSTALL_DATA) pslave.conf.5 $(INST_PREFIX)/$(mandir)/man5 $(INSTALL_PROGRAM) @stripping@ -m 755 src/portslave $(INST_PREFIX)/$(sbindir) $(INSTALL_DATA) portslave.8 $(INST_PREFIX)/$(mandir)/man8 $(INSTALL_PROGRAM) @stripping@ -m 755 src/ctlportslave $(INST_PREFIX)/$(sbindir) $(INSTALL_DATA) ctlportslave.1 $(INST_PREFIX)/$(mandir)/man1 $(INSTALL_PROGRAM) @stripping@ -m 644 src/libpsr.so $(INST_PREFIX)/$(libdir) -$(INSTALL_PROGRAM) @stripping@ -m 644 src/libportslave.so $(INST_PREFIX)/$(libdir) install: deb-install $(INSTALL_PROGRAM) @stripping@ -m 755 $(pppdir)/pppd/pppd $(INST_PREFIX)/@pppdradius@ $(INSTALL_DATA) $(pppdir)/pppd/pppd.8 $(INST_PREFIX)/$(mandir)/man8/pppd-radius.8 clean: make -C src clean -make -C $(pppdir)/pppd -f Makefile.linux clean distclean: clean rm -f config.* Makefile pslave_cfg.h pslave.conf portslave.8 rm -f src/Makefile extract_and_patch rm -f configure-stamp build-stamp debian/postinst.debhelper debian/prerm.debhelper debian/substvars debian/files rm -rf debian/portslave rm -rf ppp-2.4.? portslave-2010.04.19.1/rlogin.spec0000664000000000000000000000272307411446072013335 0ustar %define name rlogin %define version 8.10 %define rev 1 %define group Applications/Communications %define copyright GPL summary : rlogin hacked with -i support for portslave. name : %{name} version : %{version} release : %{rev} copyright : %{copyright} group : %{group} buildroot : /tmp/%{name}-%{version} source0: http://www.sourceforge.net/projects/portslave/rlogin-8.10.tar.gz %description This is a version of rlogin that accepts an extra -i parameter to specify the local user-name in the rlogin protocol. This should not be needed as a standard rlogin should (hopefully) have this feature. %prep %setup0 -n %{name}-%{version} %build make %install DESTDIR=$RPM_BUILD_ROOT; export DESTDIR [ -n "`echo $DESTDIR | sed -n 's:^/tmp/[^.].*$:OK:p'`" ] && rm -rf $DESTDIR || (echo "Invalid BuildRoot: '$DESTDIR'! Check the spec ..."; exit 1) || exit 1 mkdir -p $DESTDIR/usr/{bin,man/man1} install -s -o root -g bin -m 4511 rlogin-radius $DESTDIR/usr/bin install -o bin -g bin -m 644 *.1 $DESTDIR/usr/man/man1 %post %postun %clean DESTDIR=$RPM_BUILD_ROOT;export DESTDIR;[ -n "$UID" ]&&[ "$UID" -gt 0 ]&&exit 0 [ -n "`echo $DESTDIR | sed -n 's:^/tmp/[^.].*$:OK:p'`" ] && rm -rf $DESTDIR || (echo "Invalid BuildRoot: '$DESTDIR'! Check the spec ..."; exit 1) || exit 1 %files /usr/bin/rlogin-radius /usr/man/man1/rlogin.1.gz %changelog * Tue Jul 13 2001 Andrew McRory - 8.10 - created package for portslave distribution portslave-2010.04.19.1/config.log0000664000000000000000000002242511362674403013141 0ustar This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by configure, which was generated by GNU Autoconf 2.65. Invocation command line was $ ./configure --prefix=/usr --mandir=/usr/share/man --with-pppdir=ppp-2.4.1 --sysconfdir=/etc/portslave --with-pppdradius=/usr/sbin/pppd --enable-ipv6 --enable-shadow --with-radclient-cfg=/etc/radiusclient/radiusclient.conf ## --------- ## ## Platform. ## ## --------- ## hostname = athena uname -m = x86_64 uname -r = 2.6.32-3-amd64 uname -s = Linux uname -v = #1 SMP Wed Feb 24 18:07:42 UTC 2010 /usr/bin/uname -p = unknown /bin/uname -X = unknown /bin/arch = unknown /usr/bin/arch -k = unknown /usr/convex/getsysinfo = unknown /usr/bin/hostinfo = unknown /bin/machine = unknown /usr/bin/oslevel = unknown /bin/universe = unknown PATH: ~/bin PATH: /usr/local/bin PATH: /usr/bin PATH: /bin PATH: /usr/games ## ----------- ## ## Core tests. ## ## ----------- ## configure:2008: checking for gcc configure:2024: found /usr/bin/gcc configure:2035: result: gcc configure:2264: checking for C compiler version configure:2273: gcc --version >&5 gcc (Debian 4.4.2-9) 4.4.3 20100108 (prerelease) Copyright (C) 2009 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. configure:2284: $? = 0 configure:2273: gcc -v >&5 Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.2-9' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.4.3 20100108 (prerelease) (Debian 4.4.2-9) configure:2284: $? = 0 configure:2273: gcc -V >&5 gcc: '-V' option must have argument configure:2284: $? = 1 configure:2273: gcc -qversion >&5 gcc: unrecognized option '-qversion' gcc: no input files configure:2284: $? = 1 configure:2304: checking whether the C compiler works configure:2326: gcc -g -O2 conftest.c >&5 configure:2330: $? = 0 configure:2379: result: yes configure:2382: checking for C compiler default output file name configure:2384: result: a.out configure:2390: checking for suffix of executables configure:2397: gcc -o conftest -g -O2 conftest.c >&5 configure:2401: $? = 0 configure:2423: result: configure:2445: checking whether we are cross compiling configure:2453: gcc -o conftest -g -O2 conftest.c >&5 configure:2457: $? = 0 configure:2464: ./conftest configure:2468: $? = 0 configure:2483: result: no configure:2488: checking for suffix of object files configure:2510: gcc -c -g -O2 conftest.c >&5 configure:2514: $? = 0 configure:2535: result: o configure:2539: checking whether we are using the GNU C compiler configure:2558: gcc -c -g -O2 conftest.c >&5 configure:2558: $? = 0 configure:2567: result: yes configure:2576: checking whether gcc accepts -g configure:2596: gcc -c -g conftest.c >&5 configure:2596: $? = 0 configure:2637: result: yes configure:2654: checking for gcc option to accept ISO C89 configure:2718: gcc -c -g -O2 conftest.c >&5 configure:2718: $? = 0 configure:2731: result: none needed configure:2756: checking how to run the C preprocessor configure:2787: gcc -E conftest.c configure:2787: $? = 0 configure:2801: gcc -E conftest.c conftest.c:9:28: error: ac_nonexistent.h: No such file or directory configure:2801: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "" | #define PACKAGE_TARNAME "" | #define PACKAGE_VERSION "" | #define PACKAGE_STRING "" | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | /* end confdefs.h. */ | #include configure:2826: result: gcc -E configure:2846: gcc -E conftest.c configure:2846: $? = 0 configure:2860: gcc -E conftest.c conftest.c:9:28: error: ac_nonexistent.h: No such file or directory configure:2860: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "" | #define PACKAGE_TARNAME "" | #define PACKAGE_VERSION "" | #define PACKAGE_STRING "" | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | /* end confdefs.h. */ | #include configure:2925: checking for a BSD-compatible install configure:2993: result: /usr/bin/install -c configure:3048: checking for ranlib configure:3064: found /usr/bin/ranlib configure:3075: result: ranlib configure:3226: checking for an ANSI C-conforming const configure:3291: gcc -c -g -O2 conftest.c >&5 configure:3291: $? = 0 configure:3298: result: yes configure:3307: checking for grep that handles long lines and -e configure:3365: result: /bin/grep configure:3370: checking for egrep configure:3432: result: /bin/grep -E configure:3437: checking for ANSI C header files configure:3457: gcc -c -g -O2 conftest.c >&5 configure:3457: $? = 0 configure:3530: gcc -o conftest -g -O2 conftest.c >&5 configure:3530: $? = 0 configure:3530: ./conftest configure:3530: $? = 0 configure:3541: result: yes configure:3554: checking for sys/types.h configure:3554: gcc -c -g -O2 conftest.c >&5 configure:3554: $? = 0 configure:3554: result: yes configure:3554: checking for sys/stat.h configure:3554: gcc -c -g -O2 conftest.c >&5 configure:3554: $? = 0 configure:3554: result: yes configure:3554: checking for stdlib.h configure:3554: gcc -c -g -O2 conftest.c >&5 configure:3554: $? = 0 configure:3554: result: yes configure:3554: checking for string.h configure:3554: gcc -c -g -O2 conftest.c >&5 configure:3554: $? = 0 configure:3554: result: yes configure:3554: checking for memory.h configure:3554: gcc -c -g -O2 conftest.c >&5 configure:3554: $? = 0 configure:3554: result: yes configure:3554: checking for strings.h configure:3554: gcc -c -g -O2 conftest.c >&5 configure:3554: $? = 0 configure:3554: result: yes configure:3554: checking for inttypes.h configure:3554: gcc -c -g -O2 conftest.c >&5 configure:3554: $? = 0 configure:3554: result: yes configure:3554: checking for stdint.h configure:3554: gcc -c -g -O2 conftest.c >&5 ## ---------------- ## ## Cache variables. ## ## ---------------- ## ac_cv_c_compiler_gnu=yes ac_cv_c_const=yes ac_cv_env_CC_set= ac_cv_env_CC_value= ac_cv_env_CFLAGS_set=set ac_cv_env_CFLAGS_value='-g -O2' ac_cv_env_CPPFLAGS_set=set ac_cv_env_CPPFLAGS_value= ac_cv_env_CPP_set= ac_cv_env_CPP_value= ac_cv_env_LDFLAGS_set=set ac_cv_env_LDFLAGS_value= ac_cv_env_LIBS_set= ac_cv_env_LIBS_value= ac_cv_env_build_alias_set= ac_cv_env_build_alias_value= ac_cv_env_host_alias_set= ac_cv_env_host_alias_value= ac_cv_env_target_alias_set= ac_cv_env_target_alias_value= ac_cv_header_inttypes_h=yes ac_cv_header_memory_h=yes ac_cv_header_stdc=yes ac_cv_header_stdlib_h=yes ac_cv_header_string_h=yes ac_cv_header_strings_h=yes ac_cv_header_sys_stat_h=yes ac_cv_header_sys_types_h=yes ac_cv_objext=o ac_cv_path_EGREP='/bin/grep -E' ac_cv_path_GREP=/bin/grep ac_cv_path_install='/usr/bin/install -c' ac_cv_prog_CPP='gcc -E' ac_cv_prog_ac_ct_CC=gcc ac_cv_prog_ac_ct_RANLIB=ranlib ac_cv_prog_cc_c89= ac_cv_prog_cc_g=yes ## ----------------- ## ## Output variables. ## ## ----------------- ## CC='gcc' CFLAGS='-g -O2' CPP='gcc -E' CPPFLAGS='' DEFS='' ECHO_C='' ECHO_N='-n' ECHO_T='' EGREP='/bin/grep -E' EXEEXT='' GREP='/bin/grep' INSTALL_DATA='${INSTALL} -m 644' INSTALL_PROGRAM='${INSTALL}' INSTALL_SCRIPT='${INSTALL}' LDFLAGS='' LIBOBJS='' LIBS='' LTLIBOBJS='' OBJEXT='o' PACKAGE_BUGREPORT='' PACKAGE_NAME='' PACKAGE_STRING='' PACKAGE_TARNAME='' PACKAGE_URL='' PACKAGE_VERSION='' PATH_SEPARATOR=':' RANLIB='ranlib' SHELL='/bin/sh' ac_ct_CC='gcc' arp='' assignment='' bigutmp='' bindir='/usr/bin' build_alias='' callback='' callback_patch='' datadir='${datarootdir}' datarootdir='${prefix}/share' docdir='${datarootdir}/doc/${PACKAGE}' dvidir='${docdir}' exec_prefix='/usr' fido='' host_alias='' htmldir='${docdir}' ifconfig='' includedir='${prefix}/include' infodir='${datarootdir}/info' ipv6='#define HAVE_IPV6' libdir='/usr/lib' libexecdir='${exec_prefix}/libexec' localedir='${datarootdir}/locale' localstatedir='${prefix}/var' mandir='/usr/share/man' no_local_ip='' oldincludedir='/usr/include' pdfdir='${docdir}' pppdir='' pppdradius='/usr/sbin/pppd' pppsourcedir='' prefix='/usr' program_transform_name='s,x,x,' psdir='${docdir}' radclient_cfg='' rlogin='' route='' rundir='' sbindir='/usr/sbin' shadow='#define HAS_SHADOW' sharedstatedir='${prefix}/com' ssh='' stripping='-s' sysconfdir='/etc/portslave' target_alias='' telnet='' version='2010.03.30' ## ----------- ## ## confdefs.h. ## ## ----------- ## /* confdefs.h */ #define PACKAGE_NAME "" #define PACKAGE_TARNAME "" #define PACKAGE_VERSION "" #define PACKAGE_STRING "" #define PACKAGE_BUGREPORT "" #define PACKAGE_URL "" #define STDC_HEADERS 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_STAT_H 1 #define HAVE_STDLIB_H 1 #define HAVE_STRING_H 1 #define HAVE_MEMORY_H 1 #define HAVE_STRINGS_H 1 #define HAVE_INTTYPES_H 1 configure: caught signal 2 configure: exit 1 portslave-2010.04.19.1/portslave.spec.in0000664000000000000000000000542307422044651014466 0ustar summary: Terminal server that does PPP and authenticates via RADIUS name: portslave version: @version@ release: 1 copyright: GPL group: Applications/Communications buildroot: /tmp/portslave-%{version} source0: http://www.sourceforge.net/projects/portslave/portslave_%{version}.tar.gz source1: http://www.sourceforge.net/projects/portslave/@pppdir@.tgz %description This package provides a program named portslave which will use AT commands to answer a modem when it rings. It will then display a login: prompt at which the user can enter a user-name and password. If the user sends PPP data then portslave will run it's own pppd instead and authenticate the user via PAP. When the user-name and password are received they will be verified via a RADIUS server. At the end of the call the accounting data will be written to the RADIUS server. %prep %setup0 -q -c -a1 -n portslave-%{version} cp %{SOURCE1} . %build pushd portslave-%{version} ./configure make popd %install DESTDIR=$RPM_BUILD_ROOT; export DESTDIR [ -n "`echo $DESTDIR | sed -n 's:^/tmp/[^.].*$:OK:p'`" ] && rm -rf $DESTDIR || (echo "Invalid BuildRoot: '$DESTDIR'! Check the spec ..."; exit 1) || exit 1 mkdir -p $DESTDIR/usr/{{s,}bin,lib} mkdir -p $DESTDIR%{_mandir}/man{1,5,8} mkdir -p $DESTDIR/etc/{portslave/filters,/rc.d/init.d} pushd portslave-%{version} install -c -m 644 pslave.conf $DESTDIR/etc/portslave/pslave.conf.sample install -c -m 644 pslave.conf.5 $DESTDIR%{_mandir}/man5 install -c -m 755 src/portslave $DESTDIR/usr/sbin install -c -m 644 portslave.8 $DESTDIR%{_mandir}/man8 install -c -o root -g daemon -m 4750 src/ctlportslave $DESTDIR/usr/sbin install -c -m 644 ctlportslave.1 $DESTDIR%{_mandir}/man1 install -c -m 755 @pppdir@/pppd/pppd $DESTDIR/usr/sbin/pppd-radius install -c -m 644 @pppdir@/pppd/pppd.8 $DESTDIR%{_mandir}/man8/pppd-radius.8 install -c -m 644 src/libpsr.so $DESTDIR/usr/lib install -c -m 644 src/libportslave.so $DESTDIR/usr/lib popd %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %clean DESTDIR=$RPM_BUILD_ROOT;export DESTDIR;[ -n "$UID" ]&&[ "$UID" -gt 0 ]&&exit 0 [ -n "`echo $DESTDIR | sed -n 's:^/tmp/[^.].*$:OK:p'`" ] && rm -rf $DESTDIR || (echo "Invalid BuildRoot: '$DESTDIR'! Check the spec ..."; exit 1) || exit 1 %files %defattr(-,root,root) /usr/sbin/portslave /usr/sbin/ctlportslave /usr/sbin/pppd-radius /usr/lib/libpsr.so /usr/lib/libportslave.so %{_mandir}/man1/ctlportslave.1* %{_mandir}/man5/pslave.conf.5* %{_mandir}/man8/portslave.8* %{_mandir}/man8/pppd-radius.8* /etc/portslave/pslave.conf.sample %dir /etc/portslave %dir /etc/portslave/filters %doc portslave-%{version}/docs/* %changelog * Sat Oct 27 2001 Alexandr D. Kanevskiy - package for ASPLinux 7.2 * Tue Jul 10 2001 Andrew McRory - 2001_07-10.1 - created package for portslave distribution portslave-2010.04.19.1/pslave.conf.in0000664000000000000000000001177511352123103013726 0ustar # pslave.conf Here is the sample server configuration file. # see http://doc.coker.com.au/projects/portslave/ for more information # # Version: @version@ # IP address - if left empty, uses the IP address of the system (hostname). # This is used as the "local" address for SLIP and PPP connections. # # used to be conf.ipno all.loc_host 192.168.42.1 # If you set this to "yes", you can always login locally by putting a '!' # before your loginname. Useful for emergencies when the RADIUS server is down. # all.locallogins no # Logging stuff - this program can use a remote syslog daemon if needed. # If you want to log locally leave the "syslog" field empty. The facility # field is an integer between 0 and 7 and sets the syslog facility to # local0-local7. # #all.syslog logger.someisp.com all.syslog all.facility 2 # Directory where your scripts that set up IP filtering (typically using # ipfwadmin) are stored. To invoke them, just add the RADIUS-attribute # Framed-Filter-Id = "foo" to your profile, where foo is the name of script. # all.filterdir @sysconfdir@/filters ## The all entry is used as a template for all others. This means that ## setting all.debug to "2", you set s0.debug, s1.debug, s2.debug etc. ## to "2". It also means that all these settings can be overridden on a ## per-port basis below. # Debugging output to syslog. Set to 0, 1, or 2. 2 is pretty verbose. # all.debug 1 # Authentication type - either "radius" or "none". # all.authtype radius # Default is to accept NULL passwords when doing radius authentication. Set # to "0" or "1". This option does not have effect on non-radius # authentication - i.e. if "authtype" is "none" or if you do a local login. # all.radnullpass yes # Default protocol and host. # all.protocol ppp # Default IP stuff. If you end the "rem_host" with a "+", the portnumber will # be added to the IP number. The IP number of a port is used when the RADIUS # server doesn't send an IP number, or if it tells us to use a dynamic rem_host. # # Leave the netmask at 255.255.255.255, unless your really know what # you're doing. # # all.rem_host used to be all.ipno all.rem_host 192.168.42.2+ all.netmask 255.255.255.255 all.mtu 1500 # Standard message that is issued on connect. # all.issue \n\ Portslave Internet Services\n\ \n\ Welcome to terminal server %h port S%p \n\ \n\ Customer Support: 123-555-1212 http://www.myisp.net/\n\ \n # If you want portslave to update the wtmp file just # like a regular getty/login, set this to yes. # all.syswtmp yes ## Options for the serial port. # Porttype (passed to radius server for logging). # async, sync, isdn, isdn-v120, isdn-v110 # all.porttype async # Speed. All ports are set to 8N1. # all.speed 115200 # Use this to initialize the connection # # d == delay (1 sec), p == pause (0.1 sec), l == toggle DTR # r == , l == # # If the modem tells us the calling number by "NMBR = num" and the called # number by "NDID = num" (as some brands apparently do) then add the # following to the start of the initchat to recognise the CLI numbers: # SETVAR "S=NMBR = " \ # SETVAR "D=NDID = " \ # all.initchat TIMEOUT 10 \ ABORT "NO CARRIER" \ ABORT VOICE \ SETVAR "C=CARRIER " \ SETVAR C+PROTOCOL: \ SETVAR C?CONNECT \ "" \d\l\dATZ \ OK\r\n-ATZ-OK\r\n "\c" \ TIMEOUT 3600 \ RING "\c" \ STATUS Incoming %p:I.HANDSHAKE \ "" ATA \ TIMEOUT 75 \ CONNECT "\c" \ STATUS Connected %p:I.HANDSHAKE # Flow control on this serial port: # hard - hardware, rts/cts # soft - software, CTRL-S / CTRL-Q # none. # all.flow hard # Use the DCD line or not (this sets CLOCAL if off). This means that the # session will get hung up if the modem hangs up. Can be set to 0 or 1. # all.dcd yes # PPP options - used if we autodetect a PPP session. # Note that we set mru and mtu both to the MTU setting. # all.autoppp proxyarp %d asyncmap 0 %i: \ noipx noccp login auth require-pap refuse-chap \ mtu %t mru %t \ ms-dns 192.168.1.1 ms-dns 192.168.1.2 \ plugin @libdir@/libpsr.so ## PPP options - User already authenticated and service type is PPP. # all.pppopt proxyarp %d asyncmap 0 %i:%j \ noipx noccp \ mtu %t mru %t \ netmask %m idle %I maxconnect %T \ ms-dns 192.168.1.1 ms-dns 192.168.1.2 \ plugin @libdir@/libpsr.so ## Tty names are s0...s63. For every port we need to define a tty port, and ## an IP number for when radius tells us to pick one ourself. Unless you ## use the IP pool option mentioned above (IP number with "+" appended). ## ## Note that you can change _all_ of the above settings that start ## with all.xxxx on a per-port basis, such as issue, prompt etc. # ##make the first 32 ports be Rocketport #s{0-31} ttyR{0-31} ##used to need the following lines repeated #s0.tty ttyR0 #s1.tty ttyR1 #s2.tty ttyR2 ##make the next 32 ports be Cyclades #s{32-63} ttyC{0-31} ##make the next 32 ports be Stallion #s{64-95} ttyE{0-31} ##make ports 100 and 101 be standard serial. #s{100-101} ttyS{0-1} ##the above but for devfs #s{0-31} ttS/R{0-31} #s{32-63} ttS/C{0-31} #s{64-95} ttS/E{0-31} #s{100-101} ttS/{0-1} portslave-2010.04.19.1/docs/0000775000000000000000000000000007541700342012110 5ustar portslave-2010.04.19.1/docs/logcheck.pppd0000664000000000000000000000150210110566366014554 0ustar port\[S[0-9]+\]: Hangup \(SIGHUP\) port\[S[0-9]+\]: Modem hangup port\[S[0-9]+\]: Connection terminated. port\[S[0-9]+\]: Connect time .* minutes. port\[S[0-9]+\]: Sent .* bytes, received .* bytes. port\[S[0-9]+\]: Exit. port\[S[0-9]+\]: Couldn.t set pass-filter in kernel: Invalid argument port\[S[0-9]+\]: Cannot determine ethernet address for proxy ARP port\[S[0-9]+\]: found interface eth. for proxy arp port\[S[0-9]+\]: (local |remote) IP address port\[S[0-9]+\]: LCP terminated by peer pppd\[.*\]: Plugin /usr/lib/libpsr.so loaded port\[S[0-9]+\]: pppd 2.4.. started by .*, uid 0 port\[S[0-9]+\]: Using interface ppp port\[S[0-9]+\]: Connect: ppp.* <--> /dev/ port\[S[0-9]+\]: Connection terminated. port\[S[0-9]+\]: No response to [0-9]+ echo-requests port\[S[0-9]+\]: Serial link appears to be disconnected. portslave-2010.04.19.1/docs/no-portslave.txt0000664000000000000000000000204607412472141015304 0ustar If you want to run the libpsr.so code without running it through Portslave (for example if you use a program other than the main Portslave program to connect) then you could use a shell script such as the following to launch pppd with libpsr.so loaded: #!/bin/bash export PORTSLAVELOGNAME="$1" export PORTSLAVE_SESSION=`date +%s``printf "%X" $RANDOM` export PORTSLAVE_START_TIME=`date +%s` exec /usr/sbin/pppd plugin /usr/lib/libpsr.so Here's how to do it with PPTP: /etc/pptp.conf: option /etc/ppp/pptp.options localip 192.168.236.133 # Be warned. pppd option in /etc/pptp.conf is not standard ! # use patch from ASPLinux pptpd-1.1.2 RPM or later. pppd /usr/sbin/pptp-portslave /etc/portslave/pslave.conf: # configure it as usual, but with lines defined for pseudo-tty devices s{1000-1063}.tty pts/{0-63} /usr/sbin/pptp-portslave: #!/bin/bash export PORTSLAVELOGNAME="AutoPPP" export PORTSLAVE_SESSION=`date +%s``printf "%X" $RANDOM` export PORTSLAVE_START_TIME=`date +%s` export PORTSLAVE_DO_ACCT="1" exec /usr/sbin/pppd $* plugin /usr/lib/libpsr.so portslave-2010.04.19.1/docs/chatscript-for-USR-Courier0000664000000000000000000000330407411456002017035 0ustar Here is the default initchat setting: all.initchat TIMEOUT 10 \ ABORT "NO CARRIER" \ ABORT VOICE \ "" \d\l\dATZ \ OK\r\n-ATZ-OK\r\n "\c" \ TIMEOUT 3600 \ RING "\c" \ STATUS Incoming %p:I.HANDSHAKE \ "" ATA \ TIMEOUT 75 \ CONNECT@ "\c" \ STATUS Connected %p:I.HANDSHAKE Here's a chat script that matches Nicholas's suggestion and may work better with USR Courier V.everything modems. Please note that as this is an undocumented and non-standard AT command I provide no guarantee about the following, it may potentially cause hardware damage if used in the wrong way... all.initchat TIMEOUT 10 \ ABORT "NO CARRIER" \ ABORT VOICE \ "" \d\l\dATNX \ "" \d\d\l\dATZ \ OK\r\n-ATZ-OK\r\n "\c" \ TIMEOUT 3600 \ RING "\c" \ STATUS Incoming %p:I.HANDSHAKE \ "" ATA \ TIMEOUT 75 \ CONNECT@ "\c" \ STATUS Connected %p:I.HANDSHAKE From: "Nicholas Tretyachenko" To: "Bill Roberts" , Hello all We have also been suffering from USR V.everything lockups, but have decreased possibility of modem lockup with undocumented ATNX command on every initialization of modem. This command resets RAM of the modem's DSP. Probably cause of lockups is overheating of DSP's RAM. Try to initialize your modems that way: ATNX (then wait for a couple seconds (\d\d). Modem doesn't respond with OK) ATZ (or your preferred initialization string) With regards, Nicholas Tretyachenko portslave-2010.04.19.1/docs/MAINTAINERS0000664000000000000000000000116707411414605013612 0ustar * All versions up to and including 1.16: Miquel van Smoorenburg 1.16 is the last version from me. Here in the Netherlands, people are moving away from the traditional terminal server+modems solution. From Januari 1st, 1998 we will only use ISDN PRI solutions. Whoever wants to take over portslave is free to do so, but you might want to contact me first to see if noone else is working on it yet so that I can try to coordinate it a bit. * 1.17 Dave Cinege * 1.2.0+ Dave Cinege * 2000-12-24+ Russell Coker portslave-2010.04.19.1/docs/README_20010000664000000000000000000001623507541415412013442 0ustar Portslave 2000+ Russell Coker 1. DISCLAIMER. There is no warranty of any kind. Please see the LICENSE file for additional information. 2. INTRODUCTION. This is the Portslave RADIUS client. RADIUS (Remote Authentication Dial-In User Service), simply put allows you to authenticate logins from a central RADIUS server without having to keep user account information on multiple machines. As the name states RADIUS is primarily used in terminal servers (aka RAS: Remote Auth Servers) for logging in dial in modem users. Portslave can 'answer the line' and act as the RADIUS client for this as well as other Unix services such as telnet and secure shell (ssh). 3. RADIUS You will need at least one RADIUS server on one of your systems. The best RADIUS server is FreeRadius. You *need* a working RADIUS server first, and you have to understand how it works before you can continue. Note that if you want to offer shell-logins you need an updated dictionary file with the "Shell-User" entry (such as the default for FreeRadius). Use "Login-Service = Shell-User" to let a user use an account on the local machine. BTW, the official new name for this is actually "Administrative-User". 4. BUILDING THE SOFTWARE. How to compile pppd and rlogin. This version supports pppd versions 2.4.0 and 2.4.1. The ./configure script by default will look in the parent directory for the most recent (according to an alpha-numeric sort) file matching "../ppp*gz". Alternatively you can run "./configure --enable-pppdir=ppp-2.4.0" to specify the old version. The ./configure script will create makefiles that take the name of the archive without the ".tar.gz" or ".tgz" extension as the name of the directory that it will be extracted to. Then it will extract the archive as part of the build process and compile the files it contains. Then it will apply patches from the patches/ppp-version directory. The reason for this is to support multiple versions of pppd without the need to include the source to any version of the pppd in the archive. Also eventually I hope to do away with the need for a hacked pppd. 5. INSTALLING THE SOFTWARE. If you use the default paths, you need to install the next files: pslave.conf /etc/portslave/pslave.conf pslave.conf.5 /usr/local/man/man5/pslave.conf.5 src/portslave /usr/local/sbin/portslave portslave.8 /usr/local/man/man8/portslave.8 src/ctlportslave /usr/local/sbin/ctlportslave ctlportslave.1 /usr/local/man/man1/ctlportslave.1 libpsr/libpsr.so /usr/local/lib/libpsr.so ppp-2.4.1/pppd/pppd /usr/local/sbin/pppd-radius You can use the provided "install.sh" script to do this for you. ("make install" also works, it calls the "install.sh" script). It's usually safer to just move all files by hand. Notice that the Portslave RADIUS specific pppd and binary appends a '-radius' suffix so it can peacefully co-exist with the non-RADIUS version. 6. CONFIGURATION First you'll have to choose where to let the portslaves log their messages. The portslaves can use both a local or a remote syslog daemon. On that machine, do the following: o add "local2 -/var/log/local2.log" to /etc/syslog.conf o change any lines that look like "*.debug" or "*.info" to "*.debug;local2.none" to prevent sensitive info being logged to maybe publically readable files. o Create /var/log/local2.log and chmod 600 it so that it's safe. Although we won't write passwords there by default so making it more widely read shouldn't be such a problem. Now you'll have to edit /etc/portslave/pslave.conf". The comments in this file are intentionally minimal as it is fully documented in the man page. 7. EXECUTION Portslave is designed to be spawned by init. This is done by adding a line in your /etc/inittab for every port that you have configured. These lines have to look like this: S0:23:respawn:/usr/local/portslave/bin/portslave 0 [...] S31:23:respawn:/usr/local/portslave/bin/portslave 31 Note that the first field (the "id" field) can only have more than 2 characters if you have a recent sysvinit (>= 2.60) compiled with a recent libc (>= 5.2.18). This doesn't matter; 2 characters is also fine as long as the id fields are unique. 8. CTLPORTSLAVE, FINGERD Ctlportslave gets installed setuid root, group daemon. -rwsr-x--- 1 root daemon 12428 Jun 21 04:00 ctlportslave It offers a very limited subset of the Portmaster interface, and as of 1.2.0 some of it's own unique features. It offers two modes of operation, as a client for the "pmmon" utility from Brad Owens, , or when invoked with '-f' as a quasi emulation of the finger daemon. 7.1 CTLPORTSLAVE AS PMMON CLIENT (depreciated) Add the following to /etc/passwd and set the password for `!root' using the "passwd \!root" command: !root:x:999:1:Portslave Admin:/tmp:/usr/local/sbin/ctlportslave 999 is a free UID, 1 is the GID of the daemon group on your machine. ctlportslave can also be invoked ont he local machine for 'pmmon' style access without the above set up. Unless you already have a desire to use pmmon, it it recommended you only complete the 'finger' set up. 7.2 CTLPORTSLAVE AS FINGERD (prefered) Add this to /etc/inetd.conf. Comment out the existing fingerd entry if needed: finger stream tcp nowait nobody.daemon /usr/sbin/tcpd /usr/local/sbin/ctlportslave -f ctlportslave -f -p psfinger -r psreset ps-finger 7979/tcp (all on one line). Now send SIGHUP to the running inetd. NOTE that fingerd runs as user nobody, group daemon. ctlportslave can also be renamed (or smylinked) with 'finger' in it's name and it will be run as finger without the '-f'. This is provided for backwards compatability and this method has depreciated. 9. FILES IN /etc/ppp Make sure the /etc/ppp/pap-secrets file is empty. Also there must be 2 files "ip-up" and "ip-down" there, that are executable. A file with a single first line "#! /bin/sh" will do. Chmod those files to 755. You also need an options file there. That file must preferably also be empty (0 bytes). 10. AND NOW... Give an "init q" and the portslaves should start. You can see in the logfile (/var/log/local6.log) what exactly is happening. If you want to see much more debug output, set the "debug" entry in the "pslave.conf" config file to 1 or 2, and add the keyword "debug" to both lines of ppp options (all.pppopt and all.autoppp). All debugging output will still go to the "local2.log" file. 11. MORE INFO. You can try the the linux-isp mailing list, which on a lot of sites used to be accessible as the newsgroup linux.admin.isp (not anymore). For the mailing list, send a message with "help" in the body to linuxisp-request@friendly.jeffnet.org. Several people on that list are successfully using this software. Home of portslave at http://portslave.linuxrouter.org/ If you want to do some special routing for single static IP numbers have a look at ripd, @ http://www.miquels.cistron.nl/radius/portslave.html Read the MAINTAINER file to find out who is maintaining portslave. portslave-2010.04.19.1/docs/callback0000664000000000000000000000034607411456002013567 0ustar To enable callback run "./configure --enable-callback" before compiling, then after installing add "callback server" at pppopt/autoppp in your config and use Callback-Number attrbute or Cisco-AVPair="lcp:callback-dialstring=...." portslave-2010.04.19.1/docs/woody-potato.diff0000664000000000000000000000376207411463602015420 0ustar diff -ruN portslave-woody/debian/conffiles portslave-potato/debian/conffiles --- portslave-woody/debian/conffiles Thu Jan 1 01:00:00 1970 +++ portslave-potato/debian/conffiles Sat Dec 15 07:51:31 2001 @@ -0,0 +1 @@ +/etc/portslave/pslave.conf diff -ruN portslave-woody/debian/control portslave-potato/debian/control --- portslave-woody/debian/control Tue Dec 11 11:36:01 2001 +++ portslave-potato/debian/control Sat Dec 15 07:53:55 2001 @@ -7,7 +7,7 @@ Package: portslave Architecture: any -Depends: ${shlibs:Depends}, ppp (= 2.4.1.uus-4) +Depends: ${shlibs:Depends} Description: Terminal server that does PPP and authenticates via RADIUS This package provides a program named portslave which will use AT commands to answer a modem when it rings. It will then display a login: prompt at diff -ruN portslave-woody/debian/rules portslave-potato/debian/rules --- portslave-woody/debian/rules Sat Dec 15 07:31:52 2001 +++ portslave-potato/debian/rules Sat Dec 15 08:03:34 2001 @@ -6,17 +6,15 @@ #export DH_VERBOSE=1 # This is the debhelper compatability version to use. -export DH_COMPAT=3 +export DH_COMPAT=2 export PKGDIR=`pwd`/debian/portslave configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. - ./configure --prefix=/usr --mandir=/usr/share/man --with-pppdir=ppp-2.4.1 --sysconfdir=/etc/portslave --with-pppdradius=/usr/sbin/pppd --enable-ipv6 --enable-shadow + ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc/portslave --enable-shadow rm -rf ppp-2.4.1 - mkdir -p ppp-2.4.1/pppd - cp debian/ppp-2.4.1-headers/* ppp-2.4.1/pppd touch configure-stamp @@ -47,7 +45,7 @@ dh_installdirs # Add here commands to install the package into debian/tmp. - $(MAKE) deb-install INST_PREFIX=$(PKGDIR) + $(MAKE) install INST_PREFIX=$(PKGDIR) mv $(PKGDIR)/etc/portslave/pslave.conf.sample $(PKGDIR)/etc/portslave/pslave.conf mkdir -p $(PKGDIR)/usr/share/lintian/overrides cp debian/lintian $(PKGDIR)/usr/share/lintian/overrides/portslave portslave-2010.04.19.1/docs/default-config0000664000000000000000000000110107411451640014713 0ustar # The following is the compiled-in defaults all.hostname `hostname` all.loc_host (IP address that conf.hostname resolves to) all.prompt "%h login: " all.radnullpass true all.radtimeout 3 all.radretries 5 all.utmpfrom "%p:%P.%3.%4" all.sysutmp true all.syswtmp true all.protocol ppp all.telnet `which telnet` all.ssh `which ssh` all.rlogin `which rlogin` all.pppd (location where we install radius-pppd or location of pppd if we use standard pppd) all.lockdir /var/lock all.term vt100 all.stripnames true all.debug 0 all.parity none all.stopbits 1 all.datasize 8 all.facility 2 portslave-2010.04.19.1/docs/LICENSE0000664000000000000000000000236707411446706013134 0ustar Portslave is Copyright (C) Miquel van Smoorenburg 1997-1998. Dave Cinege 1998-1999. Russell Coker 2000-2001. (And others) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 dated June, 1991. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. On Debian GNU/Linux systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL-2'. This copyright is valid for the sources found in the src/ and libpsr/ directories. The other software included has the following copyrights: ppp-2.4.*-radius/ See the README file (some BSD / some GPL) The modifications made to that software are in the public domain if the copyright allows that, or otherwise under the original copyright. portslave-2010.04.19.1/docs/RFCS0000664000000000000000000000136007411461424012571 0ustar From rfc 2900 Internet Official Protocol Standards: Draft Standard Protocols RADIUS Remote Authentication Dial In User Service (RADIUS) 2865 Proposed Standard Protocols -------- RADIUS Authentication Server MIB 2619 -------- RADIUS Authentication Client MIB 2618 Non-standard stuff: Informational 2924 Accounting Attributes and Record Formats 2906 AAA Authorization Requirements 2882 Network Access Servers Requirements: Extended RADIUS Practices 2869 RADIUS Extensions 2868 RADIUS Attributes for Tunnel Protocol Support 2867 RADIUS Accounting Modifications for Tunnel Protocol Support 2866 RADIUS Accounting 2809 Implementation of L2TP Compulsory Tunneling via RADIUS 3162 RADIUS and IPv6 portslave-2010.04.19.1/docs/HOWTO.ASSIGN_IP0000664000000000000000000002114007411456002014301 0ustar ASSIGNING IP ADDRESSES PORTSLAVE 2001.10.28 Sections ======== Below are the sections of this document: - Compiling - Overview - IP Assignment - PPPD Settings - Radius Settings - Portslave Settings - Client IP Assignment - Common Configurations - NOTES Compiling ========= This is not a standard feature of Portslave (yet). You have to give "./configure" the parameter "--enable-assignment", this will result in the C macros PORTSLAVE_CLIENT_IP_RULES and ALLOW_NO_LOCAL_IP being defined. PORTSLAVE_CLIENT_IP_RULES enables the client IP address selection and ALLOW_NO_LOCAL_IP allows the use of no local IP address. Overview ======== There are several sources used to assign IP addresses with portslave pppd: 1. PPPD Command line 2. File, /etc/ppp/options 3. File, /etc/ppp/options. 4. File, ~/.ppprc 5. Radius server 6. Portslave configuration file, /etc/portslave/pslave.conf 7. Client selection Each of these sources has its own method of setting the IP addresses and indicating when the address is not assigned. In addition, there are rules which determine from which source an IP address will be assigned. This file describes these rules and gives examples of common configurations. IP Assignment ============= The order of precedence for the assignment of IP addresses is shown below. The first of these locations that contains an IP address assignment sets the IP address. Note that the local and remote IP addresses can be assigned independent of each other even though both use the same rules. 1. Client selection * 2. Radius server 3. /etc/portslave/pslave.conf 4. Command line 5. ~/.ppprc 6. /etc/ppp/options 7. /etc/ppp/options. * This has not been fully verified but has been seen in testing. PPPD Settings ============= For the command line, options, options., and .ppprc locations, the IP addresses can be assigned using the : format. In order to indicate that either address is not assigned, simply exclude it from the argument. If neither is assigned, the entire address specifier can be excluded. Note that excluding the address from the specifier will not undo a previous assignment nor prevent a future assignment. So, for example, if the value "192.168.1.1:" resides in the options file, an entry of "10.3.0.1:10.4.0.2" on the command line will still set the remote IP address to 10.4.0.2. Likewise, with the entry of "192.168.1.1:" in the options file and an entry of "10.3.0.1:10.4.0.2" in the options. file will yield a remote IP address of 10.4.0.2. Radius Settings =============== There are different radius implementations, each of which has its own method of setting the various attributes. Here are the attributes which may be used to assign IP addresses: ATTRIBUTE MEANING ---------------------- --------------------------------------------- 8 Framed IP Address Remote IP Address 9 Framed IP Netmask Remote IP Netmask 14 Login IP Host Remote IP Address Any attribute which is not supplied by the radius server to the portslave radius client is left unassigned. In addition, setting an IP Address to 255.255.255.255 will also indicate that it is unassigned. Portslave Settings ================== Below are the settings in the pslave.conf file which affect the IP Address assignment. all.loc_host - Sets the local IP Address of the server. Set to 255.255.255.255 in order to indicate that the local IP Address is unassigned. all.rem_host - Sets the remote IP Address of all ports. Set to 255.255.255.255 in order to indicate that the remote IP Address is unassigned. s.rem_host -Sets the remote IP Address of the specified port. Set to 255.255.255.255 in order to indicate that the remote IP Address is unassigned. NOTE: if both all.rem_host and s.rem_host reside in the configuration file, the s.rem_host setting is the one that will be used. Client IP Assignment ==================== Allowing the client to assign the IP address even when the raduis server is used involves the following additional settings in pslave.conf: all.valid_ip - A list of strings which indicate the valid IP addresses which can be selected by a client. The format of the strings matches the IP address field of the pap-secrets file. s.valid_ip - Same as all.valid_ip but only affects one port. Common Configurations ===================== Below are some common configurations for remote IP address assignment and settings that will support each configuration. 1. Assign remote IP address on the radius server 2. Assign remote IP address in options file 3. Assign remote IP address in pslave.conf file 4. Assign remote IP address in options. file 5. Allow client to select the remote IP address Here are the sample settings for each configuration: 1. Assign remote IP address on the radius server: /etc/ppp/options - Exclude entry. /etc/ppp/options. - Exclude entry. ~/.ppprc - Exclude entry. /etc/portslave/pslave.conf - Include entry "all.rem_host 255.255.255.255", or the s.rem_host equivalent; for example: "s0.rem_host 255.255.255.255". Command Line - Exclude setting. Radius Server - Assign IP address. Client - Exclude setting. 2. Assign remote IP address in options file: /etc/ppp/options - Include entry such as ":192.168.1.1" /etc/ppp/options. - Exclude entry. ~/.ppprc - Exclude entry. /etc/portslave/pslave.conf - Include entry "all.rem_host 255.255.255.255", or the s.rem_host equivalent; for example: "s0.rem_host 255.255.255.255". Command Line - Exclude setting. Radius Server - Exclude setting or assign "255.255.255.255". Client - Exclude setting. 3. Assign remote IP address in pslave.conf file: /etc/ppp/options - Exclude entry. /etc/ppp/options. - Exclude entry. ~/.ppprc - Exclude entry. /etc/portslave/pslave.conf - Include entry "all.rem_host 192.168.2.1", or the s.rem_host equivalent; for example: "s0.rem_host 192.168.2.1". Command Line - Exclude setting. Radius Server - Exclude setting or assign "0.0.0.0". Client - Exclude setting. 4. Assign remote IP address in options. file: /etc/ppp/options - Exclude entry. /etc/ppp/options. - Include entry such as ":192.168.1.1" ~/.ppprc - Exclude entry. /etc/portslave/pslave.conf - Include entry "all.rem_host 255.255.255.255", or the s.rem_host equivalent; for example: "s0.rem_host 255.255.255.255". Command Line - Exclude setting. Radius Server - Exclude setting or assign "255.255.255.255". Client - Exclude setting. 5. Allow client to assign remote IP address: /etc/ppp/options - Exclude entry. /etc/ppp/options. - Exclude entry. ~/.ppprc - Exclude entry. /etc/portslave/pslave.conf - Include entry "all.rem_host 255.255.255.255", or the s.rem_host equivalent; for example: "s0.rem_host 255.255.255.255". Also, include the entry "all.valid_ip " or the s.valid_ip equivalent. Note that in this case is any string accepted in the IP address field of the pap-secrets file. Command Line - Exclude setting. Radius Server - Exclude setting or assign "255.255.255.255". Client - Exclude setting. NOTES ===== - This file is based on Portslave distribution 2001.10.28. - Modifications were made to the base distribution to enable some of the functionality described in this file. - A large number of combinations of configurations exists because of the number of locations that can be used to hold settings. Putting most of the settings into a single location, such as the pslave.conf file, helps to reduce the complexity and confusion. In addition, because of the number of combinations is large, it is difficult to verify that each one operates as expected. portslave-2010.04.19.1/docs/logcheck0000664000000000000000000000130510110566422013604 0ustar port\[S[0-9]+\]: initchat failed - timeout port\[S[0-9]+\]: portslave started on port port\[S[0-9]+\]: user .* logged (in|out) port\[S[0-9]+\]: chat_send port\[S[0-9]+\]: chat_expect port\[S[0-9]+\]: chatarray: port\[S[0-9]+\]: Detected login for port\[S[0-9]+\]: PPP frames detected - switching to PPP mode port\[S[0-9]+\]: .*/PPP session \(.*\) port\[S[0-9]+\]: Got Hangup - exiting port\[S[0-9]+\]: Connected - waiting for login port\[S[0-9]+\]: Added (abort|setvar) string port\[S[0-9]+\]: (Add|Delet)ing routes port\[S[0-9]+\]: Match on setvar string port\[S[0-9]+\]: Cleaned (abort|setvar) list port\[S[0-9]+\]: read_char: timed out in poll port\[S[0-9]+\]: Got a reply, code .*length portslave-2010.04.19.1/docs/TODO0000664000000000000000000000227507411454215012607 0ustar Test realms support, ssh, etc (pre9 changes) Fix update_framed_route() to better handle netmask according to RFC. (Linux 2.2 wants /bits on networkip. 2.0 can't deal with it.) Reply-Message Giving extra instance of element 0 for over 1 output. Can't find bug. Is it the RADIUS server? Add connect info patch? post 1.2.0 ML-PPP support provide route/ifconfig port to iproute? Portability issue fixes. Fix remaining 'FIX ME's. Implement PW_NAS_PORT_LIMIT (?) Implement PW_FRAMED_ROUTING (?) post 2001 Fix serial port locking for devfs (needs LSB discussion). Fix SLIP code to do proxyarp the same way as ppp. Make sure that all error codes from system calls are caught, particularly the write() calls in chat.c! Re-format everything to new coding standards, two spaces for indenting, no tabs, '{' and '}' in the same column. Check all the locking code and make sure that all error conditions are caught. Fix the following bug where it always seems to restart twice: Oct 14 22:49:37 tsv port[S23]: portslave started on port 23 (/dev/ttyE23) Oct 14 22:49:41 tsv port[S23]: tcsetattr /dev/ttyE23: Input/output error Oct 14 22:49:41 tsv port[S23]: portslave started on port 23 (/dev/ttyE23) portslave-2010.04.19.1/docs/README.time0000664000000000000000000000173107550414032013725 0ustar + + Time limits for incoming calls support for portslave + +For example you need modem to answer incoming calls since 08:00 up to 21:00. You can define time value for tty which will limit incoming calls. Outside those times the modem will not even be initialised (so it could be used for voice calls). ttyname.login_time TIMES Syntax: TIMES is a comma separated list of times for which the entry is valid. The entry will be ignored completely out- side these times. The format for each element of the times field is: DD[DD...][SSSS-EEEE] Where: DD is one of Sun Mon Tue Wed Thu Fri Sat All Week Weekend (All = All days, week = Mon .. Fri, Weekend = Sat + Sun) SSSS and EEEE are start and end times in 24 hour notation Examples: all.time All 0800-2100 s0.time Mon Tue Wed Thu Fri 2300-0700,Sat Sun 1800-0900 Sincerely yours, Dmitry Sergienko portslave-2010.04.19.1/docs/pslave.conf.sample0000664000000000000000000000315107411456002015526 0ustar # You can delete the examples below and unused ports above # if you wish to clean up the config file, ofcourse. # S30 is an external modem. # s30.tty ttyS0 # S31 is a test port with a terminal on it. # # NOTE: you can ofcourse also enter tty9 here instead of ttyS1. # That way you can test portslave on a virtual console by # switching to it with ALT-F9. # s31.tty ttyS1 s31.speed 9600 s31.flow soft s31.dcd 0 s31.initchat "" # S32 is my builtin 9600 baud modem # s32.tty ttyS3 s32.speed 19200 # S33 is connected to a macine that _thinks_ it is connected to a modem. # In this case, portslaves emulates a Hayes compatible modem. We use it # to hook up our Mac with MACPPP over a serial null modem cable. # s33.tty ttyS2 s33.speed 57600 s33.emumodem yes # Leased Lines. # # Note that we change the lcp-timeout (lcp-restart) from 3 (default) to 4. # PPP 2.2.0f in combination with some other PPP implementations may # otherwise get stuck in an endless negotiation loop. Dialin lines do # not have this problem because both sides start up at the same time. # # Do this only one _one_ side ofcourse. s34.tty ttyR47 s34.initchat TIMEOUT 10 \ ABORT "NO CARRIER" \ ABORT VOICE \ "" \d\l\dATZ \ OK\r\n-ATZ-OK\r\n "\c" \ STATUS Incoming %p:I.HANDSHAKE \ "" ATA \ TIMEOUT 75 \ CONNECT@ "\c" \ STATUS LEASED %p:%c s34.authtype none s34.issue "" s34.protocol ppp s34.rem_host 192.168.5.249 s34.netmask 255.255.255.248 s34.pppopt proxyarp modem asyncmap 0 %i:%j netmask %m \ -ipx-protocol -ccp-protocol passive mtu 576 mru 576 \ lcp-restart 4 ip-up-script /etc/ppp/ip-up.leased \ ip-down-script /etc/ppp/ip-down.leased portslave-2010.04.19.1/docs/environment-variables0000664000000000000000000000152407412365206016352 0ustar Environment variables used by libpsr: PORTSLAVE_CONF - the location of the config file if it's not the compiled in default. PORTSLAVELOGNAME - the name that is written to log files as the "login name" of the user. PORTSLAVE_SESSION - the RADIUS protocol session code. PORTSLAVE_START_TIME - the unix-format time that the session started. CONNECT_INFO - connect data (carrier speed, V42, etc), whatever the modem returns between "CONNECT " and the end of the line. PORTSLAVE_FILTER - the filter(s) to run on bringing up IP. PORTSLAVE_FRAMED_ROUTE - the route(s) to add/remove when putting the link up/down. PORTSLAVE_DO_ACCT - if set then do accounting. PORTSLAVE_PORT - the port number for portslave. PORTSLAVE_CLI_SRC - what CLI says is the customer's phone number. PORTSLAVE_CLI_DST - what CLI says is the number the customer dialled. portslave-2010.04.19.1/docs/HOW-TO-REPORT-BUGS0000664000000000000000000000275307411451640014566 0ustar Last updated: 2001-10-15 Firstly make sure your email address works. Spending my time writing a detailed response to a bug report only to have it bounce really annoys me and makes bug reports from that person take a much lower priority! Get a hotmail address if you have to (I actually don't like hotmail, but have to admit that they are more reliable than most mail servers on the net). Make sure you give following info: 1. What linux distribution do you use (e.g. Debian 2.2, Red Hat 7.2, etc). 2. What kernel do you use (uname -a). 3. Attach your /etc/portslave/pslave.conf (with the RADIUS shared secret removed. 4. Send the syslog data. Paste the logs direct from the log files, don't re-type them (this is important for accuracy). 5. If you suspect there is a problem with portslave <---> radius daemon communication, attach also your radius daemon config files - the "users" and "clients" files (these are different for different radius servers). 6. A) Select a test port on your access server, then enable debugging for that port by setting the corresponding "sN.debug" item to 2 (N is the number of your test port). B) Add "debug kdebug7" to the command line options of radius pppd. C) Edit your /etc/syslog.conf and add following lines to it: local2.* -/var/log/portslave daemon.* -/var/log/portslave then "killall -HUP syslogd". D) After triggering the bug, attach the part of /var/log/portslave generated by portslave on the test port. portslave-2010.04.19.1/docs/ChangeLog.ancient0000664000000000000000000002304507411447423015312 0ustar 31_Dec_1999-1 (Unofficial) * Removed unnecessary warning for users that disconnect without having been logged in. * Replaced all calls to sprintf() with calls to snprintf() 03_Dec_1999-1 (Unofficial) * Updated changelog for 24_Nov_1999-2 * Added two new options to pppd-radius: ip-up-script - specifies pathname of ip-up script ip-down-script - specifies pathname of ip-down script * Fixed a bug in radius accounting which caused portslave sometimes to send logout packets for users that were not logged in. 24_Nov_1999-2 (Unofficial) * Included missing errno.h which broke compile on some machines. 24_Nov_1999-1 (Unofficial) * Now ip_up_hook() is called when IP protocol goes up. 23_Nov_1999-3 (Unofficial) * Updated Portslave to pppd-2.3.10. 18_Nov_1999-2 (Unofficial) * Dropped select() support. We use poll() instead. * Changed semantics of STATUS chat keyword. Now it does not update the wtmp logfile. Also now sysutmp and syswtmp config items do not have effect on the result of the STATUS keyword. 16_Nov_1999-2 (Unofficial) * Applied Josh Green's patch that fixed bug in portslave logging. * Fixed a bug which effectively always allowed local logins even if they were disabled in the config file. * Some cleanups of the syslog code. 17_Sep_1999-5 (Unofficial) * Changed the name of my development snapshots, so they are not confused with the official stable/pre versions. * Added new chat keywords: TIMEOUT N - Sets chat timeout to N. 0 means infinite timeout. WAIT DCD - Waits for modem carrier. Affected by chat timeout. STATUS login_format from_format - Updates utmp/wtmp files Best reference for the time being is the new pslave.conf. * Removed lots of config items: waitfor, aa, stripnames, answer, checktime, checkchat * Minimum loglevel fixed in libpsr (LOG_DEBUG and LOG_INFO messages were not logged). * Send accounting start request only once per user login. * Lots of code cleanup here and there. 1.2.0pre13beta2 (Unofficial) * You need to run ./configure before calling "make". Just use make clean ./configure make make install to compile and install portslave * all.radnullpass config item - whether to accept "" passwords. * Configurable utmp/wtmp strings - uses printf-like format strings. * Some minor code cleanups. 1.2.0pre12 * Fixed update_framed_route(). Changed operation to staircase order. (FIFO/LIFO) IE Last entry to be added is the first to be deleted. (Fixes possible dependency problems) * update_filter_id tested with PPP and AutoPPP. Fixed command line. Changed operation to staircase order. (FIFO/LIFO) IE Last entry to be added is the first to be deleted. (Fixes possible dependency problems) * Reply-Message fixed. (I think. Seeing extra output but think it's the RADIUS server. Reports please.) * Cleaned some log output. * Merged Vesselin's pre10 poll patch 1.2.0pre11 * Portslave now toggles the DTR line when opening the serial port. It previously relied on the externally spawned program to close the connection. PPPD would close the line fine. SLIP, Rlogin, or a non-autoppp password failure would NOT. (Bug IMHO) * Search services file for radius and radacct ports. * Session-Timeout support, to limit the maximum connection time. * New 'big utmp' format (when using libc6 or similar) Entire IP stored in utmp, as well as connect string. * Update utmp with: user:'Incoming' status:'HANKSHAKE' (modem answer) user:'Connected' status:connect string (speed) * Changed ctlportslave to work with utmp 'status' messages. * Changed ctlportslave to report actual type when called as 'finger' instead of just 'Network'. * New ctlportslave view, 'detailed' * New password option for ctlportslave as fingerd. * New reset ports option for ctlportslave as fingerd. * New 'UPTIME' compile option for ctlportslave as fingerd. * Byte accounting fixed for non-AUTOPPP. * Byte accounting added for SLIP and CSLIP. (Portslave now forks) * Filter ID patch added. * SSH service patch added. * Realms support patch added. UUCPHACK code removed. * Portslave no longer depends on the external program stty. * Operate on stdin option. (Backend mgetty) * Modem checking feature. * Compiler routines optimized. (No debug. Binaries now smaller) * Various minor bug fixes. * Various buffer overflow fixes. * PPPD 2.3.8 (ppp 2.2 support purged) * Many more things forgotten... portslave (1.17) cistron; urgency=low * Added ppp 2.3.5 support. * Change names of pppd, /etc/ppp, and rlogin to *-radius * Change default paths of binaries and config file * Updated install.sh -- Dave Cinege Tue, 03 Nov 1998 07:57:00 -0500 portslave (1.16) cistron; urgency=low * Build autoppp part of portslave as shared lib, linked in on-demand by ppp-2.2.0f. * Added MD5 auth for accounting packets; thanks to Eric Stern * Fixed bug in Reply-Message handling. Or actually, string handling in general. Thanks to Jens Glaser * Now logs everything after CONNECT to radius with Connect-Info. * Added "porttype" configuration variable, based on a suggestion from Carl Privitt . * Check for Framed-Protocol = PPP after authentication in pppd * Fix comment handling of config file parser * Added RADIUS logging of sent/recv octets for PPP This should now work reliably minus 1 or 2 seconds before hangup. * Added ctlportslave utility. Can be used as shell for `!root', adds portmaster-like command line admin interface. Very simplistic but useful for packages like pmmon. * Fixed length field of IP address / integer (was 6 instead of 4) Do not include trailing '\0' in strings. * Now also compiles with GNU libc (aka libc6). Diffs submitted by . * Added conf.stripnames option -- Miquel van Smoorenburg Thu, 22 Jan 1998 12:13:46 +0100 portslave (1.15) cistron; urgency=low * lib.c:getline() now accepts \r, \r\n, \n as end-of-line. * getty:login() turns off input CRNL translation * Added new feature: portslave can now emulate a modem. Set "sXX.emumodem 1" to enable this feature. * Add support for updating local utmp and wtmp files. * Add support for radius Idle-Timeout attribute -- Miquel van Smoorenburg Thu, 5 Jun 1997 20:49:21 +0200 portslave (1.14) cistron; urgency=low * Added copyright notice to README (GPL) * Add note about ripd to README * Change default MTU in sample server.cfg to 1500 - some PPP implementations have trouble with fragmentation. -- Miquel van Smoorenburg Wed, 7 May 1997 13:57:32 +0200 portslave (1.13) cistron; urgency=low * Added CREAD to the c_cflag initialization. This should fix the digiboards. (Fix by Jean-Francois Micouleau ) * Added telnet support. Maybe also pass username if known? -- Miquel van Smoorenburg Thu, 24 Apr 1997 21:36:16 +0200 portslave (1.12) cistron; urgency=high * Now sends accounting requests to the radius accounting port (1646) instead of the authentication port (1645) - funny that nobody found this obvious bug yet (and that it actually _worked_ ..) * Some extra info added to server.cfg * Remove MRU settings; use MTU for both MTU and MRU * Fix '-' argument -- Miquel van Smoorenburg Thu, 6 Feb 1997 22:22:16 +0100 portslave (1.11) cistron; urgency=low * Added comment in server.cfg about "stuck in negotation" loop that ppp-2.2.0f can get into with leased lines, with a workaround. It seems to work for a lot of people except me :(. Under investigation. * Fix for syslog() not working on port 0: Jens Glaser -- Miquel van Smoorenburg Thu, 14 Nov 1996 13:45:53 +0100 portslave (1.10) cistron; urgency=high * Fixed SLIP/CSLIP support that I broke in 1.0.8 or so. -- Miquel van Smoorenburg Mon, 29 Oct 1996 15:41:32 +0100 portslave (1.09) cistron; urgency=low * Fixed leased-line support (again; must have misplaced a part of some previous changes) -- Miquel van Smoorenburg Mon, 22 Oct 1996 11:59:21 +0200 portslave (1.08) cistron; urgency=low * Fixed local syslog logging * Fixed portslave-over-telnet * Added debug option, standard turned off. -- Miquel van Smoorenburg Mon, 14 Oct 1996 18:12:57 +0200 portslave (1.07a) cistron; urgency=low * Removed the nonsense about pap-secrets. -- Miquel van Smoorenburg Mon, 08 Oct 1996 18:02:16 +0200 portslave (1.07) cistron; urgency=low * Fixed the sample server.cfg file; it had a few typos and missing features (esp. the leased-line example) * Fixed leased-line support * Note about /etc/ppp/pap-secrets in README -- Miquel van Smoorenburg Mon, 07 Oct 1996 13:28:21 +0200 portslave (1.06) cistron; urgency=low * Added support for portslave - over - telnetd. portslave now checks if the first argument starts with '-'. If so, it uses ttyname(0) to find the right entry in the server.cfg file. -- Miquel van Smoorenburg Wed, 02 Oct 1996 16:54:29 +0200 portslave (1.05) cistron; urgency=high * Fixed CLOCAL stuff (only ever set if port.dcd is 0). This works around a bug in the Comtrol Rocketport driver. * Added ChangeLog file. -- Miquel van Smoorenburg Tue, 01 Oct 1996 17:06:40 +0200 portslave-2010.04.19.1/docs/fido.txt0000664000000000000000000000201607522604511013571 0ustar Now PORTSLAVE contains ALPHA code for support incoming FidoNet calls. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Author: Andy Pershin Adapted for portslave 2002.01.19 by Dmitry Sergienko HOWTO: 1. ./configure --enable-fido ; make 2. Edit the configuration file for fidonet support. all.fidonet [yes|no] all.fidologin login all.fidopasswd Sec00r3 or sNN.fidonet [yes|no] sNN.fidologin login sNN.fidopasswd Sec00r3 3. Add the user `login' in YOUR system where RADIUS looking for. Example: useradd -g uucp -s /usr/lib/fidonet/bin/ifcico -c "FidoNet" -d /usr/lib/fidonet fidonet 4. Create .rhosts file in FidoNet's $HOME (rlogin) Example: echo "my.portslave.host.org" >/usr/lib/fidonet/.rhosts 5. Configure RADIUS server: fidonet Password="Sec00r3" Service-Type = Login-User, Login-Service = Rlogin, Login-IP-Host = your.fidonet.host.org portslave-2010.04.19.1/pslave.conf.50000664000000000000000000003402611354242251013466 0ustar .TH "pslave.conf" "5" "2010.03.30" "Russell Coker " "Portslave" .SH "NAME" .BR pslave.conf \- configuration file for portslave(8) .SH "FORMAT" A line that starts with '#' is a comment. Any other line is a configuration statement. Configuration statements may be extended to cover multiple lines with a '\\' character at the end of a line. .SH "OVERVIEW" In previous versions of Portslave there are two main types of configuration directives, global directives that start with .B 'conf.' and line directives starting with .B 'all.' or .B 'sXX.' The configuration directives were divided (somewhat arbitarily) into global directives that apply to all lines and line directives that may have different values for each line. This distinction makes no sense to me, so I have removed it. Now all directives can have different values for each line! This gives this version of Portslave many new configuration options that were previously absent. If a line starts with .B 'conf.' or .B 'all.' then it's value is a default value for all lines. If a line starts with .B 'sXX.' then it's value applies to the specified line (where 'XX' specifies the number of the 'NAS port' \- a non-negative number). This number is the command-line parameter used on the portslave command line. .SH "DATA TYPES" Configuration directives are all comprised of a name followed by a value. The value may be of type int, dynamic int, bool, string, enum, hostname, hostname service, IP number, IP number service, dynamic IP number, and chat\-script. .TP .B int A simple number. .TP .B dynamic int Number which may end in a '+' character to specify that the it is to have the port number added to it. .TP .B bool A boolean value, 0/no/false or 1/yes/true. .TP .B string A string may comprise multiple lines, non\-terminal lines must end with a '\\' character. Strings do not need quotes around them (double quotes around strings are accepted but ignored, useful if you want leading or trailing white\-space I guess). The null string representation is "". All the usual string escape sequences are supported, \\n for a new line, \\r for carriage return, ^D or ^d means the controll\-D sequence (character ASCII 4 EOT). .TP .B enum One of several string values that are internally translated to a number. .TP .B hostname Hostnames are resolved to IP addresses immediately upon startup! You must have your name server running before Portslave is started! .TP .B hostname service hostname and IP service (either a number or a name to be resolved from /etc/services). The IP service is optional, if it is specified then the IP address must be enclosed in "[" and "]". .TP .B IP number Simple dotted\-quad IP address. .TP .B dynamic IP number Dotted\-quad IP address which may end in a '+' character to specify that the IP address is to have the port number added to it. .SH "EXPANSION" Lines may be expanded in the following fashion: .B s{32-63}.tty tts/C{0-31} This means the same as the following: .B s32.tty tts/C0 .B s33.tty tts/C1 .B ... .B s63.tty tts/C31 .SH "ATTRIBUTES" .TP .B logpassword bool \- whether to write users' passwords to syslog (default no). .TP .B chat\-script A chat script is at it's simplest a series of .B expect send pairs. The system will expect a string and then send another string in response if/when it receives the expect string. An expect\-string may be of the form .B A\-B\-C in which case if the sub\-string .B A is not found due to timeout then the sub\-string .B B will be sent and then the sub\-string .B C will be expected. NB There must be exactly three parts to an expect-string that has sub-strings and they are to be delimited by "\-" characters. Also note that to wait for a "\-" you must escape it as "\\\-". The send string may have the following special escape sequences. "\\d" for a one second delay, "\\p" for a 100ms pause, "\\l" to lower DTR for one second, "\\c" to specify that the string is not to end with a "\\r" character, and "\\K" to send a break character. Also special strings may be inserted before the .B expect strings in any part of the chat script. The special strings are as follows: .B TIMEOUT XX to specify that the new timeout when waiting for an expect string is to be .B XX seconds. .B WAIT DCD to wait for the .B DCD line of the modem to be asserted. .B STATUS USER\-NAME HOST\-NAME writes an entry to the /var/run/utmp file with the user name field set to the first parameter (portslave uses "Incoming" and "Connected" as the default values for the first two phases of connecting). It also uses "%p:I.HANDSHAKE" as the default for the hostname. See ctlportslave for the use of this. .B ABORT XX to abort the connection if the string .B XX (which may contain multiple words surrounded by quotes) is received. .B SETVAR Z=XX to set the variable specified by the character .B Z to the text following the string .B XX (quote the entire .B Z=XX part if the string .B XX contains a space). The variable .B Z may be 'C' for the connect string, 'S' for the source of the call (from caller line identification), or 'D' for the number dialled (from CLI). Here is an example to recognise the connect strings from common configurations of Hayes compatible modems: SETVAR "C=CARRIER " SETVAR C+PROTOCOL: SETVAR C?CONNECT The first line does an unconditional assignment when the string "CARRIER " is found, the second appends data to the variable when the string "PROTOCOL" is found, and the third will do an assignment when the string "CONNECT" is found if the variable is empty. Note that in the variable assignment white-space preceeding the value is removed. .SH "GLOBAL DIRECTIVES" .TP .B hostname String \- Hostname of the current system. Defaults to the hostname returned by gethostname(). .TP .B loc_host IP number \- address for local end of SLIP and PPP connections, defaults to a DNS lookup of the value from .B hostname. .TP .B lockdir String \- Lock directory, defaults to /var/lock which is the directory for FSSTD compliant systems. If set to an empty string then it will turn off locking. .TP .B rlogin String \- Where to find the rlogin binary that accepts the \-i flag for specifying the local user\-name. Defaults to the location where we install rlogin\-radius. .TP .B telnet String \- Where to find telnet. This can just be the system telnet. Defaults to where telnet is detected on the local system. .TP .B ssh String \- Where to find ssh. This can just be the system SSH. Defaults to where ssh is detected on the local system. .TP .B pppd String \- Where to find our patched pppd that supports the libpsr.so library. Defaults to the location where we install pppd\-radius. .TP .B locallogins bool \- If you set this to true, you can login locally by putting a '!' before your loginname. Useful for emergencies when the RADIUS server is down. Setting this is a potential security risk! .TP .B allow_chap bool \- Set to true if you want CHAP authentication. Turned off by default at the moment because the chap code in pppd doesn't allow setting the IP address. .TP .B syslog hostname \- The host to send remote syslog data to. Leave empty for only local logging. .TP .B facility int \- The local facility number. A number from 0 to 7 inclusive means syslog facility local0 to local7. .TP .B filterdir string \- Directory where your scripts that set up IP filtering (typically using ipchains or iptables) are stored. To invoke them, just add the RADIUS\-attribute Framed\-Filter\-Id = "foo" to your profile, where foo is the name of script. Then the script will be run as: .B script .TP .B stripnames bool \- whether to remove a preceeding 'P', 'C', 'S', '!', or 'L' or a trailing '.slip', '.cslip', or '.ppp' before storing the user-name in the utmp. .TP .B tty string \- this is the only line directive that can't be used as an 'all.' or 'conf.' setting. It is used to specify the device file (either an absolute path or relative to /dev) that is used for the device. If you want devices /dev/tts/0 and /dev/ttr/5 to be NAS ports 1 and 2 respectively and have them use the default line settings (from the 'all' values) then you can use the following lines: s1.tty tts/0 s2.tty ttr/5 .TP .B debug int \- 0 means no debug output, 1 means some, 2 means all. 2 means lots of data! .TP .B sysutmp bool \- if true then log to utmp like a regular getty/login. Do not set this to false unless you really know what you are doing, it breaks ctlportslave (amoung other things). .TP .B syswtmp bool \- if true then log to wtmp like a regular getty/login (NB we will never log to wtmp if utmp logging is off). .TP .B utmpfrom string \- format of the utmp/wtmp FROM field. See the expansion directives section. The default value is "%p:%P.%3.%4", for ctlportslave to work properly the start of the string must be "%p:". .TP .B emumodem bool \- emulate a modem. This is for when Portslave is directly connected to a machine that thinks it is connected to a modem. Portslave will emulate a Hayes compatible modem. .TP .B porttype enum \- 'async', 'sync', 'isdn', 'isdn\-v120', or 'isdn\-v110'. If you don't understand this then you probably want 'async'. .TP .B authtype enum \- 'none', 'radius', 'tacacs', 'remote', 'local', 'radius/local', 'tacacs/local', 'local/radius', or 'local/tacacs' for which type of authentication to use. 'none' means that we just use the supplied user-name for logging purposes and don't talk to the RADIUS server on login. .TP .B radclient_config_file string \- file name for configuration file for radclient .TP .B radnullpass bool \- true means to accept RADIUS logins with a null password, false means to reject them. Default true. .TP .B tacauthhost1 tacauthhost2 hostname \- host names for the TACACS Authentication host if Portslave is compiled with TACACS support. .TP .B protocol enum \- 'login', 'rlogin', 'telnet', 'ssh1', 'ssh', 'slip', 'cslip', 'ppp', 'ppp_only', 'tcpclear', 'tcplogin', 'console', 'socket_client', 'socket_server', or 'socket_ssh'. Login is to exec /bin/login. Rlogin, telnet, and ssh are for executing those programs to login to other machines. Slip, cslip, and PPP are for running those IP connectivity protocols, ppp_only is for leased line configuration. Tcplogin and console are apparently not implemented, with tcpclear I have not been able to work out what it does. Contributions welcome! Default ppp. .TP .B host hostname \- default host for rlogin/telnet/ssh sessions. .TP .B rem_host dynamic IP number \- used as the client IP address if the RADIUS server doesn't send an IP address, or when it tells us to use a dynamic address. .TP .B netmask IP number \- in almost all cases it should be 255.255.255.255, leave it at that unless you really know what you are doing. .TP .B mtu int \- MTU for connection, 1500 is a good value as that's what Ethernet uses and most packets get routed over Ethernet in some way so 1500 avoids fragmentation and reduces the number of packets needed to transfer data. .TP .B mru int \- MRU for connection, generally should be the same as the MTU. .TP .B autoppp string \- PPP command\-line options to be used when we autodetect a PPP session. Note that the expansion directives apply. .TP .B pppopt string \- PPP command\-line options to be used when we have already authenticated the user and the service type is known to be PPP. Same format as autoppp. .TP .B issue string \- message that is issued on connect. Expansion directives are applied. .TP .B prompt string \- login prompt, default is "%h login: ". Expansion directives are applied. .TP .B term string \- terminal type for rlogin/telnet/ssh sessions. Defaults to vt100. .TP .B speed int \- port speed in bps. .TP .B socket_port dynamic int \- port number used for telnet targets. .TP .B parity enum \- 'none', 'odd', or 'even'. .TP .B stopbits int \- number of stop bits. .TP .B datasize int \- size of a character 5, 6, 7, or 8 bits. .TP .B dcd bool \- use the DCD line or not (this sets CLOCAL if off). This means that the session will get hung up if the modem hangs up. .TP .B flow enum \- 'none', 'hard', or 'soft'. Hardware (RTS/CTS), software (XON/XOFF AKA ^S/^Q), or no flow control. .TP .B initchat chat\-script \- the chat script for initialising the modem and answering. Needs much more documentation on this. .TP .B radclient_config_file string \- configuration file for radclient (default /etc/portslave/radclient.conf). .TP .B login_time string \- the times that are allowed for logins. .TP .B login_time_limited bool \- if true then the maximum length of the call will be determined by the value of the login_time setting. .SH "EXPANSION DIRECTIVES" These directives can be used for the format of the utmp/wtmp field, for the autoppp, pppopt, issue, prompt fields, and others. .TP .B %l login name .TP .B %L stripped login name .TP .B %p NAS port number .TP .B %P protocol .TP .B %b port speed .TP .B %H host for telnet/ssh connections .TP .B %i local IP .TP .B %j remote IP .TP .B %1 first byte (MSB) of remote IP .TP .B %2 second byte of remote IP .TP .B %3 third byte of remote IP .TP .B %4 fourth byte (LSB) of remote IP .TP .B %c connect\-info .TP .B %m netmask .TP .B %M .B multilink if the RADIUS server has PW_NAS_PORT_LIMIT set to > 1, otherwise empty string .TP .B %t MTU .TP .B %r MRU .TP .B %I idle timeout .TP .B %T session timeout .TP .B %h hostname .TP .B %d dcd setting, expands to "modem" if DCD line is to be used or to "local" if it isn't. Put this on the ppp command line to give it the right setting to match the value of the "dcd" attribute. .TP .B %% % .SH "BUGS" The documentation section for protocol in the line directives section needs to be improved. I intend to do so as soon as I work out what the code does. The initchat option needs heaps more documentation. As soon as I figure it out... The realm section needs to be improved, to do this I have to go through the code and comment what it does so I can understand it. .SH "AUTHOR" This man page was written by Russell Coker . May be freely used and distributed without restriction. .SH "SEE ALSO" .BR portslave (8), .BR pppd (8), .BR cltportslave (1) .BR http://doc.coker.com.au/projects/portslave/ portslave-2010.04.19.1/configure.in0000664000000000000000000001017511354242054013473 0ustar dnl Process this file with autoconf to produce a configure script. AC_INIT(src/lib.c) AC_SUBST(version) version="2010.03.30" dnl Checks for programs. AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_RANLIB dnl Sets /usr as the base for installation instead of /usr/local dnl AC_PREFIX_DEFAULT(/usr) if [[ "$prefix" = "NONE" ]]; then prefix=$ac_default_prefix fi if [[ "$exec_prefix" = "NONE" ]]; then exec_prefix=$prefix fi if [[ "$bindir" = "\${exec_prefix}/bin" ]]; then bindir=$exec_prefix/bin fi if [[ "$sbindir" = "\${exec_prefix}/sbin" ]]; then sbindir=$exec_prefix/sbin fi if [[ "$libdir" = "\${exec_prefix}/lib" ]]; then libdir=$exec_prefix/lib fi if [[ "$sysconfdir" = "\${prefix}/etc" ]]; then if [[ "$prefix" = "/usr" ]]; then sysconfdir=/etc else sysconfdir=$prefix/etc fi fi AC_SUBST(pppdradius) AC_ARG_WITH(pppdradius, [ --with-pppdradius=pathname specifies full path to pppd-radius [$sbindir/pppd-radius] ], pppdradius=$withval, pppdradius="$sbindir/pppd-radius") AC_SUBST(stripping) AC_ARG_ENABLE(stripping, [ --disable-stripping disables stripping of installed binaries], STRIPPING=$strippingval, STRIPPING=no) if [[ ! "$STRIPPING" = "no" ]]; then stripping="" else stripping="-s" fi echo $DEB_BUILD_OPTIONS | grep -q nostrip if [[ "$?" = "0" ]]; then stripping="" fi AC_ARG_ENABLE(debug, [ --enable-debug enables debug code generation for binaries], debug=-g, debug="") echo $DEB_BUILD_OPTIONS | grep -q debug if [[ "$?" = "0" ]]; then debug=-g fi AC_SUBST(callback) AC_SUBST(callback_patch) AC_ARG_ENABLE(callback, [ --enable-callback enables compilation of callback PPP code], callback=y, callback="") if [[ "$callback" = "y" ]]; then callback="#define PORTSLAVE_CALLBACK" callback_patch=../patches/ppp-2.4.1-CBCPs.asp.patch fi AC_SUBST(fido) AC_ARG_ENABLE(fido, [ --enable-fido enables compilation of Fidonet support code], fido=y, fido="") if [[ "$fido" = "y" ]]; then fido="#define HAVE_FIDO" fi AC_SUBST(assignment) AC_SUBST(no_local_ip) AC_ARG_ENABLE(assignment, [ --enable-assignment enables client assignment of IP addresses], assignment=y, assignment="") if [[ "$assignment" = "y" ]]; then assignment="#define PORTSLAVE_CLIENT_IP_RULES" no_local_ip="#define ALLOW_NO_LOCAL_IP" fi AC_SUBST(ipv6) AC_ARG_ENABLE(ipv6, [ --enable-ipv6 enables IPv6], ipv6=y, ipv6="") if [[ "$ipv6" = "y" ]]; then ipv6="#define HAVE_IPV6" fi AC_SUBST(shadow) AC_ARG_ENABLE(shadow, [ --enable-shadow enables shadow password support ], shadow=y, shadow="") if [[ "$shadow" = "y" ]]; then shadow="#define HAS_SHADOW" fi dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T AC_SUBST(rundir) AC_ARG_WITH(rundir, [ --with-rundir=DIR specifies directory for pid files etc [/var/run] ], rundir=$withval, rundir="/var/run") inst_libdir='${PREFIX}'$libdir AC_SUBST(radclient_cfg) AC_ARG_WITH(radclient_cfg, [ --with-radclient-cfg=file specifies default radclient config file ], radclient_cfg=$withval, radclient_cfg="$sysconfdir/radiusclient.conf") AC_SUBST(pppdir) pppdir=ppp-2.4.1 AC_SUBST(route) AC_PATH_PROG(route, "route", "/sbin/route", "$PATH:/sbin:/usr/sbin") AC_SUBST(ifconfig) AC_PATH_PROG(ifconfig, "ifconfig", "/sbin/ifconfig", "$PATH:/sbin:/usr/sbin") AC_SUBST(arp) AC_PATH_PROG(arp, "arp", "/usr/sbin/arp", "$PATH:/sbin:/usr/sbin") AC_SUBST(telnet) AC_PATH_PROG(telnet, "telnet", "/usr/bin/telnet", "$PATH") AC_SUBST(ssh) AC_PATH_PROG(ssh, "ssh", "/usr/bin/ssh", "$PATH") AC_SUBST(rlogin) AC_PATH_PROG(rlogin, "rlogin", "/usr/bin/rlogin", "$PATH") dnl defined if UT_HOSTSIZE > 23 AC_SUBST(bigutmp) AC_TRY_COMPILE([#include ] , [char foo[UT_HOSTSIZE - 23];] , bigutmp=yes) if [[ "$bigutmp" = "yes" ]]; then bigutmp="#define HAVE_BIGUTMP" fi AC_SUBST(pppsourcedir) if [[ -f $pppdir.t*gz ]]; then pppsourcedir="." else pppsourcedir=".." fi AC_SUBST(CFLAGS) CFLAGS="-O2 $debug -Wall -W -Wshadow -Wpointer-arith -Wwrite-strings -pedantic" AC_OUTPUT(Makefile pslave_cfg.h pslave.conf portslave.8 portslave.spec src/Makefile extract_and_patch) portslave-2010.04.19.1/sh.common0000664000000000000000000001067307411405576013022 0ustar ## ## This file is part of shtool and free software; you can redistribute ## it and/or modify it under the terms of the GNU General Public ## License as published by the Free Software Foundation; either version ## 2 of the License, or (at your option) any later version. ## ## This file is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ## USA, or contact Ralf S. Engelschall . ## ## ## COMMON UTILITY CODE ## # determine name of tool if [ ".$tool" != . ]; then # used inside shtool script toolcmd="$0 $tool" toolcmdhelp="shtool $tool" msgprefix="shtool:$tool" else # used as standalone script toolcmd="$0" toolcmdhelp="sh $0" msgprefix="$str_tool" fi # parse argument specification string eval `echo $arg_spec |\ sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` # parse option specification string eval `echo h.$opt_spec |\ sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` # interate over argument line opt_PREV='' while [ $# -gt 0 ]; do # special option stops processing if [ ".$1" = ".--" ]; then shift break fi # determine option and argument opt_ARG_OK=no if [ ".$opt_PREV" != . ]; then # merge previous seen option with argument opt_OPT="$opt_PREV" opt_ARG="$1" opt_ARG_OK=yes opt_PREV='' else # split argument into option and argument case "$1" in -[a-zA-Z0-9]*) eval `echo "x$1" |\ sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ -e 's/";\(.*\)$/"; opt_ARG="\1"/'` ;; -[a-zA-Z0-9]) opt_OPT=`echo "x$1" | cut -c3-` opt_ARG='' ;; *) break ;; esac fi # eat up option shift # determine whether option needs an argument eval "opt_MODE=\$opt_MODE_${opt_OPT}" if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then opt_PREV="$opt_OPT" continue fi fi # process option case $opt_MODE in '.' ) # boolean option eval "opt_${opt_OPT}=yes" ;; ':' ) # option with argument (multiple occurances override) eval "opt_${opt_OPT}=\"\$opt_ARG\"" ;; '+' ) # option with argument (multiple occurances append) eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\"" ;; * ) echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 exit 1 ;; esac done if [ ".$opt_PREV" != . ]; then echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 exit 1 fi # process help option if [ ".$opt_h" = .yes ]; then echo "Usage: $toolcmdhelp $str_usage" exit 0 fi # complain about incorrect number of arguments case $arg_MODE in '=' ) if [ $# -ne $arg_NUMS ]; then echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 exit 1 fi ;; '+' ) if [ $# -lt $arg_NUMS ]; then echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 exit 1 fi ;; esac # establish a temporary file on request if [ ".$gen_tmpfile" = .yes ]; then if [ ".$TMPDIR" != . ]; then tmpdir="$TMPDIR" elif [ ".$TEMPDIR" != . ]; then tmpdir="$TEMPDIR" else tmpdir="/tmp" fi tmpfile="$tmpdir/.shtool.$$" rm -f $tmpfile >/dev/null 2>&1 touch $tmpfile fi portslave-2010.04.19.1/pslave_cfg.h.in0000664000000000000000000000160710027273672014057 0ustar #ifndef __pslave_cfg_h #define __pslave_cfg_h @shadow@ @bigutmp@ #define PORTSLAVE_VERSION "@version@" @callback@ @assignment@ @no_local_ip@ @ipv6@ @fido@ #define RAD_ID_FILE "@rundir@/radius.id" #define PID_DIR "@rundir@" #define RAD_SESSIONID_FILE "@rundir@/radsession.id" #define CONFFILE "@sysconfdir@/pslave.conf" #define SYSCONFDIR "@sysconfdir@" #define RADCLIENT_CFG "@radclient_cfg@" #define PATH_ROUTE "@route@" #define PATH_IFCONFIG "@ifconfig@" #define PATH_ARP "@arp@" #define PATH_TELNET "@telnet@" #define PATH_SSH "@ssh@" #define PATH_RLOGIN "@rlogin@" #define PATH_PPP_RADIUS "@pppdradius@" #define BINDIR "@bindir@" #define SBIN_DIR "@sbindir@" /* Amount of seconds to sleep between SLIP/CSLIP traffic stat querys */ /* Less time == more load but better total accuracy. Does not effect PPP. */ #define STATS_SLEEP 3 #include #endif /* __pslave_cfg_h */ portslave-2010.04.19.1/patches/0000775000000000000000000000000007420112440012577 5ustar portslave-2010.04.19.1/patches/ppp-2.4.1-alex/0000775000000000000000000000000007412472207015000 5ustar portslave-2010.04.19.1/patches/ppp-2.4.1-alex/ppp-2.4.1-warnings.patch0000664000000000000000000000170307411456002021101 0ustar diff -ru ppp-2.4.1/pppd/auth.c ppp-patched/pppd/auth.c --- ppp-2.4.1/pppd/auth.c Mon Oct 29 17:24:45 2001 +++ ppp-patched/pppd/auth.c Mon Oct 29 17:29:45 2001 @@ -64,6 +64,7 @@ #define PW_PPP PW_LOGIN #endif #endif +#include #include "pppd.h" #include "fsm.h" diff -ru ppp-2.4.1/pppd/md5.c ppp-patched/pppd/md5.c --- ppp-2.4.1/pppd/md5.c Mon Oct 29 17:30:13 2001 +++ ppp-patched/pppd/md5.c Mon Oct 29 17:26:46 2001 @@ -33,6 +33,7 @@ *********************************************************************** */ +#include #include "md5.h" /* Binary files ppp-2.4.1/pppd/pppd and ppp-patched/pppd/pppd differ diff -ru ppp-2.4.1/pppd/utils.c ppp-patched/pppd/utils.c --- ppp-2.4.1/pppd/utils.c Mon Oct 29 17:30:13 2001 +++ ppp-patched/pppd/utils.c Mon Oct 29 17:26:46 2001 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include portslave-2010.04.19.1/patches/ppp-2.4.1-alex/ppp-2.3.11-pam_session.patch0000664000000000000000000000061007411456002021645 0ustar --- ppp-2.4.0b4.orig/pppd/auth.c +++ ppp-2.4.0b4/pppd/auth.c @@ -1120,7 +1120,7 @@ if (pam_error == PAM_SUCCESS && !PAM_error) { pam_error = pam_acct_mgmt (pamh, PAM_SILENT); if (pam_error == PAM_SUCCESS) - pam_open_session (pamh, PAM_SILENT); + pam_error = pam_open_session (pamh, PAM_SILENT); } *msg = (char *) pam_strerror (pamh, pam_error); portslave-2010.04.19.1/patches/ppp-2.4.1-alex/ppp-2.4.0-reap.patch0000664000000000000000000000071607411456002020202 0ustar --- ppp-2.4.0/pppd/main.c.reap Thu Jul 6 07:17:02 2000 +++ ppp-2.4.0/pppd/main.c Thu Nov 9 17:41:30 2000 @@ -1579,7 +1579,8 @@ (chp? chp->prog: "??"), pid, WTERMSIG(status)); } else if (debug) dbglog("Script %s finished (pid %d), status = 0x%x", - (chp? chp->prog: "??"), pid, status); + (chp? chp->prog: "??"), pid, + WIFEXITED(status) ? WEXITSTATUS(status) : status); if (chp && chp->done) (*chp->done)(chp->arg); if (chp) portslave-2010.04.19.1/patches/ppp-2.4.1-CBCPs.asp.patch0000664000000000000000000013141407411463602016546 0ustar diff -ruN ppp-2.4.1/README.cbcp ppp-2.4.1-patched/README.cbcp --- ppp-2.4.1/README.cbcp Thu May 22 07:48:50 1997 +++ ppp-2.4.1-patched/README.cbcp Sun Dec 16 14:26:37 2001 @@ -1,7 +1,8 @@ Microsoft Call Back Configuration Protocol. by Pedro Roque Marques (updated by Paul Mackerras) - + (updated by Bolke de Bruin, bolke@xs4all.nl) + The CBCP is a method by which the Microsoft Windows NT Server may implement additional security. It is possible to configure the server in such a manner so as to require that the client systems which @@ -11,10 +12,6 @@ It is a requirement of servers so configured that the protocol be exchanged. -So, this set of patches may be applied to the pppd process to enable -the cbcp client *only* portion of the specification. It is primarily -meant to permit connection with Windows NT Servers. - The ietf-working specification may be obtained from ftp.microsoft.com in the developr/rfc directory. @@ -22,76 +19,17 @@ extended to permit the callback operation. For this reason, these patches are not 'part' of pppd but are an adjunct to the code. -To enable CBCP support, all that is required is to change the -appropriate Makefile in the pppd subdirectory to add "-DCBCP_SUPPORT" -to the CFLAGS definition and add cbcp.o to the list of object files, -and then recompile pppd. The patch below does this for Makefile.bsd -and Makefile.linux. - - ---------------------------------cut here------------------------------- -diff -r -c ppp-2.3.orig/pppd/Makefile.bsd ppp-2.3/pppd/Makefile.bsd -*** ppp-2.3.orig/pppd/Makefile.bsd Tue Oct 8 13:33:33 1996 ---- ppp-2.3/pppd/Makefile.bsd Fri Apr 11 23:59:15 1997 -*************** -*** 4,14 **** - # -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.. -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 - MAN= pppd.cat8 - MAN8= pppd.8 - BINMODE=4555 ---- 4,14 ---- - # -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+= -I.. -DHAVE_PATHS_H -D_BITYPES -DCBCP_SUPPORT - - 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 cbcp.c - MAN= pppd.cat8 - MAN8= pppd.8 - BINMODE=4555 -diff -r -c ppp-2.3.orig/pppd/Makefile.linux ppp-2.3/pppd/Makefile.linux -*** ppp-2.3.orig/pppd/Makefile.linux Tue Oct 8 15:42:41 1996 ---- ppp-2.3/pppd/Makefile.linux Sat Apr 12 00:02:28 1997 -*************** -*** 14,20 **** - 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 - ---- 14,20 ---- - 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 cbcp.o - - all: pppd - -*************** -*** 36,42 **** - #INCLUDE_DIRS= -I/usr/include -I.. - INCLUDE_DIRS= - -! COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE - - CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) - ---- 36,42 ---- - #INCLUDE_DIRS= -I/usr/include -I.. - INCLUDE_DIRS= - -! COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DCBCP_SUPPORT - - CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) - +The configuration files in this setup are already configured to use +CBCP both as a server (when specified with "callback server") and +client (callback ). I sure would like some info how it is +working especially client side as I did not test that. + +Also you may have noticed that a few other patches exist for older +versions of ppp (2.3.5, 2.3.7, 2.3.10) I have made these comply +with the new 2.4.0 and I *do* hope it gets finally in the main +branch, because I know a lot of people are stuck with NT-RAS, and +would gladly replace it with a *nix/*bsd solution. + +Some work still has to be done. Client input should be checked for +should be shell escaped (SECURITY FLAW!), code cleanups should be made +etc etc. \ No newline at end of file diff -ruN ppp-2.4.1/chat/Makefile.linux ppp-2.4.1-patched/chat/Makefile.linux --- ppp-2.4.1/chat/Makefile.linux Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/chat/Makefile.linux Sun Dec 16 14:26:37 2001 @@ -1,6 +1,6 @@ # $Id: Makefile.linux,v 1.9 1999/08/13 01:54:32 paulus Exp $ -CDEF1= -DTERMIOS # Use the termios structure +#CDEF1= -DTERMIOS # Use the termios structure CDEF2= -DSIGTYPE=void # Standard definition CDEF3= -UNO_SLEEP # Use the usleep function CDEF4= -DFNDELAY=O_NDELAY # Old name value diff -ruN ppp-2.4.1/chat/chat.c ppp-2.4.1-patched/chat/chat.c --- ppp-2.4.1/chat/chat.c Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/chat/chat.c Sun Dec 16 14:26:37 2001 @@ -590,10 +590,13 @@ { #if defined(get_term_param) term_parms t; - - if (get_term_param (&t) < 0) - fatal(2, "Can't get terminal parameters: %m"); - + int ctl; + + ctl = get_term_param (&t); + if (ctl < 0) { + syslog(LOG_NOTICE, "Could not get FD: %s", strerror(errno)); + fatal(2, "Can't get terminal parameters: %m"); + } saved_tty_parameters = t; have_tty_parameters = 1; diff -ruN ppp-2.4.1/etc.ppp/callback-client ppp-2.4.1-patched/etc.ppp/callback-client --- ppp-2.4.1/etc.ppp/callback-client Thu Jan 1 01:00:00 1970 +++ ppp-2.4.1-patched/etc.ppp/callback-client Sun Dec 16 14:26:37 2001 @@ -0,0 +1,9 @@ +#!/bin/sh +# Script callback-client +# Script parameters: delay time in seconds + +DELAY="$1" + +/usr/sbin/chat -v -t 2 "" \d+++\d\c OK ATH0 OK +sleep $DELAY s +/usr/sbin/chat -v "" ATZ OK "" RING ATA CONNECT diff -ruN ppp-2.4.1/etc.ppp/callback-server ppp-2.4.1-patched/etc.ppp/callback-server --- ppp-2.4.1/etc.ppp/callback-server Thu Jan 1 01:00:00 1970 +++ ppp-2.4.1-patched/etc.ppp/callback-server Sun Dec 16 14:26:37 2001 @@ -0,0 +1,10 @@ +#!/bin/sh +# Script callback-server +# Script parameters: delay time in seconds, callback number + +DELAY="$1" +NUMBER="$2" + +/usr/sbin/chat -v -t 2 "" \d+++\d\c OK ATH0 OK +sleep $DELAY s +/usr/sbin/chat -v "" ATZ OK ATD$NUMBER CONNECT diff -ruN ppp-2.4.1/etc.ppp/callback-users ppp-2.4.1-patched/etc.ppp/callback-users --- ppp-2.4.1/etc.ppp/callback-users Thu Jan 1 01:00:00 1970 +++ ppp-2.4.1-patched/etc.ppp/callback-users Sun Dec 16 14:26:37 2001 @@ -0,0 +1,10 @@ +# User list for callback +# Username option +# option - no callback +# option * or empty user definied +# option other admin definied: this number +# in username * and ? wildcars valid, callback uses the best fit +# Examples: +# zotyo 67435 # user zotyo admin definied, number 67453 +# gates - # gates not called back +* \ No newline at end of file diff -ruN ppp-2.4.1/linux/Makefile.top ppp-2.4.1-patched/linux/Makefile.top --- ppp-2.4.1/linux/Makefile.top Mon Apr 17 12:39:26 2000 +++ ppp-2.4.1-patched/linux/Makefile.top Sun Dec 16 14:26:37 2001 @@ -2,7 +2,7 @@ BINDIR = $(DESTDIR)/usr/sbin -MANDIR = $(DESTDIR)/usr/man +MANDIR = $(DESTDIR)/usr/share/man ETCDIR = $(DESTDIR)/etc/ppp # uid 0 = root diff -ruN ppp-2.4.1/pppd/Makefile.linux ppp-2.4.1-patched/pppd/Makefile.linux --- ppp-2.4.1/pppd/Makefile.linux Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/Makefile.linux Sun Dec 16 14:26:37 2001 @@ -15,7 +15,7 @@ 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 utils.o sys-linux.o ipxcp.o multilink.o \ - tdb.o tty.o + tdb.o tty.o cbcp.o all: pppd @@ -56,7 +56,7 @@ INCLUDE_DIRS= -I../include -COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP +COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP -DCBCP_SUPPORT CFLAGS= $(UDEB_CFLAGS) $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) diff -ruN ppp-2.4.1/pppd/auth.c ppp-2.4.1-patched/pppd/auth.c --- ppp-2.4.1/pppd/auth.c Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/auth.c Sun Dec 16 14:26:37 2001 @@ -173,7 +173,6 @@ /* 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 **)); @@ -500,8 +499,7 @@ /* * Proceed to the network phase. */ -static void -network_phase(unit) +void network_phase(unit) int unit; { lcp_options *go = &lcp_gotoptions[unit]; @@ -521,7 +519,8 @@ /* * If we negotiated callback, do it now. */ - if (go->neg_cbcp) { + if (((go->neg_cbcp) || (lcp_hisoptions[unit].neg_cbcp)) + && (phase != PHASE_CALLBACK)) { new_phase(PHASE_CALLBACK); (*cbcp_protent.open)(unit); return; diff -ruN ppp-2.4.1/pppd/cbcp.c ppp-2.4.1-patched/pppd/cbcp.c --- ppp-2.4.1/pppd/cbcp.c Thu Mar 8 06:11:10 2001 +++ ppp-2.4.1-patched/pppd/cbcp.c Sun Dec 16 14:26:44 2001 @@ -2,6 +2,8 @@ * cbcp - Call Back Configuration Protocol. * * Copyright (c) 1995 Pedro Roque Marques + * Copyright (c) 2001 Bolke de Bruin + * * All rights reserved. * * Redistribution and use in source and binary forms are permitted @@ -18,30 +20,23 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: cbcp.c,v 1.11 2001/03/08 05:11:10 paulus Exp $" +#ifndef lint +static const char rcsid[] = "$Id: cbcp.c,v 1.14 2001/01/21 05:50:26 bolke Exp $"; +#endif #include #include #include #include +#include +#include #include "pppd.h" #include "cbcp.h" #include "fsm.h" #include "lcp.h" - -static const char rcsid[] = RCSID; - -/* - * Options. - */ -static int setcbcp __P((char **)); - -static option_t cbcp_option_list[] = { - { "callback", o_special, setcbcp, - "Ask for callback", OPT_PRIO | OPT_A2STRVAL, &cbcp[0].us_number }, - { NULL } -}; +#include "ipcp.h" +#include "pathnames.h" /* * Protocol entry points. @@ -69,8 +64,6 @@ 0, "CBCP", NULL, - cbcp_option_list, - NULL, NULL, NULL }; @@ -79,26 +72,23 @@ /* internal prototypes */ +static void cbcp_sendreq __P((void *arg)); static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len)); -static void cbcp_resp __P((cbcp_state *us)); -static void cbcp_up __P((cbcp_state *us)); +static void cbcp_sendresp __P((cbcp_state *us)); +static void cbcp_recvresp __P((cbcp_state *us, char *pckt, int len)); +static void cbcp_sendack __P((void *)); static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len)); + static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len)); +static void cbcp_make_options __P((int unit)); +static int cbcp_check_user __P((char *user, char *mask)); +static void cbcp_start_callback __P((cbcp_state *us)); +static void cbcp_up __P((cbcp_state *us)); -/* option processing */ -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); -} + +cbcp_state *stop_iface = NULL; + +void (*cbcp_init_hook) __P((cbcp_state *)) = NULL; /* init state */ static void @@ -110,7 +100,6 @@ us = &cbcp[iface]; memset(us, 0, sizeof(cbcp_state)); us->us_unit = iface; - us->us_type |= (1 << CB_CONF_NO); } /* lower layer is up */ @@ -120,18 +109,19 @@ { cbcp_state *us = &cbcp[iface]; - dbglog("cbcp_lowerup"); - dbglog("want: %d", us->us_type); - - if (us->us_type == CB_CONF_USER) - dbglog("phone no: %s", us->us_number); + CBCPDEBUG((LOG_DEBUG, "cbcp_lowerup")); + CBCPDEBUG((LOG_DEBUG, "want: %d", us->us_type)); } +/* CBCP indulhat: kliens oldal eseten nincs feladat, + szerver oldalon atkuldeni a valszthato opciokat */ static void cbcp_open(unit) int unit; { - dbglog("cbcp_open"); + CBCPDEBUG((LOG_DEBUG, "cbcp_open")); + if (lcp_hisoptions[unit].neg_cbcp) + cbcp_make_options(unit); } /* process an incomming packet */ @@ -146,11 +136,13 @@ u_short len; cbcp_state *us = &cbcp[unit]; + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *his = &lcp_hisoptions[unit]; inp = inpacket; if (pktlen < CBCP_MINLEN) { - error("CBCP packet is too small"); + syslog(LOG_ERR, "CBCP packet is too small"); return; } @@ -160,7 +152,7 @@ #if 0 if (len > pktlen) { - error("CBCP packet: invalid length"); + syslog(LOG_ERR, "CBCP packet: invalid length"); return; } #endif @@ -169,17 +161,36 @@ switch(code) { case CBCP_REQ: + if ( !go->neg_cbcp ) + { + syslog(LOG_ERR, "CBCP received CBCP_REQ, but CBCP running in server mode!"); + return; + } us->us_id = id; cbcp_recvreq(us, inp, len); break; case CBCP_RESP: - dbglog("CBCP_RESP received"); + if ( !his->neg_cbcp ) + { + syslog(LOG_ERR, "CBCP received CBCP_RESP, but CBCP running in client mode!"); + return; + } + if (id != us->us_id) + syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d", + us->us_id, id); + + cbcp_recvresp(us, inp, len); break; case CBCP_ACK: + if ( !go->neg_cbcp ) + { + syslog(LOG_ERR, "CBCP received CBCP_ACK, but CBCP running in server mode!"); + return; + } if (id != us->us_id) - dbglog("id doesn't match: expected %d recv %d", + syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d", us->us_id, id); cbcp_recvack(us, inp, len); @@ -259,13 +270,14 @@ printer(arg, " delay = %d", delay); } - if (olen > 3) { + if (olen > 4) { int addrt; char str[256]; GETCHAR(addrt, p); memcpy(str, p, olen - 4); str[olen - 4] = 0; + p += olen - 4; printer(arg, " number = %s", str); } printer(arg, ">"); @@ -291,41 +303,40 @@ char *pckt; int pcktlen; { - u_char type, opt_len, delay, addr_type; + u_char type, opt_len, addr_type; char address[256]; int len = pcktlen; address[0] = 0; while (len) { - dbglog("length: %d", len); - GETCHAR(type, pckt); GETCHAR(opt_len, pckt); + us->us_delay =0; if (opt_len > 2) - GETCHAR(delay, pckt); + GETCHAR(us->us_delay, pckt); us->us_allowed |= (1 << type); switch(type) { case CB_CONF_NO: - dbglog("no callback allowed"); + CBCPDEBUG((LOG_DEBUG, "no callback allowed")); break; case CB_CONF_USER: - dbglog("user callback allowed"); + CBCPDEBUG((LOG_DEBUG, "user callback allowed")); if (opt_len > 4) { GETCHAR(addr_type, pckt); memcpy(address, pckt, opt_len - 4); address[opt_len - 4] = 0; if (address[0]) - dbglog("address: %s", address); + CBCPDEBUG((LOG_DEBUG, "address: %s", address)); } break; case CB_CONF_ADMIN: - dbglog("user admin defined allowed"); + CBCPDEBUG((LOG_DEBUG, "user admin defined allowed")); break; case CB_CONF_LIST: @@ -334,60 +345,64 @@ len -= opt_len; } - cbcp_resp(us); + cbcp_sendresp(us); } static void -cbcp_resp(us) +cbcp_sendresp(us) cbcp_state *us; { - u_char cb_type; + u_char cb_allowed; u_char buf[256]; u_char *bufp = buf; int len = 0; - cb_type = us->us_allowed & us->us_type; - dbglog("cbcp_resp cb_type=%d", cb_type); + cb_allowed = us->us_allowed; + CBCPDEBUG((LOG_DEBUG, "cbcp_sendresp: available options: %d", cb_allowed)); #if 0 - if (!cb_type) + if (!cb_allowed) lcp_down(us->us_unit); #endif - if (cb_type & ( 1 << CB_CONF_USER ) ) { - dbglog("cbcp_resp CONF_USER"); + if (cb_allowed & ( 1 << CB_CONF_USER ) ) { /* The best metod :-) */ + us->us_type= ( 1 << CB_CONF_USER ); + CBCPDEBUG((LOG_DEBUG, "cbcp_sendresp CONF_USER")); PUTCHAR(CB_CONF_USER, bufp); len = 3 + 1 + strlen(us->us_number) + 1; PUTCHAR(len , bufp); - PUTCHAR(5, bufp); /* delay */ + PUTCHAR(us->us_delay, bufp); PUTCHAR(1, bufp); BCOPY(us->us_number, bufp, strlen(us->us_number) + 1); cbcp_send(us, CBCP_RESP, buf, len); return; } - if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { - dbglog("cbcp_resp CONF_ADMIN"); + if (cb_allowed & ( 1 << CB_CONF_ADMIN ) ) { + us->us_type= ( 1 << CB_CONF_ADMIN ); + CBCPDEBUG((LOG_DEBUG, "cbcp_sendresp CONF_ADMIN")); PUTCHAR(CB_CONF_ADMIN, bufp); len = 3; - PUTCHAR(len, bufp); - PUTCHAR(5, bufp); /* delay */ + PUTCHAR(len , bufp); + PUTCHAR(us->us_delay, bufp); cbcp_send(us, CBCP_RESP, buf, len); return; } - if (cb_type & ( 1 << CB_CONF_NO ) ) { - dbglog("cbcp_resp CONF_NO"); + if (cb_allowed & ( 1 << CB_CONF_NO ) ) { + us->us_type= ( 1 << CB_CONF_NO ); + CBCPDEBUG((LOG_DEBUG, "cbcp_sendresp CONF_NO")); PUTCHAR(CB_CONF_NO, bufp); len = 3; PUTCHAR(len , bufp); PUTCHAR(0, bufp); cbcp_send(us, CBCP_RESP, buf, len); - start_networks(); return; } + syslog(LOG_WARNING, "cbcp_sendresp: no usable options available!"); } +/* Send the packet */ static void cbcp_send(us, code, buf, len) cbcp_state *us; @@ -414,43 +429,430 @@ output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } +/* Received Ack */ static void cbcp_recvack(us, pckt, len) cbcp_state *us; char *pckt; int len; { - u_char type, delay, addr_type; + u_char type, addr_type; int opt_len; char address[256]; + stop_iface = us; + if (len) { GETCHAR(type, pckt); GETCHAR(opt_len, pckt); if (opt_len > 2) - GETCHAR(delay, pckt); + GETCHAR(us->us_delay, pckt); if (opt_len > 4) { GETCHAR(addr_type, pckt); memcpy(address, pckt, opt_len - 4); address[opt_len - 4] = 0; if (address[0]) - dbglog("peer will call: %s", address); + CBCPDEBUG((LOG_DEBUG, "peer will call: %s", address)); } - if (type == CB_CONF_NO) - return; + if (type != CB_CONF_NO) + { + callback_in_progress = us->us_unit + 1; + callback_in_progress |= CBCP_CLIENT; + cbcp_up(us); + } + else + network_phase(us->us_unit); + } + else + syslog(LOG_DEBUG, "cbcp: received bad ack - packet too small"); + + +} + +/* Make options + if auth req, options from callback-users file, else use CBCP_CONF_USER */ +static void +cbcp_make_options (unit) + int unit; +{ + cbcp_state *us = &cbcp[unit]; + FILE *userfile; + struct stat sbuf; + int best_fit, got_fit, newline; + char uname[ 256 ], option[ 256 ]; + + us->us_id = 1; + us->us_count = 0; + us->us_delay = 5; /* Default delay 5 seconds */ + if ( *peer_authname ) { /* Username available */ + userfile = fopen( _PATH_CBCP_USERS, "r" ); + if ( userfile == NULL ){ + syslog( LOG_ERR, "Can't open callback user file: %s %m", + _PATH_CBCP_USERS ); + syslog( LOG_WARNING, "Allow user definied callback." ); + us->us_allowed = ( 1 << CB_CONF_USER ); + }else + { + if ( fstat(fileno(userfile), &sbuf) < 0) { + syslog(LOG_WARNING, "Cannot stat userfile file %s: %m", + _PATH_CBCP_USERS ); + } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { + syslog(LOG_WARNING, "Warning - user file %s has world and/or group access", + _PATH_CBCP_USERS ); + } + + us->us_allowed = ( 1 << CB_CONF_NO ); /* Assume, no callback allowed */ + + if (getword(userfile, uname, &newline, _PATH_CBCP_USERS)){ /* file not empty */ + newline = 1; + best_fit = 0; + *option = 0; + for (;;) { + /* + * Skip until we find a word at the start of a line. + */ + while (!newline && getword(userfile, uname, + &newline, _PATH_CBCP_USERS)) + ; + if (!newline) + break; /* got to end of file */ + + /* + * Got a user - check if it's a match or a wildcard. + */ + got_fit = cbcp_check_user( peer_authname, uname ); + if ( got_fit <= best_fit ){ + newline = 0; + continue; + } + + /* Read the options */ + best_fit = got_fit; + if (getword(userfile, option, &newline, _PATH_CBCP_USERS)) + break; + + if ( newline ) + *option = 0; + + if ( best_fit == 100 ) + break; + } + } + + switch ( *option ){ + case '-' : us->us_allowed = ( 1 << CB_CONF_NO ); break; + case '*' : + case 0 : us->us_allowed = ( 1 << CB_CONF_USER ); break; + default : us->us_allowed = ( 1 << CB_CONF_ADMIN ); + us->us_number = strdup( option ); break; + } + fclose( userfile ); + } + } + else + us->us_allowed = ( 1 << CB_CONF_USER ); + + if (cbcp_init_hook) + cbcp_init_hook( us ); + + cbcp_sendreq( us ); +} + + +/* make cbcp request packet & send it */ +static void +cbcp_sendreq (arg) + void *arg; +{ + cbcp_state *us=(cbcp_state *)arg; + u_char cb_allow = us->us_allowed; + u_char buf[256]; + u_char *bufp = buf; + int len = 0; + + us->us_count++; + if (us->us_count<=CBCP_MAXRETRY) + TIMEOUT( cbcp_sendreq, arg, CBCP_DEFTIMEOUT ); + else + { + lcp_close(0, "Sorry, CBCP not responding."); + return; + } + CBCPDEBUG((LOG_DEBUG, "cbcp_sendreq cb_allowed=%d", cb_allow)); + + + if (cb_allow & ( 1 << CB_CONF_USER ) ) { + CBCPDEBUG((LOG_DEBUG, "cbcp_sendreq CONF_USER")); + PUTCHAR(CB_CONF_USER, bufp); + len+=3; + PUTCHAR(3 , bufp); + PUTCHAR(us->us_delay, bufp); + } + + if (cb_allow & ( 1 << CB_CONF_ADMIN ) ) { + CBCPDEBUG((LOG_DEBUG, "cbcp_sendreq CONF_ADMIN")); + PUTCHAR(CB_CONF_ADMIN, bufp); + len += 3; + PUTCHAR(3 , bufp); + PUTCHAR(us->us_delay, bufp); + } + + if (cb_allow & ( 1 << CB_CONF_NO ) ) { + CBCPDEBUG((LOG_DEBUG, "cbcp_sendreq CONF_NO")); + PUTCHAR(CB_CONF_NO, bufp); + len += 3; + PUTCHAR(3 , bufp); + PUTCHAR(us->us_delay, bufp); + } + + if (len) + cbcp_send(us, CBCP_REQ, buf, len); + else + { + syslog(LOG_WARNING, "cbcp: no available options to client!"); + } +} + +/* Received CBCP response, make ACK */ +static void +cbcp_recvresp (us, pckt, len) + cbcp_state *us; + char *pckt; + int len; +{ + u_char type, addr_type; + int opt_len; + char address[256]; + + if (len) { + GETCHAR(type, pckt); + GETCHAR(opt_len, pckt); + + if (!(( 1 << type )& us->us_allowed )) { + CBCPDEBUG((LOG_DEBUG, "CBCP received options not allowed on server!")); + return; + } + + if ((type!= CB_CONF_NO ) && + (type!= CB_CONF_USER ) && + (type!= CB_CONF_ADMIN )) { + syslog(LOG_DEBUG, "CBCP received BAD Response: too more or unknown options %d",type); + return; + } + + UNTIMEOUT( cbcp_sendreq, us ); + us->us_count = 0; + + + if (opt_len > 2) + GETCHAR(us->us_delay, pckt) + if ( us->us_delay < 5 ) + us->us_delay = 5; + + if (opt_len > 4) { + GETCHAR(addr_type, pckt); /* Address Type mezo elvesztve !!! */ + memcpy(address, pckt, opt_len - 4); + address[opt_len - 4] = 0; + if (address[0]) + syslog(LOG_DEBUG, "peer will callback the client on: %s", address); + us->us_number=strdup( address ); + } + + us->us_type = ( 1 << type ); + cbcp_sendack( us ); + } + else + { + syslog(LOG_DEBUG, "CBCP received BAD Response: size to small"); } +} - cbcp_up(us); +/* Send the CBCP_ACK packet */ +static void +cbcp_sendack (arg) + void *arg; +{ + cbcp_state *us= (cbcp_state *)arg; + u_char cb_type; + u_char buf[256]; + u_char *bufp = buf; + int len = 0; + + stop_iface = (cbcp_state *)arg; + cb_type = us->us_type; + + CBCPDEBUG((LOG_DEBUG, "cbcp_sendack cb_type=%d", cb_type)); + + us->us_count++; + if (us->us_count<=CBCP_MAXRETRY) + TIMEOUT( cbcp_sendack, arg, CBCP_DEFTIMEOUT ); + else + { + lcp_close(0, "Sorry, CBCP not responding."); + return; + } + +#if 0 + if (!cb_type) + lcp_down(us->us_unit); +#endif + + if (cb_type == (1 << CB_CONF_USER )) { + CBCPDEBUG((LOG_DEBUG, "cbcp_sendack CONF_USER")); + PUTCHAR(CB_CONF_USER, bufp); + len = 3 + 1 + strlen(us->us_number) + 1; + PUTCHAR(len , bufp); + PUTCHAR(us->us_delay, bufp); /* delay */ + PUTCHAR(1, bufp); /* Elvesztett byte... */ + BCOPY(us->us_number, bufp, strlen(us->us_number) + 1); + cbcp_send(us, CBCP_ACK, buf, len); +/* lcp_close( 2, "Illegal, but required to server..." ); */ + callback_in_progress = us->us_unit + 1; + return; + } + + if (cb_type == (1 << CB_CONF_ADMIN )) { + CBCPDEBUG((LOG_DEBUG, "cbcp_sendack CONF_ADMIN")); + PUTCHAR(CB_CONF_ADMIN, bufp); + len = 3; + PUTCHAR(len , bufp); + PUTCHAR(us->us_delay, bufp); /* delay */ + PUTCHAR(0, bufp); + cbcp_send(us, CBCP_ACK, buf, len); +/* lcp_close( 2, "Illegal, but required to server..." ); */ + callback_in_progress = us->us_unit + 1; + return; + } + + if (cb_type == (1 << CB_CONF_NO )) { + CBCPDEBUG((LOG_DEBUG, "cbcp_sendack CONF_NO")); + PUTCHAR(CB_CONF_NO, bufp); + len = 3; + PUTCHAR(len , bufp); + PUTCHAR(0, bufp); + cbcp_send(us, CBCP_ACK, buf, len); + if (us->us_count<=1) + network_phase(us->us_unit); + return; + } + + syslog(LOG_DEBUG, "CBCP - Bad options in Ack routine."); + +} + +/* CBCP coming succesful up */ +void cbcp_stop() +{ + if ( stop_iface && lcp_allowoptions[stop_iface->us_unit].neg_cbcp ) + { + UNTIMEOUT( cbcp_sendack, stop_iface ); + cbcp_start_callback( stop_iface ); + } +} + +/* The server side coming up & client 'ack-ed' */ +void cbcp_start_callback (us) + cbcp_state *us; +{ + lcp_allowoptions[us->us_unit].neg_cbcp=0; + + CBCPDEBUG((LOG_DEBUG, "cbcp_start_callback running")); } -/* ok peer will do callback */ +/* The client side coming up: server allowed the callback */ static void cbcp_up(us) cbcp_state *us; { - persist = 0; - lcp_close(0, "Call me back, please"); - status = EXIT_CALLBACK; + lcp_wantoptions[us->us_unit].neg_cbcp=0; + CBCPDEBUG((LOG_DEBUG, "cbcp_up called")); + lcp_close(us->us_unit, "Call me back, please"); } + +/* The main module gets the script with parameters to run */ +char *cbcp_get_script() +{ + cbcp_state *us = &cbcp[(callback_in_progress & CBCP_NCLIENT)-1]; + char script[ 256 ]; + + if ( callback_in_progress & CBCP_CLIENT ) + sprintf( script, "%s %d", _PATH_CBCP_CLIENT, us->us_delay ); + else + sprintf( script, "%s %d %s", _PATH_CBCP_SERVER, + us->us_delay, us->us_number ); + + return strdup( script ); +} + +/* give me the hit rate. wild cars '*?' valids */ +int cbcp_check_user ( user, mask ) + char *user; + char *mask; +{ + char *curr_user = user; + char *curr_mask = mask; + char *find, backp = 0; + int count, len = 0; + + if ( !strcasecmp( user, mask )) + return 100; + + if ( !strcmp( mask, "*" )) + return 1; + + if ( !*user ) + return 0; + + count = 0; + + while(( find = strpbrk( curr_mask, "*?" )) != 0 ) { + if ( find != curr_mask ){ + len = find - curr_mask; + if ( strncmp( curr_user, curr_mask, len )) + break; + } + + curr_mask += len + 1; + curr_user += len; + count += len; + if ( *curr_user == 0 ) + break; + + if ( *find == '?' ) { + curr_user++; + if ( *curr_user == 0 ) + break; + } else { + if ( *curr_mask == 0 ) + break; + + if ( ( find = strpbrk( curr_mask, "*?" )) != 0 ){ + backp = *find; + *find = 0; + } + curr_user = strstr( curr_user, curr_mask ); + if ( find ) + *find = backp; + if ( !curr_user ) + break; + + find = strpbrk( curr_mask, "*?" ); + if ( find ) + len = find - curr_mask; + else + len = strlen( curr_mask ); + + curr_mask += len; + curr_user += len; + count += len; + } + } + + if ( *curr_user && *curr_mask && !strcmp( curr_user, curr_mask )) + count += strlen( curr_user ); + + return ( count * 100 / strlen( user ) ); +} + diff -ruN ppp-2.4.1/pppd/cbcp.h ppp-2.4.1-patched/pppd/cbcp.h --- ppp-2.4.1/pppd/cbcp.h Sat Nov 7 07:55:38 1998 +++ ppp-2.4.1-patched/pppd/cbcp.h Sun Dec 16 14:26:37 2001 @@ -6,6 +6,8 @@ u_char us_id; /* Current id */ u_char us_allowed; int us_type; + u_char us_delay; + u_char us_count; char *us_number; /* Telefone Number */ } cbcp_state; @@ -19,8 +21,19 @@ #define CBCP_RESP 2 #define CBCP_ACK 3 +#define CBCP_DEFTIMEOUT 5 +#define CBCP_MAXRETRY 50 +#define CBCP_CLIENT 0x8000 +#define CBCP_NCLIENT 0x7fff + +#define CBCPDEBUG(x) /*if (debug)*/ syslog x + #define CB_CONF_NO 1 #define CB_CONF_USER 2 #define CB_CONF_ADMIN 3 #define CB_CONF_LIST 4 + +char *cbcp_get_script __P(()); +void cbcp_stop __P(()); + #endif diff -ruN ppp-2.4.1/pppd/ipcp.c ppp-2.4.1-patched/pppd/ipcp.c --- ppp-2.4.1/pppd/ipcp.c Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/ipcp.c Sun Dec 16 14:26:37 2001 @@ -38,6 +38,10 @@ #include "ipcp.h" #include "pathnames.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif + static const char rcsid[] = RCSID; /* global vars */ @@ -1224,6 +1228,9 @@ u_char maxslotindex, cflag; int d; +#ifdef CBCP_SUPPORT + cbcp_stop(); +#endif /* * Reset all his options. */ diff -ruN ppp-2.4.1/pppd/ipv6cp.c ppp-2.4.1-patched/pppd/ipv6cp.c --- ppp-2.4.1/pppd/ipv6cp.c Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/ipv6cp.c Sun Dec 16 14:26:37 2001 @@ -122,6 +122,10 @@ #include "magic.h" #include "pathnames.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif + static const char rcsid[] = RCSID; /* global vars */ @@ -854,6 +858,10 @@ u_char *p; /* Pointer to next char to parse */ u_char *ucp = inp; /* Pointer to current output char */ int l = *len; /* Length left */ + +#ifdef CBCP_SUPPORT + cbcp_stop(); +#endif /* * Reset all his options. diff -ruN ppp-2.4.1/pppd/ipxcp.c ppp-2.4.1-patched/pppd/ipxcp.c --- ppp-2.4.1/pppd/ipxcp.c Thu Mar 8 06:11:13 2001 +++ ppp-2.4.1-patched/pppd/ipxcp.c Sun Dec 16 14:26:37 2001 @@ -39,6 +39,10 @@ #include "pathnames.h" #include "magic.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif + static const char rcsid[] = RCSID; /* global vars */ @@ -974,6 +978,10 @@ u_char *p; /* Pointer to next char to parse */ u_char *ucp = inp; /* Pointer to current output char */ int l = *len; /* Length left */ + +#ifdef CBCP_SUPPORT + cbcp_stop(); +#endif /* * Reset all his options. diff -ruN ppp-2.4.1/pppd/lcp.c ppp-2.4.1-patched/pppd/lcp.c --- ppp-2.4.1/pppd/lcp.c Thu Mar 8 06:11:14 2001 +++ ppp-2.4.1-patched/pppd/lcp.c Sun Dec 16 14:26:37 2001 @@ -342,9 +342,7 @@ ao->neg_magicnumber = 1; ao->neg_pcompression = 1; ao->neg_accompression = 1; -#ifdef CBCP_SUPPORT - ao->neg_cbcp = 1; -#endif + ao->neg_cbcp = 0; ao->neg_endpoint = 1; } @@ -1663,6 +1661,16 @@ break; } ho->neg_accompression = 1; + break; + + case CI_CALLBACK: + LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd CALLBACK")); + if (!ao->neg_cbcp || + cilen != CILEN_CHAR ) { + orc = CONFREJ; + break; + } + ho->neg_cbcp = 1; break; case CI_MRRU: diff -ruN ppp-2.4.1/pppd/main.c ppp-2.4.1-patched/pppd/main.c --- ppp-2.4.1/pppd/main.c Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/main.c Sun Dec 16 14:26:37 2001 @@ -119,6 +119,10 @@ char **script_env; /* Env. variable values for scripts */ int s_env_nalloc; /* # words avail at script_env */ +#ifdef CBCP_SUPPORT +int callback_in_progress; /* Callback running */ +#endif + u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ @@ -230,6 +234,10 @@ int i, t; char *p; struct passwd *pw; +#ifdef CBCP_SUPPORT + char *connector; +#endif + struct protent *protp; char numbuf[16]; @@ -481,6 +489,10 @@ add_fd(fd_ppp); lcp_open(0); /* Start protocol */ +#ifdef CBCP_SUPPORT + for(callback_in_progress=1;callback_in_progress;){ + callback_in_progress=0; +#endif status = EXIT_NEGOTIATION_FAILED; new_phase(PHASE_ESTABLISH); while (phase != PHASE_DEAD) { @@ -517,7 +529,75 @@ warn("unable to delete pid file %s: %m", pidfilename); pidfilename[0] = 0; } +#ifdef CBCP_SUPPORT + if (callback_in_progress){ + connector = NULL; + cbcp_stop(); + remove_fd(fd_ppp); + clean_check(); + the_channel->disestablish_ppp(devfd); + fd_ppp = -1; + + if (!hungup){ + lcp_lowerdown(0); + } else { + tty_close_fds(); + setup_serial(connector); + + } + + devfd = callback(); + + /* set up the serial device as a ppp interface */ + tdb_writelock(pppdb); + fd_ppp = the_channel->establish_ppp(devfd); + if (fd_ppp < 0) { + tdb_writeunlock(pppdb); + status = EXIT_FATAL_ERROR; + goto disconnect; + } + + if (!demand && ifunit >= 0) + set_ifunit(1); + tdb_writeunlock(pppdb); + /* + * Start opening the connection and wait for + * incoming events (reply, timeout, etc.). + */ + notice("Connect: %s <--> %s", ifname, ppp_devnam); + gettimeofday(&start_time, NULL); + link_stats_valid = 0; + script_unsetenv("CONNECT_TIME"); + script_unsetenv("BYTES_SENT"); + script_unsetenv("BYTES_RCVD"); + lcp_lowerup(0); + + /* + * If we are initiating this connection, wait for a short + * time for something from the peer. This can avoid bouncing + * our packets off his tty before he has it set up. + */ + add_fd(fd_ppp); + if (listen_time != 0) { + struct timeval t; + t.tv_sec = listen_time / 1000; + t.tv_usec = listen_time % 1000; + wait_input(&t); + } + + /*if (connector != NULL || ptycommand != NULL) { + struct timeval t; + t.tv_sec = 1; + t.tv_usec = 0; + wait_input(&t); + }*/ + + lcp_open(0); /* Start protocol */ + } + } +#endif + /* * If we may want to bring the link up again, transfer * the ppp unit back to the loopback. Set the diff -ruN ppp-2.4.1/pppd/options.c ppp-2.4.1-patched/pppd/options.c --- ppp-2.4.1/pppd/options.c Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/options.c Sun Dec 16 14:26:37 2001 @@ -43,6 +43,12 @@ char *strdup __P((char *)); #endif +#ifdef CBCP_SUPPORT +#include "fsm.h" +#include "lcp.h" +#include "cbcp.h" +#endif + static const char rcsid[] = RCSID; struct option_value { @@ -130,6 +136,10 @@ static int n_arguments __P((option_t *)); static int number_option __P((char *, u_int32_t *, int)); +#ifdef CBCP_SUPPORT +static int setcbcp __P((char **)); +#endif + /* * Structure to store extra lists of options. */ @@ -270,6 +280,11 @@ "set filter for active pkts", OPT_PRIO }, #endif +#ifdef CBCP_SUPPORT + { "callback", o_special, setcbcp, + "Callback request to server - OR - calling back the client" }, +#endif + { NULL } }; @@ -1519,3 +1534,23 @@ return 0; } #endif /* PLUGIN */ + +#ifdef CBCP_SUPPORT +static int +setcbcp(argv) + char **argv; +{ + cbcp[0].us_number = strdup(*argv); + if (cbcp_protent.enabled_flag) + novm("Only one callback parameter supported!"); + if (cbcp[0].us_number == 0) + novm("callback number"); + if (!strcmp(cbcp[0].us_number,"server")){ + lcp_allowoptions[0].neg_cbcp = 1; + } else { + lcp_wantoptions[0].neg_cbcp = 1; + } + cbcp_protent.enabled_flag = 1; + return 1; +} +#endif diff -ruN ppp-2.4.1/pppd/patchlevel.h ppp-2.4.1-patched/pppd/patchlevel.h --- ppp-2.4.1/pppd/patchlevel.h Sun Mar 25 06:51:54 2001 +++ ppp-2.4.1-patched/pppd/patchlevel.h Sun Dec 16 14:26:37 2001 @@ -1,4 +1,4 @@ /* $Id: patchlevel.h,v 1.53 2001/03/25 04:51:54 paulus Exp $ */ -#define VERSION "2.4.1" +#define VERSION "2.4.1 with CBCPs (ASPLinux)" #define DATE "25 March 2001" diff -ruN ppp-2.4.1/pppd/pathnames.h ppp-2.4.1-patched/pppd/pathnames.h --- ppp-2.4.1/pppd/pathnames.h Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/pathnames.h Sun Dec 16 14:26:37 2001 @@ -40,6 +40,13 @@ #define _PATH_IPXDOWN _ROOT_PATH "/etc/ppp/ipx-down" #endif /* IPX_CHANGE */ +#ifdef CBCP_SUPPORT +#define _PATH_CBCP_SERVER _ROOT_PATH "/etc/ppp/callback-server" +#define _PATH_CBCP_CLIENT _ROOT_PATH "/etc/ppp/callback-client" +#define _PATH_CBCP_USERS _ROOT_PATH "/etc/ppp/callback-users" +#define _PATH_CBCP _ROOT_PATH "/etc/ppp/callback" +#endif /* CBCP_SUPPORT */ + #ifdef __STDC__ #define _PATH_PPPDB _ROOT_PATH _PATH_VARRUN "pppd.tdb" #else /* __STDC__ */ diff -ruN ppp-2.4.1/pppd/pppd.8 ppp-2.4.1-patched/pppd/pppd.8 --- ppp-2.4.1/pppd/pppd.8 Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/pppd.8 Sun Dec 16 14:26:37 2001 @@ -72,6 +72,14 @@ or include .. as a pathname component. The format of the options file is described below. .TP +.B callback \fIserver/number +When compiled with the CBCP extensions (-DCBCP_SUPPORT) the ppp daemon +can act as a client to servers which provide CBCP-protocol callback +negotiation or act as a \fIserver. It reads its options from +/etc/ppp/callback-users and invokes /etc/ppp/callback-server +when dialing out. Otherwise it will invoke /etc/ppp/callback-client +to wait for a call. +.TP .B connect \fIscript Use the executable or shell command specified by \fIscript\fR to set up the serial line. This script would typically use the chat(8) diff -ruN ppp-2.4.1/pppd/pppd.h ppp-2.4.1-patched/pppd/pppd.h --- ppp-2.4.1/pppd/pppd.h Sun Dec 16 14:25:15 2001 +++ ppp-2.4.1-patched/pppd/pppd.h Sun Dec 16 14:26:44 2001 @@ -48,6 +48,9 @@ #include "eui64.h" #endif +/* for cbcp_init_hook */ +#include "cbcp.h" + /* * Limits. */ @@ -282,6 +285,10 @@ extern struct bpf_program active_filter; /* Filter for link-active pkts */ #endif +#ifdef CBCP_SUPPORT +extern int callback_in_progress; /*Callback running*/ +#endif + #ifdef MSLANMAN extern bool ms_lanman; /* Use LanMan password instead of NT */ /* Has meaning only with MS-CHAP challenges */ @@ -426,6 +433,8 @@ /* Procedures exported from tty.c. */ void tty_init __P((void)); +void setup_serial __P((char *)); +int callback __P ((void)); /* Procedures exported from utils.c. */ void log_packet __P((u_char *, int, char *, int)); @@ -447,6 +456,7 @@ void end_pr_log __P((void)); /* finish up after using pr_log */ /* Procedures exported from auth.c */ +void network_phase __P((int)); /* the dataexchanger CP-s goung up */ 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 */ @@ -614,6 +624,7 @@ extern void (*ip_up_hook) __P((void)); extern void (*ip_down_hook) __P((void)); extern void (*ip_choose_hook) __P((u_int32_t *)); +extern void (*cbcp_init_hook) __P((cbcp_state *)); /* * Inline versions of get/put char/short/long. diff -ruN ppp-2.4.1/pppd/tty.c ppp-2.4.1-patched/pppd/tty.c --- ppp-2.4.1/pppd/tty.c Tue Mar 13 06:54:43 2001 +++ ppp-2.4.1-patched/pppd/tty.c Sun Dec 16 14:26:37 2001 @@ -48,6 +48,9 @@ #include "pppd.h" #include "fsm.h" #include "lcp.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif /* CBCP_SUPPORT */ void tty_process_extra_options __P((void)); void tty_check_options __P((void)); @@ -78,6 +81,8 @@ static int ttyfd; /* Serial port file descriptor */ static char speed_str[16]; /* Serial port speed as string */ +/*static void setup_serial __P();*/ + mode_t tty_mode = (mode_t)-1; /* Original access permissions to tty */ int baud_rate; /* Actual bits/second for serial device */ char *callback_script; /* script for doing callback */ @@ -458,10 +463,10 @@ int connect_tty() { char *connector; - int fdflags; - struct stat statbuf; char numbuf[16]; + connector = doing_callback? callback_script: connect_script; + /* * Get a pty master/slave pair if the pty, notty, socket, * or record options were specified. @@ -489,66 +494,7 @@ 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. - */ - hungup = 0; - kill_link = 0; - connector = doing_callback? callback_script: connect_script; - if (devnam[0] != 0) { - for (;;) { - /* If the user specified the device name, become the - user before opening it. */ - int err, prio; - - prio = privopen? OPRIO_ROOT: tty_options[0].priority; - if (prio < OPRIO_ROOT) - seteuid(uid); - ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0); - err = errno; - if (prio < OPRIO_ROOT) - seteuid(0); - if (ttyfd >= 0) - break; - errno = err; - if (err != EINTR) { - error("Failed to open %s: %m", devnam); - status = EXIT_OPEN_FAILED; - } - if (!persist || err != EINTR) - return -1; - } - real_ttyfd = ttyfd; - if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 - || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) - warn("Couldn't reset non-blocking mode on device: %m"); - - /* - * 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) { - warn("Couldn't restrict write permissions to %s: %m", devnam); - } else - tty_mode = statbuf.st_mode; - - /* - * Set line speed, flow control, etc. - * If we have a non-null connection or initializer script, - * 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 could clear CLOCAL at this point. - */ - set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0) - || initializer != NULL)); - } + setup_serial(connector); /* * If the pty, socket, notty and/or record option was specified, @@ -672,6 +618,113 @@ return ttyfd; } +void setup_serial(char *connector) +{ + int fdflags; + struct stat statbuf; + + /* + * 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. + */ + hungup = 0; + kill_link = 0; + connector = doing_callback? callback_script: connect_script; + if (devnam[0] != 0) { + for (;;) { + /* If the user specified the device name, become the + user before opening it. */ + int err, prio; + + prio = privopen? OPRIO_ROOT: tty_options[0].priority; + if (prio < OPRIO_ROOT) + seteuid(uid); + ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0); + err = errno; + if (prio < OPRIO_ROOT) + seteuid(0); + if (ttyfd >= 0) + break; + errno = err; + if (err != EINTR) { + error("Failed to open %s: %m", devnam); + status = EXIT_OPEN_FAILED; + } + if (!persist || err != EINTR) + return -1; + } + real_ttyfd = ttyfd; + if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 + || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) + warn("Couldn't reset non-blocking mode on device: %m"); + + /* + * 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) { + warn("Couldn't restrict write permissions to %s: %m", devnam); + } else + tty_mode = statbuf.st_mode; + + /* + * Set line speed, flow control, etc. + * If we have a non-null connection or initializer script, + * 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 could clear CLOCAL at this point. + */ + set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0) + || initializer != NULL)); + } +} + +#ifdef CBCP_SUPPORT +int callback() +{ + char *s; + char numbuf[16]; + + cbcp_protent.enabled_flag = 0; /* Already not need */ + s = cbcp_get_script(); + syslog(LOG_INFO, "Callback with <%s>",s ); + + set_up_tty( ttyfd, 1 ); + + if (real_ttyfd != -1) { + if (!default_device && modem) { + setdtr(real_ttyfd, 0); /* in case modem is off hook */ + sleep(1); + setdtr(real_ttyfd, 1); + } + } + + /* syslog(LOG_INFO, "ttyfd is %d and hungup is %d",ttyfd,hungup ); */ + if (device_script(s, ttyfd, ttyfd, 0) < 0) { + error("Callback script failed"); + status = EXIT_INIT_FAILED; + setdtr(ttyfd, 0 ); + return -1; + } + + info("Serial connection established." ); + + if (real_ttyfd != -1) + set_up_tty( real_ttyfd, 0 ); + + slprintf(numbuf, sizeof(numbuf), "%d", baud_rate); + script_setenv("SPEED", numbuf, 1); + + return ttyfd; + +} +#endif /* CBCP Support */ void disconnect_tty() { portslave-2010.04.19.1/patches/ppp-2.4.1-unused/0000775000000000000000000000000007412472207015352 5ustar portslave-2010.04.19.1/patches/ppp-2.4.1-unused/003_cbcp.diff0000664000000000000000000000115607411455210017472 0ustar --- ppp-2.4.0b4.orig/pppd/Makefile.linux +++ ppp-2.4.0b4/pppd/Makefile.linux @@ -15,7 +15,7 @@ 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 utils.o sys-linux.o ipxcp.o multilink.o \ - tdb.o tty.o + tdb.o tty.o cbcp.o all: pppd @@ -56,7 +56,7 @@ INCLUDE_DIRS= -I../include -COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP +COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP -DCBCP_SUPPORT CFLAGS= $(UDEB_CFLAGS) $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) portslave-2010.04.19.1/patches/ppp-2.4.1/0000775000000000000000000000000007550354503014052 5ustar portslave-2010.04.19.1/patches/ppp-2.4.1/015_scripts_pon.diff0000664000000000000000000000031207411461424017625 0ustar --- ppp-2.4.0b4.orig/scripts/pon +++ ppp-2.4.0b4/scripts/pon @@ -0,0 +1,9 @@ +#!/bin/sh + +if [ "$1" = "quick" ] +then + touch /var/run/ppp-quick + shift +fi + +/usr/sbin/pppd call ${1:-provider} portslave-2010.04.19.1/patches/ppp-2.4.1/027_child_debugging.diff0000664000000000000000000000071607411461424020373 0ustar --- ppp-2.4.0/pppd/main.c.reap Thu Jul 6 07:17:02 2000 +++ ppp-2.4.0/pppd/main.c Thu Nov 9 17:41:30 2000 @@ -1579,7 +1579,8 @@ (chp? chp->prog: "??"), pid, WTERMSIG(status)); } else if (debug) dbglog("Script %s finished (pid %d), status = 0x%x", - (chp? chp->prog: "??"), pid, status); + (chp? chp->prog: "??"), pid, + WIFEXITED(status) ? WEXITSTATUS(status) : status); if (chp && chp->done) (*chp->done)(chp->arg); if (chp) portslave-2010.04.19.1/patches/ppp-2.4.1/020_IPPROTO_TCP_undefine.diff0000664000000000000000000000050607411461424021002 0ustar --- ppp-2.4.1.orig/pppd/ipcp.c Wed Jul 4 21:49:07 2001 +++ ppp-2.4.1/pppd/ipcp.c Wed Jul 4 21:48:46 2001 @@ -2028,7 +2028,7 @@ */ #define IP_HDRLEN 20 /* bytes */ #define IP_OFFMASK 0x1fff -#define IPPROTO_TCP 6 +/* in /usr/include/netinet/in.h #define IPPROTO_TCP 6 */ #define TCP_HDRLEN 20 #define TH_FIN 0x01 portslave-2010.04.19.1/patches/ppp-2.4.1/012_secure-card.diff0000664000000000000000000000161107411461424017457 0ustar --- ppp-2.4.0b4.orig/scripts/secure-card +++ ppp-2.4.0b4/scripts/secure-card @@ -1,4 +1,4 @@ -#!/usr/local/bin/expect -f +#!/usr/bin/expect -f # # This script was written by Jim Isaacson . It is # designed to work as a script to use the SecureCARD(tm) device. This @@ -17,14 +17,14 @@ send_user "hello, starting ppp\n" -system "stty 19200 -echoe -echo raw < /dev/cua3 > /dev/cua3" +system "stty 19200 -echoe -echo raw < /dev/ttyS3 > /dev/ttyS3" # # These are the parameters for the program. # set user Pxxxxxx set password xxxxxxx -set modem /dev/cua3 +set modem /dev/ttyS3 set dialup set timeout 60 @@ -107,5 +107,5 @@ } } -overlay -0 $spawn_id -1 $spawn_id pppd /dev/cua3 19200 192.111.187.215: \ +overlay -0 $spawn_id -1 $spawn_id pppd /dev/ttyS3 19200 192.111.187.215: \ crtscts modem defaultroute debug portslave-2010.04.19.1/patches/ppp-2.4.1/014_scripts_poff.diff0000664000000000000000000000136707411461424017775 0ustar --- ppp-2.4.0b4.orig/scripts/poff +++ ppp-2.4.0b4/scripts/poff @@ -0,0 +1,26 @@ +#!/bin/sh + +# Lets see how many pppds are running.... +set -- `cat /var/run/ppp*.pid 2>/dev/null` + +case $# in + 0) # pppd only creates a pid file once ppp is up, so let's try killing pppd + # on the assumption that we've not got that far yet. + killall pppd + ;; + 1) # If only one was running then it can be killed (apparently killall + # caused problems for some, so lets try killing the pid from the file) + kill $1 + ;; + *) # More than one! Aieehh.. Dont know which one to kill. + echo "More than one pppd running. None stopped" + exit 1 + ;; +esac + +if [ -r /var/run/ppp-quick ] +then + rm -f /var/run/ppp-quick +fi + +exit 0 portslave-2010.04.19.1/patches/ppp-2.4.1/016_chat_manpage.diff0000664000000000000000000000120107411461424017670 0ustar --- ppp-2.4.0.orig/chat/chat.8 Mon Sep 6 17:10:23 1999 +++ ppp-2.4.0/chat/chat.8 Sun Feb 25 17:11:27 2001 @@ -154,7 +154,7 @@ .IP # Now wait for the prompt and send logout string .br -\'# ' logout +\&'# ' logout .LP .SH SENDING DATA FROM A FILE @@ -216,7 +216,7 @@ .br SAY "Dialling your ISP...\\n" .br -\'' ATDT5551212 +\&'' ATDT5551212 .br TIMEOUT 120 .br @@ -326,13 +326,13 @@ .br CONNECT \\c .br -\'Callback login:' call_back_ID +\&'Callback login:' call_back_ID .br HANGUP OFF .br ABORT "Bad Login" .br -\'Callback Password:' Call_back_password +\&'Callback Password:' Call_back_password .br TIMEOUT 120 .br portslave-2010.04.19.1/patches/ppp-2.4.1/998_ipv6cp-use-persistent.diff0000664000000000000000000000622307411461424021514 0ustar diff -ru ppp-2.4.1.uus.orig/pppd/ipv6cp.c ppp-2.4.1.uus.patched/pppd/ipv6cp.c --- ppp-2.4.1.uus.orig/pppd/ipv6cp.c Fri Mar 23 12:23:54 2001 +++ ppp-2.4.1.uus.patched/pppd/ipv6cp.c Wed Nov 14 19:33:37 2001 @@ -193,7 +193,7 @@ { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, "Use (default) IPv4 address as interface identifier", 1 }, -#if defined(SOL2) +#if defined(SOL2) || defined(__linux__) { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent, "Use uniquely-available persistent value for link local address", 1 }, #endif /* defined(SOL2) */ @@ -330,6 +330,8 @@ return 1; } +char *llv6_ntoa(eui64_t ifaceid); + static void printifaceid(opt, printer, arg) option_t *opt; @@ -1027,7 +1029,7 @@ if (!ipv6cp_protent.enabled_flag) return; -#if defined(SOL2) +#if defined(SOL2) || defined(__linux__) /* * Persistent link-local id is only used when user has not explicitly * configure/hard-code the id @@ -1475,7 +1477,7 @@ */ #define IP6_HDRLEN 40 /* bytes */ #define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ -#define IPPROTO_TCP 6 +/* #define IPPROTO_TCP 6 */ #define TCP_HDRLEN 20 #define TH_FIN 0x01 diff -ru ppp-2.4.1.uus.orig/pppd/ipv6cp.h ppp-2.4.1.uus.patched/pppd/ipv6cp.h --- ppp-2.4.1.uus.orig/pppd/ipv6cp.h Sat Aug 5 08:46:47 2000 +++ ppp-2.4.1.uus.patched/pppd/ipv6cp.h Wed Nov 14 19:08:36 2001 @@ -109,7 +109,7 @@ int opt_local; /* ourtoken set by option */ int opt_remote; /* histoken set by option */ int use_ip; /* use IP as interface identifier */ -#if defined(SOL2) +#if defined(SOL2) | defined(__linux__) int use_persistent; /* use uniquely persistent value for address */ #endif /* defined(SOL2) */ int neg_vj; /* Van Jacobson Compression? */ diff -ru ppp-2.4.1.uus.orig/pppd/sys-linux.c ppp-2.4.1.uus.patched/pppd/sys-linux.c --- ppp-2.4.1.uus.orig/pppd/sys-linux.c Wed Nov 14 19:05:54 2001 +++ ppp-2.4.1.uus.patched/pppd/sys-linux.c Wed Nov 14 19:44:36 2001 @@ -2750,3 +2750,51 @@ } return 1; } + +#ifdef INET6 +/* + * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI + * + * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes + * that the system has a properly configured Ethernet interface for this + * function to return non-zero. + */ +int +ether_to_eui64(eui64_t *p_eui64) +{ + struct ifreq ifr; + int skfd; + const unsigned char *ptr; + + skfd = socket(PF_INET6, SOCK_DGRAM, 0); + if(skfd == -1) + { + warn("could not open IPv6 socket"); + return 0; + } + + strcpy(ifr.ifr_name, "eth0"); + if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) + { + close(skfd); + warn("could not obtain hardware address for eth0"); + return 0; + } + close(skfd); + + /* + * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] + */ + ptr = ifr.ifr_hwaddr.sa_data; + p_eui64->e8[0] = ptr[0] | 0x02; + p_eui64->e8[1] = ptr[1]; + p_eui64->e8[2] = ptr[2]; + p_eui64->e8[3] = 0xFF; + p_eui64->e8[4] = 0xFE; + p_eui64->e8[5] = ptr[3]; + p_eui64->e8[6] = ptr[4]; + p_eui64->e8[7] = ptr[5]; + + return 1; +} +#endif portslave-2010.04.19.1/patches/ppp-2.4.1/005_fsm.c.diff0000664000000000000000000000152307411461424016274 0ustar --- ppp-2.4.0b4.orig/pppd/fsm.c +++ ppp-2.4.0b4/pppd/fsm.c @@ -213,13 +213,21 @@ (*f->callbacks->down)(f); /* Inform upper layers we're down */ /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = CLOSING; + if (f->retransmits > 0) { + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + TIMEOUT(fsm_timeout, f, f->timeouttime); + --f->retransmits; + + f->state = CLOSING; + } else { + /* + * Term requests disabled at the user's discretion. + */ + f->state = CLOSED; + if( f->callbacks->finished ) + (*f->callbacks->finished)(f); + } break; } } portslave-2010.04.19.1/patches/ppp-2.4.1/996_chap_plugin.diff0000664000000000000000000000774007540444713017616 0ustar diff -ruN ppp-2.4.1.uus.orig/pppd/auth.c ppp-2.4.1.uus/pppd/auth.c --- ppp-2.4.1.uus.orig/pppd/auth.c 2001-03-13 06:54:33.000000000 +0100 +++ ppp-2.4.1.uus/pppd/auth.c 2002-09-13 22:23:19.000000000 +0200 @@ -132,6 +132,8 @@ /* Hook for a plugin to get the PAP password for authenticating us */ int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; +int (*allowed_address_hook) __P((u_int32_t addr)) = NULL; + /* * This is used to ensure that we don't start an auth-up/down * script while one is already running. @@ -1376,6 +1378,13 @@ char *filename; struct wordlist *addrs; + if (chap_check_hook) { + ret = (*chap_check_hook)(); + if (ret >= 0) { + return ret; + } + } + filename = _PATH_CHAPFILE; f = fopen(filename, "r"); if (f == NULL) @@ -1631,6 +1640,12 @@ if (bad_ip_adrs(addr)) return 0; + + if (allowed_address_hook) { + ok = allowed_address_hook(addr); + if (ok >= 0) return ok; + } + if (addresses[unit] != NULL) { ok = ip_addr_check(addr, addresses[unit]); if (ok >= 0) diff -ruN ppp-2.4.1.uus.orig/pppd/chap.c ppp-2.4.1.uus/pppd/chap.c --- ppp-2.4.1.uus.orig/pppd/chap.c 2001-03-08 06:11:11.000000000 +0100 +++ ppp-2.4.1.uus/pppd/chap.c 2002-09-13 22:18:11.000000000 +0200 @@ -51,6 +51,17 @@ #include "chap_ms.h" #endif +/* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */int (*chap_check_hook) __P((void)) = NULL; + +/* Hook for a plugin to get the CHAP password for authenticating us */ +int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL; + +/* Hook for a plugin to validate CHAP challenge */ +int (*chap_auth_hook) __P((char *user, + u_char *remmd, + int remmd_len, + chap_state *cstate)) = NULL; + static const char rcsid[] = RCSID; /* @@ -552,10 +563,20 @@ * do the hash ourselves, and compare the result. */ code = CHAP_FAILURE; - if (!get_secret(cstate->unit, (explicit_remote? remote_name: rhostname), + if(chap_auth_hook) + { + code = (*chap_auth_hook) ( (explicit_remote ? remote_name : rhostname), + remmd, (int) remmd_len, + cstate ); + } + else + { + if (!get_secret(cstate->unit, (explicit_remote? remote_name: rhostname), cstate->chal_name, secret, &secret_len, 1)) { warn("No CHAP secret found for authenticating %q", rhostname); - } else { + } + else + { /* generate MD based on negotiated type */ switch (cstate->chal_type) { @@ -577,8 +598,8 @@ default: CHAPDEBUG(("unknown digest type %d", cstate->chal_type)); } + } } - BZERO(secret, sizeof(secret)); ChapSendStatus(cstate, code); diff -ruN ppp-2.4.1.uus.orig/pppd/chap.h ppp-2.4.1.uus/pppd/chap.h --- ppp-2.4.1.uus.orig/pppd/chap.h 1999-11-15 02:44:41.000000000 +0100 +++ ppp-2.4.1.uus/pppd/chap.h 2002-09-13 22:18:11.000000000 +0200 @@ -85,6 +85,9 @@ char *resp_name; /* Our name to send with response */ } chap_state; +/* We need the declaration of chap_state to use this prototype */ +extern int (*chap_auth_hook) __P((char *User, u_char *remmd, + int remmd_len, chap_state *cstate)); /* * Client (peer) states. diff -ruN ppp-2.4.1.uus.orig/pppd/pppd.h ppp-2.4.1.uus/pppd/pppd.h --- ppp-2.4.1.uus.orig/pppd/pppd.h 2001-03-13 06:54:37.000000000 +0100 +++ ppp-2.4.1.uus/pppd/pppd.h 2002-09-13 22:19:49.000000000 +0200 @@ -605,7 +605,10 @@ struct wordlist **paddrs, struct wordlist **popts)); extern void (*pap_logout_hook) __P((void)); +extern int (*allowed_address_hook) __P((u_int32_t addr)); extern int (*pap_passwd_hook) __P((char *user, char *passwd)); +extern int (*chap_check_hook) __P((void)); +extern int (*chap_passwd_hook) __P((char *User, char *Passwd)); extern void (*ip_up_hook) __P((void)); extern void (*ip_down_hook) __P((void)); extern void (*ip_choose_hook) __P((u_int32_t *)); portslave-2010.04.19.1/patches/ppp-2.4.1/002_chat.c.diff0000664000000000000000000000044407411461424016424 0ustar --- ppp-2.4.0b4.orig/chat/chat.c +++ ppp-2.4.0b4/chat/chat.c @@ -203,7 +203,7 @@ int clear_abort_next = 0; char *report_string[MAX_REPORTS] ; -char report_buffer[50] ; +char report_buffer[256] ; int n_reports = 0, report_next = 0, report_gathering = 0 ; int clear_report_next = 0; portslave-2010.04.19.1/patches/ppp-2.4.1/010_scripts_README.diff0000664000000000000000000000153107411461424017765 0ustar --- ppp-2.4.0b4.orig/scripts/README +++ ppp-2.4.0b4/scripts/README @@ -141,3 +141,17 @@ are escaped. This may need to be modified depending on the ssh (or pseudo-tty) implementation which may differ across platforms, for further optimizations. + +------------------------------------------------------------------------ + +12. pon, poff and ip-up + +These are modified version of the pon/poff/ip-up scripts contributed by Yann +Dirson . They allow you to call "pon quick" respectively +"pon quick my-isp" to just call the provider for running you ip-up scripts in +/etc/ppp/ip-up.d. This can be useful to check for incoming/flush outgoing +mail, without the necessary delay before hangup introduced by diald or such. + +These scripts break the possibility to connect to multiple ISPs at once, so +they are included only here. + portslave-2010.04.19.1/patches/ppp-2.4.1/026_pppd.8-active-filter.diff0000664000000000000000000000132407411461424021135 0ustar # the manpage is slightly unclear here. --- ppp-2.4.1.orig/pppd/pppd.8 Tue Mar 13 18:54:37 2001 +++ ppp-2.4.1/pppd/pppd.8 Wed Nov 7 20:31:44 2001 @@ -190,9 +190,7 @@ except that qualifiers which are inappropriate for a PPP link, such as \fBether\fR and \fBarp\fR, are not permitted. Generally the filter expression should be enclosed in single-quotes to prevent whitespace -in the expression from being interpreted by the shell. This option -is currently only available under NetBSD, and then only -if both the kernel and pppd were compiled with PPP_FILTER defined. +in the expression from being interpreted by the shell. .TP .B allow-ip \fIaddress(es) Allow peers to use the given IP address or subnet without portslave-2010.04.19.1/patches/ppp-2.4.1/023_lcp-max-termintate.diff0000664000000000000000000000064207411461424021002 0ustar --- ppp-2.4.1.orig/pppd/fsm.c Wed Jul 4 23:34:27 2001 +++ ppp-2.4.1/pppd/fsm.c Wed Jul 4 23:34:12 2001 @@ -213,6 +213,7 @@ (*f->callbacks->down)(f); /* Inform upper layers we're down */ /* Init restart counter, send Terminate-Request */ + f->retransmits = f->maxtermtransmits; if (f->retransmits > 0) { fsm_sdata(f, TERMREQ, f->reqid = ++f->id, (u_char *) f->term_reason, f->term_reason_len); portslave-2010.04.19.1/patches/ppp-2.4.1/999_minor-warnings.diff0000664000000000000000000000504607550354470020300 0ustar diff -ru ppp-2.4.1.orig/pppd/auth.c ppp-2.4.1/pppd/auth.c --- ppp-2.4.1.orig/pppd/auth.c 2002-10-06 22:54:36.000000000 +0200 +++ ppp-2.4.1/pppd/auth.c 2002-10-06 22:54:53.000000000 +0200 @@ -123,7 +123,7 @@ int (*pap_check_hook) __P((void)) = NULL; /* Hook for a plugin to check the PAP user and password */ -int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, +int (*pap_auth_hook) __P((char *User, char *Passwd, char **msgp, struct wordlist **paddrs, struct wordlist **popts)) = NULL; @@ -131,7 +131,7 @@ void (*pap_logout_hook) __P((void)) = NULL; /* Hook for a plugin to get the PAP password for authenticating us */ -int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; +int (*pap_passwd_hook) __P((char *User, char *Passwd)) = NULL; int (*allowed_address_hook) __P((u_int32_t addr)) = NULL; diff -ru ppp-2.4.1.orig/pppd/pppd.h ppp-2.4.1/pppd/pppd.h --- ppp-2.4.1.orig/pppd/pppd.h 2002-10-06 22:54:36.000000000 +0200 +++ ppp-2.4.1/pppd/pppd.h 2002-10-06 22:56:24.000000000 +0200 @@ -71,7 +71,7 @@ o_int, o_uint32, o_string, - o_wild, + o_wild }; typedef struct { @@ -578,11 +578,11 @@ int parse_args __P((int argc, char **argv)); /* Parse options from arguments given */ int options_from_file __P((char *filename, int must_exist, int check_prot, - int privileged)); + int priv)); /* 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 */ -int options_from_list __P((struct wordlist *, int privileged)); +int options_from_list __P((struct wordlist *, int priv)); /* Parse options from a wordlist */ int getword __P((FILE *f, char *word, int *newlinep, char *filename)); /* Read a word from a file */ @@ -606,12 +606,12 @@ extern int (*idle_time_hook) __P((struct ppp_idle *)); extern int (*holdoff_hook) __P((void)); extern int (*pap_check_hook) __P((void)); -extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, +extern int (*pap_auth_hook) __P((char *User, char *Passwd, char **msgp, struct wordlist **paddrs, struct wordlist **popts)); extern void (*pap_logout_hook) __P((void)); extern int (*allowed_address_hook) __P((u_int32_t addr)); -extern int (*pap_passwd_hook) __P((char *user, char *passwd)); +extern int (*pap_passwd_hook) __P((char *User, char *Passwd)); extern int (*chap_check_hook) __P((void)); extern int (*chap_passwd_hook) __P((char *User, char *Passwd)); extern void (*ip_up_hook) __P((void)); portslave-2010.04.19.1/patches/ppp-2.4.1/021_setipaddr.diff0000664000000000000000000000230007411461424017235 0ustar --- ppp-2.4.1/pppd/ipcp.c Thu Mar 8 06:11:12 2001 +++ ppp-2.4.1-new/pppd/ipcp.c Tue Jun 19 15:49:59 2001 @@ -109,7 +109,8 @@ static int setdnsaddr __P((char **)); static int setwinsaddr __P((char **)); static int setnetmask __P((char **)); -static int setipaddr __P((char *, char **, int)); +/* setipaddr() must not be static, otherwise you can't connect with portslave */ +int setipaddr __P((char *, char **, int)); static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); static option_t ipcp_option_list[] = { @@ -375,7 +376,7 @@ * If doit is 0, the call is to check whether this option is * potentially an IP address specification. */ -static int +int setipaddr(arg, argv, doit) char *arg; char **argv; --- ppp-2.4.1/pppd/pppd.h Tue Mar 13 06:54:37 2001 +++ ppp-2.4.1-new/pppd/pppd.h Tue Jun 19 15:47:34 2001 @@ -572,6 +572,7 @@ char *get_first_ethernet __P((void)); /* Procedures exported from options.c */ +int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */ int parse_args __P((int argc, char **argv)); /* Parse options from arguments given */ int options_from_file __P((char *filename, int must_exist, int check_prot, portslave-2010.04.19.1/patches/ppp-2.4.1/024_pppd.8-persist-maxfail.diff0000664000000000000000000000071307411461424021506 0ustar # the manpage is slightly unclear here. --- ppp-2.4.1.orig/pppd/pppd.8 Tue Mar 13 18:54:37 2001 +++ ppp-2.4.1/pppd/pppd.8 Thu Jul 5 00:02:09 2001 @@ -790,7 +790,8 @@ .TP .B persist Do not exit after a connection is terminated; instead try to reopen -the connection. +the connection. The \fBmaxfail\fR option still has an effect on +persistent connections. .TP .B plugin \fIfilename Load the shared library object file \fIfilename\fR as a plugin. This portslave-2010.04.19.1/patches/ppp-2.4.1/001_udeb.diff0000664000000000000000000000116007411461424016176 0ustar --- ppp-2.4.0b4.orig/chat/Makefile.linux +++ ppp-2.4.0b4/chat/Makefile.linux @@ -6,7 +6,7 @@ CDEF4= -DFNDELAY=O_NDELAY # Old name value CDEFS= $(CDEF1) $(CDEF2) $(CDEF3) $(CDEF4) -CFLAGS= -O2 -g -pipe $(CDEFS) +CFLAGS= $(UDEB_CFLAGS) -O2 -g -pipe $(CDEFS) INSTALL= install --- ppp-2.4.0b4.orig/pppd/Makefile.linux +++ ppp-2.4.0b4/pppd/Makefile.linux @@ -58,7 +58,7 @@ COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP -CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) +CFLAGS= $(UDEB_CFLAGS) $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) ifdef CHAPMS CFLAGS += -DCHAPMS=1 portslave-2010.04.19.1/patches/ppp-2.4.1/007_ipcp.h.diff0000664000000000000000000000047407411461424016455 0ustar --- ppp-2.4.0b4.orig/pppd/ipcp.h +++ ppp-2.4.0b4/pppd/ipcp.h @@ -70,4 +70,10 @@ 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; portslave-2010.04.19.1/patches/ppp-2.4.1/008_pathnames.h.diff0000664000000000000000000000075707411461424017507 0ustar --- ppp-2.4.0b4.orig/pppd/pathnames.h +++ ppp-2.4.0b4/pppd/pathnames.h @@ -26,7 +26,7 @@ #define _PATH_AUTHUP _ROOT_PATH "/etc/ppp/auth-up" #define _PATH_AUTHDOWN _ROOT_PATH "/etc/ppp/auth-down" #define _PATH_TTYOPT _ROOT_PATH "/etc/ppp/options." -#define _PATH_CONNERRS _ROOT_PATH "/etc/ppp/connect-errors" +#define _PATH_CONNERRS _ROOT_PATH "/var/log/ppp-connect-errors" #define _PATH_PEERFILES _ROOT_PATH "/etc/ppp/peers/" #define _PATH_RESOLV _ROOT_PATH "/etc/ppp/resolv.conf" portslave-2010.04.19.1/patches/ppp-2.4.1/017_memory_management.diff0000664000000000000000000000043007411461424020771 0ustar --- ppp-2.4.1.orig/pppd/main.c Tue Mar 13 06:56:19 2001 +++ ppp-2.4.1/pppd/main.c Tue Jul 10 07:47:28 2001 @@ -1779,6 +1779,9 @@ if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) error("tdb_store failed: %s", tdb_error(pppdb)); + if (vbuf) + free(vbuf); + } /* portslave-2010.04.19.1/patches/ppp-2.4.1/013_scripts_ip-up.diff0000664000000000000000000000247007411461424020070 0ustar --- ppp-2.4.0b4.orig/scripts/ip-up +++ ppp-2.4.0b4/scripts/ip-up @@ -0,0 +1,45 @@ +#!/bin/sh +# +# $Id: ip-up,v 1.1 1997/12/16 11:37:26 phil Exp $ +# +# This script is run by the pppd after the link is established. +# It should be used to add routes, set IP address, run the mailq +# etc. +# +# This script is called with the following arguments: +# Arg Name Example +# $1 Interface name ppp0 +# $2 The tty ttyS1 +# $3 The link speed 38400 +# $4 Local IP number 12.34.56.78 +# $5 Peer IP number 12.34.56.99 + +# The environment is cleared before executing this script +# so the path must be reset +PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin +export PATH +# These variables are for the use of the scripts run by run-parts +PPP_IFACE="$1" +PPP_TTY="$2" +PPP_SPEED="$3" +PPP_LOCAL="$4" +PPP_REMOTE="$5" +export PPP_IFACE PPP_TTY PPP_SPEED PPP_LOCAL PPP_REMOTE + +# as an additional convienince, $PPP_TTYNAME is set to the tty name, +# stripped of /dev/ (if present) for easier matching. +PPP_TTYNAME=`/usr/bin/basename "$2"` +export PPP_TTYNAME + +# Main Script starts here + +run-parts /etc/ppp/ip-up.d + +# if pon was called with the "quick" arg, stop ppp now +if [ -r /var/run/ppp-quick ] +then + wait + /usr/bin/poff +fi + +# last line portslave-2010.04.19.1/patches/ppp-2.4.1/004_auth.c.diff0000664000000000000000000000061007411461424016443 0ustar --- ppp-2.4.0b4.orig/pppd/auth.c +++ ppp-2.4.0b4/pppd/auth.c @@ -1120,7 +1120,7 @@ if (pam_error == PAM_SUCCESS && !PAM_error) { pam_error = pam_acct_mgmt (pamh, PAM_SILENT); if (pam_error == PAM_SUCCESS) - pam_open_session (pamh, PAM_SILENT); + pam_error = pam_open_session (pamh, PAM_SILENT); } *msg = (char *) pam_strerror (pamh, pam_error); portslave-2010.04.19.1/patches/ppp-2.4.1/009_SETUP.diff0000664000000000000000000000065307411461424016175 0ustar --- ppp-2.4.0b4.orig/SETUP +++ ppp-2.4.0b4/SETUP @@ -21,7 +21,7 @@ that you will be dialling. For example, suppose the file is called /etc/ppp/peers/isp. This file would contain something like this: -cua0 # modem is connected to /dev/cua0 +ttyS0 # modem is connected to /dev/ttyS0 38400 # run the serial port at 38400 baud crtscts # use hardware flow control noauth # don't require the ISP to authenticate itself portslave-2010.04.19.1/patches/ppp-2.4.1/011_scripts_redialer.diff0000664000000000000000000001126207411461424020622 0ustar --- ppp-2.4.0b4.orig/scripts/redialer +++ ppp-2.4.0b4/scripts/redialer @@ -1,96 +1,69 @@ #!/bin/sh -################################################################### # -# These parameters control the attack dialing sequence. +# A chatscript that will attempt to dial multiple numbers in sequence, until +# you get connected. # -# Maximum number of attempts to reach the telephone number(s) -MAX_ATTEMPTS=10 - -# Delay between each of the attempts. This is a parameter to sleep -# so use "15s" for 15 seconds, "1m" for 1 minute, etc. -SLEEP_DELAY=15s - -################################################################### +# To use: edit /etc/peers/provider, and change the connect line to read: +# connect "/usr/local/bin/redialer" # -# This is a list of telephone numbers. Add new numbers if you wish -# and see the function 'callall' below for the dial process. -PHONE1=555-1212 -PHONE2=411 +# See below for configuration. -################################################################### +# This is a list of chatscripts to use to get connected, and (optional) +# telephone numbers to call for each of those chatscripts. # -# If you use the ppp-on script, then these are passed to this routine -# automatically. There is no need to define them here. If not, then -# you will need to set the values. -# -ACCOUNT=my_account_name -PASSWORD=my_password +# Note that in the chatscripts, you may use #NUMBER#, this will be replaced +# with the number it is calling. You might want to use this to only have one +# chatscript that is used for all numbers, or you might need multiple +# chatscripts. -################################################################### -# -# Function to initialize the modem and ensure that it is in command -# state. This may not be needed, but it doesn't hurt. -# -function initialize -{ - chat -v TIMEOUT 3 '' AT 'OK-+++\c-OK' - return -} +PHONE1=123456789 +CHAT1=/etc/chatscripts/provider -################################################################### -# -# Script to dial a telephone -# -function callnumber -{ -chat -v \ - ABORT '\nBUSY\r' \ - ABORT '\nNO ANSWER\r' \ - ABORT '\nRINGING\r\n\r\nRINGING\r' \ - '' ATDT$1 \ - CONNECT '' \ - ogin:--ogin: $ACCOUNT \ - assword: $PASSWORD -# -# If the connection was successful then end the whole script with a -# success. -# - if [ "$?" = "0" ]; then - exit 0 - fi +PHONE2=912345678 +CHAT2=/etc/chatscripts/provider - return -} +PHONE3=891234567 +CHAT3=/etc/chatscripts/provider -################################################################### -# -# Script to dial any telephone number -# -function callall -{ -# echo "dialing attempt number: $1" >/dev/console - callnumber $PHONE1 -# callnumber $PHONE2 -} +PHONE4=789123456 +CHAT4=/etc/chatscripts/provider -################################################################### -# -# Initialize the modem to ensure that it is in the command state -# -initialize -if [ ! "$?" = "0" ]; then - exit 1 -fi +PHONE5=001234567 +CHAT5=/etc/chatscripts/provider +# How long to sleep between retries: # -# Dial telephone numbers until one answers -# +# Note that this is a parameter to sleep so use "15s" for 15 seconds, +# "1m" for 1 minute, etc +SLEEP_DELAY=1s + +# The code below does the dialing. + attempt=0 while : ; do - attempt=`expr $attempt + 1` - callall $attempt - if [ "$attempt" = "$MAX_ATTEMPTS" ]; then - exit 1 - fi - sleep "$SLEEP_DELAY" + attempt=`expr $attempt + 1` + NUMBER=`eval echo '$PHONE'$attempt` + CHAT=`eval echo '$CHAT'$attempt` + if [ ! "$CHAT" ]; then + attempt=0 + else + logger "Dialing attempt number: $attempt" + sed s/#NUMBER#/$NUMBER/ $CHAT >/etc/chatscripts/tmpchat + /usr/sbin/chat -v -f /etc/chatscripts/tmpchat + rm -f /etc/chatscripts/tmpchat + case $? in + 0) logger Connection established ; exit 0;; + 1) logger chat: exit 1, see manpage for details. ; exit 1;; + 2) logger chat: exit 2, see manpage for details. ; exit 2;; + 3) logger chat: exit 3, see manpage for details. ;; + 4) logger Line busy. ;; + 5) logger No Carrier. ;; + 6) logger A call is coming. Exiting! ; exit 1;; + 7) logger No dialtone. ;; + 8) logger An error occured. Exiting! ; exit 1;; + *) logger chat: exit $?, see manpage for details. ;; + esac + logger "Waiting $SLEEP_DELAY seconds before next try." + sleep $SLEEP_DELAY + fi done portslave-2010.04.19.1/patches/ppp-2.4.1/018_ip-up_option.diff0000664000000000000000000000641707411461424017723 0ustar --- ppp-2.4.1/pppd/ipcp.c Thu Mar 8 06:11:12 2001 +++ ppp-2.4.1-new/pppd/ipcp.c Tue Jun 19 15:35:36 2001 @@ -1734,7 +1734,7 @@ */ if (ipcp_script_state == s_down && ipcp_script_pid == 0) { ipcp_script_state = s_up; - ipcp_script(_PATH_IPUP); + ipcp_script(path_ipup); } } @@ -1777,7 +1777,7 @@ /* Execute the ip-down script */ if (ipcp_script_state == s_up && ipcp_script_pid == 0) { ipcp_script_state = s_down; - ipcp_script(_PATH_IPDOWN); + ipcp_script(path_ipdown); } } @@ -1828,13 +1828,13 @@ case s_up: if (ipcp_fsm[0].state != OPENED) { ipcp_script_state = s_down; - ipcp_script(_PATH_IPDOWN); + ipcp_script(path_ipdown); } break; case s_down: if (ipcp_fsm[0].state == OPENED) { ipcp_script_state = s_up; - ipcp_script(_PATH_IPUP); + ipcp_script(path_ipup); } break; } --- ppp-2.4.1/pppd/main.c Tue Mar 13 06:56:19 2001 +++ ppp-2.4.1-new/pppd/main.c Tue Jun 19 15:35:36 2001 @@ -233,6 +233,9 @@ struct protent *protp; char numbuf[16]; + strlcpy(path_ipup, "/etc/ppp/ip-up", sizeof(path_ipup)); + strlcpy(path_ipdown, "/etc/ppp/ip-down", sizeof(path_ipup)); + new_phase(PHASE_INITIALIZE); /* --- ppp-2.4.1/pppd/options.c Tue Mar 13 06:56:19 2001 +++ ppp-2.4.1-new/pppd/options.c Tue Jun 19 15:38:32 2001 @@ -85,6 +85,8 @@ bool dump_options; /* print out option values */ bool dryrun; /* print out option values and exit */ char *domain; /* domain name set by domain option */ +char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */ +char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */ extern option_t auth_options[]; extern struct stat devstat; @@ -231,6 +233,12 @@ "Print out option values after parsing all options", 1 }, { "dryrun", o_bool, &dryrun, "Stop after parsing, printing, and checking options", 1 }, + { "ip-up-script", o_string, path_ipup, + "Set pathname of ip-up script", + OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, + { "ip-down-script", o_string, path_ipdown, + "Set pathname of ip-down script", + OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, #ifdef HAVE_MULTILINK { "multilink", o_bool, &multilink, --- ppp-2.4.1/pppd/pathnames.h Thu Mar 8 06:15:37 2001 +++ ppp-2.4.1-new/pppd/pathnames.h Tue Jun 19 15:35:36 2001 @@ -21,8 +21,6 @@ #define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets" #define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets" #define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options" -#define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up" -#define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down" #define _PATH_AUTHUP _ROOT_PATH "/etc/ppp/auth-up" #define _PATH_AUTHDOWN _ROOT_PATH "/etc/ppp/auth-down" #define _PATH_TTYOPT _ROOT_PATH "/etc/ppp/options." --- ppp-2.4.1/pppd/pppd.h Tue Mar 13 06:54:37 2001 +++ ppp-2.4.1-new/pppd/pppd.h Tue Jun 19 15:39:39 2001 @@ -272,6 +272,8 @@ extern char *bundle_name; /* bundle name for multilink */ extern bool dump_options; /* print out option values */ extern bool dryrun; /* check everything, print options, exit */ +extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */ +extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */ #ifdef PPP_FILTER extern struct bpf_program pass_filter; /* Filter for pkts to pass */ portslave-2010.04.19.1/patches/ppp-2.4.1/997_more_minor_warnings.diff0000664000000000000000000000170307411461424021370 0ustar diff -ru ppp-2.4.1/pppd/auth.c ppp-patched/pppd/auth.c --- ppp-2.4.1/pppd/auth.c Mon Oct 29 17:24:45 2001 +++ ppp-patched/pppd/auth.c Mon Oct 29 17:29:45 2001 @@ -64,6 +64,7 @@ #define PW_PPP PW_LOGIN #endif #endif +#include #include "pppd.h" #include "fsm.h" diff -ru ppp-2.4.1/pppd/md5.c ppp-patched/pppd/md5.c --- ppp-2.4.1/pppd/md5.c Mon Oct 29 17:30:13 2001 +++ ppp-patched/pppd/md5.c Mon Oct 29 17:26:46 2001 @@ -33,6 +33,7 @@ *********************************************************************** */ +#include #include "md5.h" /* Binary files ppp-2.4.1/pppd/pppd and ppp-patched/pppd/pppd differ diff -ru ppp-2.4.1/pppd/utils.c ppp-patched/pppd/utils.c --- ppp-2.4.1/pppd/utils.c Mon Oct 29 17:30:13 2001 +++ ppp-patched/pppd/utils.c Mon Oct 29 17:26:46 2001 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include portslave-2010.04.19.1/patches/ppp-2.4.1/006_ipcp.c.diff0000664000000000000000000000165507411461424016451 0ustar --- ppp-2.4.0b4.orig/pppd/ipcp.c +++ ppp-2.4.0b4/pppd/ipcp.c @@ -241,6 +241,13 @@ #define CILEN_ADDR 6 /* new-style single address option */ #define CILEN_ADDRS 10 /* old-style dual address option */ +/* + * Added to allow static and dynamic ips(s) + * Hold the static address from pap-secrets + */ +u_int32_t staticaddr; +/******************************************/ + #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") @@ -1263,6 +1270,15 @@ 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); } portslave-2010.04.19.1/patches/ppp-2.4.1/025_packet_count.diff0000664000000000000000000000125507417375406017763 0ustar --- ppp-2.4.1.orig/pppd/pppd.h Tue Mar 13 06:54:37 2001 +++ ppp-2.4.1/pppd/pppd.h Mon Jul 9 17:44:28 2001 @@ -147,6 +147,8 @@ struct pppd_stats { unsigned int bytes_in; unsigned int bytes_out; + unsigned int pkts_in; + unsigned int pkts_out; }; /* Used for storing a sequence of words. Usually malloced. */ --- ppp-2.4.1.org/pppd/sys-linux.c Tue Mar 13 06:54:41 2001 +++ ppp-2.4.1/pppd/sys-linux.c Mon Jul 9 17:44:28 2001 @@ -1236,6 +1236,8 @@ } stats->bytes_in = req.stats.p.ppp_ibytes; stats->bytes_out = req.stats.p.ppp_obytes; + stats->pkts_in = req.stats.p.ppp_ipackets; + stats->pkts_out = req.stats.p.ppp_opackets; return 1; } portslave-2010.04.19.1/patches/ppp-2.4.1/022_lockfile-fix.diff0000664000000000000000000000136407411461424017644 0ustar diff -ruN -x Makefile.in -x configure -x *~ ppp-2.4.1.orig/pppd/utils.c ppp-2.4.1/pppd/utils.c --- ppp-2.4.1.orig/pppd/utils.c Fri Mar 16 15:28:05 2001 +++ ppp-2.4.1/pppd/utils.c Thu Jul 12 20:26:31 2001 @@ -819,9 +819,20 @@ major(sbuf.st_rdev), minor(sbuf.st_rdev)); #else char *p; + char lockdev[MAXPATHLEN]; + + if ((p = strstr(dev, "dev/")) != NULL) { + dev = p + 4; + strncpy(lockdev, dev, MAXPATHLEN-1); + lockdev[MAXPATHLEN-1] = 0; + while ((p = strrchr(lockdev, '/')) != NULL) { + *p = '_'; + } + dev = lockdev; + } else + if ((p = strrchr(dev, '/')) != NULL) + dev = p + 1; - if ((p = strrchr(dev, '/')) != NULL) - dev = p + 1; slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); #endif portslave-2010.04.19.1/rlogin-8.10/0000775000000000000000000000000007412472227013043 5ustar portslave-2010.04.19.1/debian/0000775000000000000000000000000012051676526012412 5ustar portslave-2010.04.19.1/debian/control0000664000000000000000000000162512051676525014020 0ustar Source: portslave Section: comm Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Russell Coker Build-Depends: debhelper, libradius1-dev, ppp-dev Standards-Version: 3.5.6 Package: portslave Architecture: any Depends: ${shlibs:Depends}, ppp (>= 2.4.5-5.1), radiusclient1 Description: Terminal server that does PPP and authenticates via RADIUS This package provides a program named portslave which will use AT commands to answer a modem when it rings. It will then display a login: prompt at which the user can enter a user-name and password. If the user sends PPP data then portslave will run its own pppd instead and authenticate the user via PAP. When the user-name and password are received they will be verified via a RADIUS server. . At the end of the call the accounting data will be written to the RADIUS server. portslave-2010.04.19.1/debian/changelog0000664000000000000000000006527112051676526014277 0ustar portslave (2010.04.19.1ubuntu1) raring; urgency=low * Merge from Debian unstable (LP: #1079649). Remaining changes: - Link library with -lcrypt to fix FTBFS. -- Vibhav Pant Sat, 17 Nov 2012 13:04:38 +0100 portslave (2010.04.19.1) unstable; urgency=high * Needs to be recompiled to work with the wheezy pppd. High urgency because it currently entirely fails to work. Closes: #679603 -- Russell Coker Sat, 30 Jun 2012 17:05:33 +1000 portslave (2010.04.19ubuntu1) precise; urgency=low * Link library with -lcrypt to fix FTBFS. -- Ilya Barygin Sat, 31 Dec 2011 11:50:01 +0400 portslave (2010.04.19) unstable; urgency=low * Fixed the "clean" target, should now build on other architectures. -- Russell Coker Mon, 19 Apr 2010 07:25:43 +1000 portslave (2010.03.30) unstable; urgency=low * Update Debhelper compatability to 7. * Don't needlessly link against libcrypt. * Remove postinst code to handle pre-lenny config file upgrades. Closes: #553290 * Built against the latest ppp package. Closes: #473080 * s/it's/its/ in description. Closes: #435680, #268539 * Don't depend on xutils. Closes: #575854 * Fixed all bugs, it's in use and important to some people, let's keep it in Debian. Closes: #559254 -- Russell Coker Tue, 30 Mar 2010 11:21:00 +1100 portslave (2005.04.03.1) unstable; urgency=high * Rebuild to work with the latest pppd. -- Russell Coker Thu, 31 Jul 2008 22:27:41 +1000 portslave (2005.04.03) unstable; urgency=high * Renamed the logcheck config file from portslave.pppd to portslave-pppd to fit with the new naming convention. * Made it build with the latest ppp. -- Russell Coker Sun, 4 Apr 2005 23:40:00 +1000 portslave (2004.03.26) unstable; urgency=low * Build-depends on ppp-dev. Closes: #240156 * Changed the version number as reported by the programs. * Note that the previous version totally disabled CHAP support (the previous changelog entry did not clearly state this). -- Russell Coker Fri, 26 Mar 2004 12:53:00 +1100 portslave (2004.03.21) unstable; urgency=low * Added an option to disable chap as the latest Debian ppp package has changed the CHAP hooks and I can't work out how to get it going again. -- Russell Coker Sun, 21 Mar 2004 22:37:00 +1100 portslave (2002.10.21) unstable; urgency=low * Fixed a bug in ./configure . -- Russell Coker Mon, 21 Oct 2002 06:39:00 +0200 portslave (2002.10.16) unstable; urgency=low * Added support for limiting the answer times. -- Russell Coker Wed, 16 Oct 2002 23:04:00 +0200 portslave (2002.09.17) unstable; urgency=low * New version that depends on libradius1. * Made "ssh" refer to version 2, and "ssh1" be the keyword for ssh V 1.x. * Fixed many trivial warnings about function parameters not being used. * Merged in FIDO support - haven't tested it yet. Author: Andy Pershin Adapted for recent versions by Dmitry Sergienko * Made rlogin use options "-8" and "-E". * Added CHAP support. -- Russell Coker Tue, 17 Sep 2002 00:24:00 +0200 portslave (2002.01.19) unstable; urgency=low * Added "%M" for multilink pppd option. * More changes related to removing support for ppp 2.4.0. -- Russell Coker Sat, 19 Jan 2002 16:33:00 +0100 portslave (2002.01.12) unstable; urgency=low * Remove support for ppp 2.4.0. -- Russell Coker Sat, 12 Jan 2002 21:02:00 +0100 portslave (2002.01.10) unstable; urgency=low * Made it not SEGV when DNS is down. * Changed some variable names to work with the next version of pppd. -- Russell Coker Thu, 10 Jan 2002 21:40:00 +0100 portslave (2001.12.28) unstable; urgency=low * Improved support for setting variables in chat script. -- Russell Coker Fri, 28 Dec 2001 00:10:00 +0100 portslave (2001.12.27) unstable; urgency=low * Added CLI support and changed the way that the initchat is parsed. This breaks old pslave.conf files. * Fixed a bug in ctlportslave so that it will clear old data from memory before displaying the logged on users (necessary for "cshow who"). * Stopped it using spaces in the Acct-Session-Id attribute. -- Russell Coker Thu, 27 Dec 2001 02:10:00 +0100 portslave (2001.12.16) unstable; urgency=low * Tidied up the debian/rules file. * Made it compile with older headers for the sockaddr_in code if you don't enable IPv6. * Made it compile with ppp*.tgz in the current directory as well as in the parent directory. * Fixed the callback patch. It compiles now - I can't test it though... * Added a patch to create potato packages to the docs directory. -- Russell Coker Sun, 16 Dec 2001 14:36:00 +0100 portslave (2001.12.11-1) unstable; urgency=low * Made the programs have the right version number. * Made it depend on the latest ppp Debian package. -- Russell Coker Tue, 11 Dec 2001 11:35:00 +0100 portslave (2001.12.11) unstable; urgency=low * Made the Acct-Session-Id aqttribute be sent in access-request packets as well as accounting. This may make it easier for some people to manage accounting. Made the Acct-Session-Id by default be the system time in seconds * 64K + the low 16bits of the PID in hex. Previously the decimal representation of the PID was merely appended to the decimal representation of the time, this meant that more space was taken up, and the session ids didn't always increase. * Added logcheck files. * Fixed a bug in ctlportslave that caused a buffer overflow on utmp parsing and a SEGV. -- Russell Coker Tue, 11 Dec 2001 10:38:00 +0100 portslave (2001.11.25) unstable; urgency=low * Added a patch from Cyclades for shadow password support. Also added support for MD5 hashed passwords. * Stopped warnings when unused port definitions reference non-existant devices. * Added a real bool type to the source. Makes the code clearer. * Started work on CID. * Added support for gethostbyname2() for IPv6. Not fully tested but works better than the previous code that broke gethostbyname() for IPv4. -- Russell Coker Sun, 25 Nov 2001 13:11:00 +0100 portslave (2001.11.18) unstable; urgency=low * Forced to change the syntax of hostname-service type for IPv6 support. Now use [a.b.c.d]port format. * IPv6 might even work. I have it sending RADIUS packets to ::1, now I need an IPv6 RADIUS server... -- Russell Coker Sun, 18 Nov 2001 21:45:00 +0100 portslave (2001.11.17) unstable; urgency=low * Made location an enum type. * Made the Debian package depend on the latest woody version. * Stopped the double messages about authentication failure. * Added a pppd patch for persistant IPv6 addresses. * Started work on IPv6 support. Use ./configure --enable-ipv6 to compile with it. It currently doesn't compile with IPv6 enabled... * Changed the parsing code to remove the remnants of the old way of doing it. Makes the code more readable. -- Russell Coker Sat, 17 Nov 2001 18:37:00 +0100 portslave (2001.11.11) unstable; urgency=low * Added new config directive for DCD related setting "%d". * Fixed a bug with rlogin/ssh where Portslave tried to connect to 0.0.0.0. -- Russell Coker Sun, 11 Nov 2001 20:18:00 +0100 portslave (2001.11.08) unstable; urgency=low * Adds more serial error checking and streamlined the default config file. * Made the default config file not allow locallogins! Also made the logging clearer. * The last version was broken badly, it never asked as a password (so any account with a password was unusable ;). Also ports were always recognised as port 0 for "portslave -" and by libpsr. It was only a development release anyway. * Made the error message be displayed on authentication failure, and fixed a potential SEGV in the failure message code. * Synchronised the patches with the latest Debian package. -- Russell Coker Thu, 8 Nov 2001 18:31:00 +0100 portslave (2001.11.05) unstable; urgency=low * Ran flawchecker to check for potential security problems. Now use /dev/urandom for random authentication vectors. Also tightened up some potentially nasty code in syslog.c and ctlportslave. The /dev/urandom change fixes a potential attack, the others just prevent SEGVs. * Added a ./configure option for enabling the IP address assignment. Also fixed a couple of minor IP assignment related bugs that crept in when merging the patch. * Removed README.NET and moved the data into portslave(8). * Merged in more code from Cyclades. * Made "s{32-63}.tty tts/C{0-31}" be a valid type of config syntax. -- Russell Coker Mon, 5 Nov 2001 20:03:00 +0100 portslave (2001.11.01) unstable; urgency=low * Started adding TACACS support. * Finished merging the callback support. Run "./configure --enable-callback" to compile it in. I haven't tested it though. * Changed the way patches are applied so the compile will abort immidiately if a patch fails. -- Russell Coker Thu, 1 Nov 2001 17:01:00 +0100 portslave (2001.10.29) unstable; urgency=low * Partial merge of Callback patch from Alexandr D. Kanevskiy . Also added some other minor patched from him. * Merge of IP assignment patch (forgot who that came from - sorry), disabled by default. I haven't tested enabling this! * Made a Framed-Route with a mask of /32 mean "route add -host" instead of "route add -net". Now we can have single IPs in framed routes. * Removed the ./configure option for the number of ports. Make it work with an arbitary large number of ports. NB ctlportslave will run out of memory if you use too high numbers... * Made ctlportslave not display idle ports. Also added an option for continuously updating the display. -- Russell Coker Mon, 29 Oct 2001 17:38:00 +0200 portslave (2001.10.26) unstable; urgency=low * Fix the RADIUS timeout code, made it try both servers in turn, not try server 0.0.0.0, and display the error messages correctly. * Fixed some buggy handling of error messages that could cause SEGV. -- Russell Coker Fri, 26 Oct 2001 22:53:00 +0200 portslave (2001.10.15) unstable; urgency=low * I broke accounting in 2001.10.09, fixed now. This also fixes a problem with utmp writing. It seems that if do_acct is set to false then the utmp record will have the IP address from pslave.conf even if that IP address was over-ruled by the RADIUS server! * Fixed utmpfrom in the default config documentation. Also made the variable in the source consistant with the config file so I don't make that mistake again. * Documented the environment variables used by portslave. -- Russell Coker Mon, 15 Oct 2001 01:18:00 +0200 portslave (2001.10.13) unstable; urgency=low * Improved the error reporting for DNS problems. * Fixed a parsing bug where unexpected tabs confused it. * Fixed a bug in the .spec file. -- Russell Coker Sat, 13 Oct 2001 19:01:00 +0200 portslave (2001.10.09) unstable; urgency=low * Removed some code from the memory management patch that's supposed to be buggy. * Reformatted the code slightly. * Fixed the .spec file to match the removal of the libpsr directory and the creation of an extra shared object. -- Russell Coker Tue, 9 Oct 2001 20:57:00 +0200 portslave (2001.10.06) unstable; urgency=low * Huge changes with this version, needs lots of testing!!! * Removed pppd-radius from the Debian package! Made it use the regular pppd. * Merged in the Cyclades code for local authentication and stub code for TACACS (anyone got some TACACS client code to share with me?). * Added %g to the formatting strings for printing the PID and %H for the target host for login sessions. * Rewrote the error handling for RADIUS packet creation and re-formatted radclient.c. Also added a config option to specify the number of RADIUS retries. * Ignore break on serial port when doing modem negotiation and login prompt. * Added port number specification for telnet service. * Replaced all sleep() and usleep() calls with nanosleep(). * Replaced the ppp 2.4.1 patches with the patches from the Debian pppd package. The Debian package had all our patches and some extras so it makes sense to track them. This also included some callback code! * Implemented the Login-TCP-Port attribute, now need code for MPPP limiting. * Stopped ssh and rlogin from disabling escape character (leave it disabled for telnet because telnet allows "open" command). * Removed hacks supporting Linux kernel < 2.2.0. It should still work on old kernels, just not display stats properly for ppp. * Added new config parameter "radretries". * Made the start time be calculated from RADIUS login time for terminal authentication (used to be from ip-up time). * Removed the libpsr directory and moved the contents to src directory. * Updated to latest debian standards version and follow the latest Debian policy on stripping and debug generation. -- Russell Coker Sat, 6 Oct 2001 19:32:38 +0200 portslave (2001.10.02) unstable; urgency=low * Removed spurious "Detected login for" syslog message on AutoPPP. * Changed ctlportslave code for detecting idle time. Now if it can't open the device it will display idle time as -1. This makes it less painful to run ctlportslave as non-root. * Made ctlportslave not display entries where the process as listed in utmp does not exist. * Updated the default-config document to include the facility and change to the new format of config file. * Changed the default initchat script to use "\c" instead of "" for null send strings. * Merged in a small amount of code from portslave-new. Added location parameter (currently always 0 and unused), also added some new logging for ssh and ssh2. Should be no functional differences because of this, just easier for me to manage my code and easier to add new features in the next release... * Updated chat.c and rwconf.c to new code standards and added better error reporting. * Fixed the Debian config file upgrade code to not match on comments. * Made the default permissions of the config file deny world read. * Finally fixed all the autoconf variable substitution issues. * Made it work with more than one abort string in initchat (previously only the first would work). -- Russell Coker Tue, 2 Oct 2001 18:37:50 +0200 portslave (2001.09.09) unstable; urgency=low * Changed the version number to use dots instead of dashes because too many programs do strange things with dashes in version numbers. * Changed the ./configure script to fix some problems with directories. -- Russell Coker Sun, 09 Sep 2001 13:21:48 +0200 portslave (2001-08-30) unstable; urgency=low * Make it build properly on Debian. Closes: #110627 -- Russell Coker Thu, 30 Aug 2001 15:41:00 +0200 portslave (2001-08-22) unstable; urgency=low * Minor addition to pslave.conf(5) and Debian packaging. * Wrote upgrade script for Debian to convert the format of the config file. -- Russell Coker Wed, 22 Aug 2001 22:02:07 +0200 portslave (2001-08-17) unstable; urgency=low * Changed the configuration in a serious way. Made "all." and "conf." be synonyms (this makes it possible to set every parameter on a per-port basis). As part of this I changed conf.ipno to all.loc_host and all.ipno to all.rem_host. * Updated the documentation and removed some obsolete stuff. * Added new autoconf code based on the work of T. M. Pederson. * Made the number of ports a config option with default 256. * Changed the user-name and password max lengths to 64. * Made many more pointers const in radclient.c. * Removed debian/conffiles because we use DH_COMPAT=3 and it's automatic. * Added a +config-file option to Portslave to allow different ports to have different config files. This is not as necessary as it used to be now that every option can be set on a per-port basis, but will be handy for upgrades. * Added config options for parity, stop-bits, and bits per byte (default 8N1). * Restructured the getty code. * Fixed a config file parsing bug when running "portslave -" with a tty that's not in the config file. * Made failure to lock /var/run/radius.id a fatal error. -- Russell Coker Fri, 17 Aug 2001 01:45:12 +0200 portslave (2001-07-13) unstable; urgency=low * Added the conf.stripnames feature. * Fixed a bug in dynamic ip address (IP address spec ending in '+') parsing. * Now adds framed-route entries AFTER IP is brought up for PAP logins. * Made the chat-script code take up to 126 strings (was 62). * Added the "ABORT" keyword to chat scripts. -- Russell Coker Fri, 13 Jul 2001 15:48:15 +0200 portslave (2001-07-12) unstable; urgency=low * Minor fix to the man page. * Made the Debian package include pppd source. -- Russell Coker Thu, 12 Jul 2001 14:34:52 +0200 portslave (2001-07-11) unstable; urgency=low * Fixed a potential SEGV if you only define the secondary RADIUS server. * Made the config file case-insensitive for key words (still case sensitive for device names etc naturally). * Made the porttype setting an enum. -- Russell Coker Wed, 11 Jul 2001 14:30:16 +0200 portslave (2001-07-10) unstable; urgency=low * Fixed a bug whereby the first line of the config file wouldn't be parsed correctly by libpsr.so. * Fixed a potential buffer overflow parsing radius packets (too many filters, messages, or routes). * Made ctlportslave take 1 character abbreviations for everything. * Made Framed-Route work with terminal authentication. Also added some error logging for when the route command returns an error, made it handle a gateway of 0.0.0.0, and handle no specification of metric. * Added a memory leak patch for pppd 2.4.1. -- Russell Coker Tue, 10 Jul 2001 12:25:47 +0200 portslave (2001-07-09) unstable; urgency=low * Rewrote all the config code to only have the configuration for the line in use in memory. Saves about 500K of resident RAM for each running copy of Portslave. * Removed some cruft from ctlportslave, cut the binary from 30K to 13K. * Changed the maximum number of lines to 1024 (was 512). Could make it larger if necessary. * Made pppd display the correct "started by user" message when using terminal authentication. * Fixed the logging code properly. * Added ppp packet counting (seriously hacking pppd). -- Russell Coker Mon, 9 Jul 2001 17:48:33 +0200 portslave (2001-07-08) unstable; urgency=low * Added per-line option for logging passwords to syslog. * Changed the syslog code to not log to the console all the time. * Documented the utmpfrom field in the config file and fixed the default. * Fixed a potential buffer overflow in ctlportslave (MAXLINES checking). * Did some more work on hacking syslog() and the debug code. Also made the debug config setting an integer not a boolean! * Now SPECIAL_STATUS honors the sysutmp config setting. * The pppopt and autoppp options must use the plugin. pppopt needs the plugin for accounting. * Stopped "make install" from creating a rc.boot directory. * For Debian make DH_COMPAT=3. -- Russell Coker Sun, 8 Jul 2001 18:24:38 +0200 portslave (2001-07-05) unstable; urgency=low * Added "make dep" support. * Added new code for de-referencing sym-links for device names. This will make locking work better regarding /dev/modem and /dev/ttyS* on devfs. Now we use absolute path names for all devices internally and strip the "/dev/" from the start before writing to utmp. -- Russell Coker Thu, 5 Jul 2001 16:10:53 +0200 portslave (2001-07-02) unstable; urgency=low * Added #include in syslog.c, needed for htonl() etc. * Added a .spec file for RPM, don't know if it works. * Added support for specifying port numbers for services. * Changed the accounting service name to "radius-acct" which is the official name (used to be "radacct"). * Changed the default port numbers (used if /etc/services doesn't contain entries for "radius" and "radius-acct") to 1812 and 1813 from 1645 and 1646. * Changed the variable PPPLOGNAME to PORTSLAVELOGNAME to avoid conflicts with the environment variable pppd sets named PPPLOGNAME. * Made it work with ppp-x.x.x.tar.gz * Changed the version number in the RPM spec file to not have hyphens. -- Russell Coker Mon, 2 Jul 2001 16:32:33 +0200 portslave (2001-06-28) unstable; urgency=low * ./configure now checks for the location of rlogin * Fixed the bug where it would send a bogus second accounting-start record. * Made it log bytes and packets sent and received in the accounting-end record (actually the pppd code is missing for packet accounting, but the portslave code is already there). * Re-added pppd 2.4.0 support and included the pppd memory leak patch from "Arthur Naseef" . * Fixed a config parsing bug that resulted in dynamic addresses being reversed. * Tweaked the syslog code some more. Now it logs way too much, which is better than not logging enough. * Fixed the spawn code so that it won't fork() for PPP protocol. * Chat now works! * Added all the docs to the Debian package. * Wrote ctlportslave(1) and documented the chat script format for pslave.conf(5). * Made ctlportslave take the option "q" to quit, saves typing. -- Russell Coker Thu, 28 Jun 2001 17:45:01 +0200 portslave (2001-06-27) unstable; urgency=low * Added some more comments and did some more work on the logging code. * Re-wrote the chat code to try and fix a stack corruption bug (and make the code readable and maintainable. * Added a patch from "Arthur Naseef" to fix memory leaks. * Fixed the shutdown code, so that on error portslave shouldn't ever hang on exit. * Moved rlogin into it's own separate package. -- Russell Coker Wed, 27 Jun 2001 17:16:45 +0200 portslave (2001-06-26) unstable; urgency=low * Added ppp_version to the symbol table for libpsr. * Fixed the logging code, it's not more consistant and the code makes more sense (to me at least). * Removed radinit, it wasn't serving any purpose, it's apparently been dead code for some time. * Audited all strcpy() code and used a few strncmp() calls and other changes to reduce the risk of buffer overflows. * Updated docs/TODO * Made all code compile with lots of gcc warnings turned on and fixed all the problems it reports! * No longer use -I../src on the compiler command line. * Copied some code from Portslave 2.0A, including the %S parameter for format strings (it's the same as our %T but we have both for compatibility). -- Russell Coker Tue, 26 Jun 2001 12:00:00 +0200 portslave (2001-06-24) unstable; urgency=low * Wrote portslave(8). -- Russell Coker Sun, 24 Jun 2001 21:55:42 +0200 portslave (2001-06-22) unstable; urgency=low * Made the integer scanning return error if sscanf() can't get exactly one value. * Added a proper bool type to configuration that accepts 0/no/false or 1/yes/true just like bools in samba, changed the default config file appropriately. * "make clean" will not longer remove pslave_cfg.h * Fixed the logging code to use the regular openlog() and syslog() library calls from libc for local logging instead of the broken AF_UNIX code that was being used before. This makes it work on recent 2.2 kernels. -- Russell Coker Fri, 22 Jun 2001 12:00:00 +0200 portslave (2001-06-21) unstable; urgency=low * Fix lock file generation to only use the last directory componant so it'll work with devfs style names. * Added the -i option to the rlogin.1 man page. * Wrote a man page for pslave.conf(5). * Made more values have sensible defaults. -- Russell Coker Thu, 21 Jun 2001 22:58:11 +0200 portslave (2001-06-20) unstable; urgency=low * Made the PPP source external to the main source for Portslave and made it apply patches from a patch directory. This will make it 100 times easier to migrate Portslave to a new version of PPPD and make it easy to compile the same version for different versions of PPPD. * Changed the macro VERSION to PORTSLAVE_VERSION to avoid conflicts. * Fixed the installation of man pages, amoung other things it won't install wrong man pages on Debian. -- Russell Coker Wed, 20 Jun 2001 12:00:00 +0200 portslave (2001-04-04) unstable; urgency=low * More work on accounting. -- Russell Coker Wed, 4 Apr 2001 14:04:45 +1000 portslave (2001-04-03) unstable; urgency=low * Adds a better description. Closes: #87397 * Changed MAXLINES from 256 to 512 (just in case 256 isn't enough). * Made the included pppd source closer to the upstream. -- Russell Coker Tue, 3 Apr 2001 14:04:45 +1000 portslave (2001-02-20) unstable; urgency=low * Changed spawnit to support up to 254 parameters when executing a program, it used to be 30. * Added accounting patch from "Alexandr D. Kanevskiy" to make it correctly send accounting packets on AutoPPP sessions. * Fixed a bunch of trivial warnings from not including system header files. -- Russell Coker Tue, 20 Feb 2001 10:29:37 +0100 portslave (2000-12-25) unstable; urgency=low * Fixed the version code. -- Russell Coker Mon, 25 Dec 2000 06:14:16 +1100 portslave (2000-12-24) unstable; urgency=low * Initial Release. -- Russell Coker Sun, 24 Dec 2000 09:57:47 +1100 Local variables: mode: debian-changelog End: portslave-2010.04.19.1/debian/rules0000775000000000000000000000471311362674236013477 0ustar #!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 # This is the debhelper compatability version to use. export DH_COMPAT=7 export PKGDIR=`pwd`/debian/portslave configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. ./configure --prefix=/usr --mandir=/usr/share/man --with-pppdir=ppp-2.4.1 --sysconfdir=/etc/portslave --with-pppdradius=/usr/sbin/pppd --enable-ipv6 --enable-shadow --with-radclient-cfg=/etc/radiusclient/radiusclient.conf rm -rf ppp-2.4.1 mkdir -p ppp-2.4.1/pppd cp debian/pppd-Makefile.linux ppp-2.4.1/pppd/Makefile.linux touch configure-stamp build: configure-stamp build-stamp build-stamp: dh_testdir # Add here commands to compile the package. $(MAKE) EXTRA_CFLAGS="-DNO_CHAP -I/usr/include/pppd" #/usr/bin/docbook-to-man debian/portslave-2000-11.sgml > portslave-2000-11.1 touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. -$(MAKE) distclean dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/tmp. $(MAKE) deb-install INST_PREFIX=$(PKGDIR) mv $(PKGDIR)/etc/portslave/pslave.conf.sample $(PKGDIR)/etc/portslave/pslave.conf mkdir -p $(PKGDIR)/usr/share/lintian/overrides cp debian/lintian $(PKGDIR)/usr/share/lintian/overrides/portslave # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install # dh_testversion dh_testdir dh_testroot # dh_installdebconf dh_installdocs docs/* mv $(PKGDIR)/usr/share/doc/portslave/LICENSE $(PKGDIR)/usr/share/doc/portslave/copyright mv $(PKGDIR)/usr/share/doc/portslave/logcheck $(PKGDIR)/etc/logcheck/ignore.d.server/portslave mv $(PKGDIR)/usr/share/doc/portslave/logcheck.pppd $(PKGDIR)/etc/logcheck/ignore.d.server/portslave-pppd dh_installexamples dh_installmenu # dh_installpam # dh_installinit # dh_installmanpages # dh_undocumented dh_installchangelogs dh_link dh_strip dh_compress dh_fixperms chmod 640 $(PKGDIR)/etc/portslave/pslave.conf # dh_makeshlibs dh_installdeb # dh_perl dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure portslave-2010.04.19.1/debian/pppd-Makefile.linux0000664000000000000000000000000510027273017016131 0ustar all: portslave-2010.04.19.1/debian/lintian0000664000000000000000000000011107411447422013757 0ustar portslave: non-standard-file-perm etc/portslave/pslave.conf 0640 != 0644 portslave-2010.04.19.1/debian/dirs0000664000000000000000000000007407411462760013274 0ustar usr/sbin etc/portslave/filters etc/logcheck/ignore.d.server portslave-2010.04.19.1/install.sh0000775000000000000000000001067507411405572013201 0ustar ## ## install -- Install a program, script or datafile ## Copyright (c) 1997-2000 Ralf S. Engelschall ## Originally written for shtool ## ## This file is part of shtool and free software; you can redistribute ## it and/or modify it under the terms of the GNU General Public ## License as published by the Free Software Foundation; either version ## 2 of the License, or (at your option) any later version. ## ## This file is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ## USA, or contact Ralf S. Engelschall . ## str_tool="install" str_usage="[-v] [-t] [-c] [-C] [-s] [-m] [-o] [-g] [-e] [ ...] " arg_spec="2+" opt_spec="v.t.c.C.s.m:o:g:e:" opt_v=no opt_t=no opt_c=no opt_C=no opt_s=no opt_m="" opt_o="" opt_g="" opt_e="" . ./sh.common # determine source(s) and destination argc=$# srcs="" while [ $# -gt 1 ]; do srcs="$srcs $1" shift done dstpath="$1" # type check for destination dstisdir=0 if [ -d $dstpath ]; then dstpath=`echo "$dstpath" | sed -e 's:/$::'` dstisdir=1 fi # consistency check for destination if [ $argc -gt 2 -a $dstisdir = 0 ]; then echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2 exit 1 fi # iterate over all source(s) for src in $srcs; do dst=$dstpath # If destination is a directory, append the input filename if [ $dstisdir = 1 ]; then dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'` dst="$dst/$dstfile" fi # Add a possible extension to src and dst if [ ".$opt_e" != . ]; then src="$src$opt_e" dst="$dst$opt_e" fi # Check for correct arguments if [ ".$src" = ".$dst" ]; then echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2 continue fi if [ -d "$src" ]; then echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2 continue fi # Make a temp file name in the destination directory dsttmp=`echo $dst |\ sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \ -e "s;\$;/#INST@$$#;"` # Verbosity if [ ".$opt_v" = .yes ]; then echo "$src -> $dst" 1>&2 fi # Copy or move the file name to the temp name # (because we might be not allowed to change the source) if [ ".$opt_C" = .yes ]; then opt_c=yes fi if [ ".$opt_c" = .yes ]; then if [ ".$opt_t" = .yes ]; then echo "cp $src $dsttmp" 1>&2 fi cp $src $dsttmp || exit $? else if [ ".$opt_t" = .yes ]; then echo "mv $src $dsttmp" 1>&2 fi mv $src $dsttmp || exit $? fi # Adjust the target file # (we do chmod last to preserve setuid bits) if [ ".$opt_s" = .yes ]; then if [ ".$opt_t" = .yes ]; then echo "strip $dsttmp" 1>&2 fi strip $dsttmp || exit $? fi if [ ".$opt_o" != . ]; then if [ ".$opt_t" = .yes ]; then echo "chown $opt_o $dsttmp" 1>&2 fi chown $opt_o $dsttmp || exit $? fi if [ ".$opt_g" != . ]; then if [ ".$opt_t" = .yes ]; then echo "chgrp $opt_g $dsttmp" 1>&2 fi chgrp $opt_g $dsttmp || exit $? fi if [ ".$opt_m" != . ]; then if [ ".$opt_t" = .yes ]; then echo "chmod $opt_m $dsttmp" 1>&2 fi chmod $opt_m $dsttmp || exit $? fi # Determine whether to do a quick install # (has to be done _after_ the strip was already done) quick=no if [ ".$opt_C" = .yes ]; then if [ -r $dst ]; then if cmp -s $src $dst; then quick=yes fi fi fi # Finally install the file to the real destination if [ $quick = yes ]; then if [ ".$opt_t" = .yes ]; then echo "rm -f $dsttmp" 1>&2 fi rm -f $dsttmp else if [ ".$opt_t" = .yes ]; then echo "rm -f $dst && mv $dsttmp $dst" 1>&2 fi rm -f $dst && mv $dsttmp $dst fi done portslave-2010.04.19.1/README.txt0000664000000000000000000000110007421536213012647 0ustar How to compile pppd and rlogin. This version supports pppd version 2.4.1. The ./configure script by default will look in the parent directory for the most recent (according to an alpha-numeric sort) file matching "../ppp*gz". The ./configure script will create makefiles that take the name of the archive without the ".tar.gz" or ".tgz" extension as the name of the directory that it will be extracted to. Then it will extract the archive as part of the build process and compile the files it contains. Then it will apply patches from the patches/ppp-version directory. portslave-2010.04.19.1/CHANGES0000664000000000000000000000002507416263766012167 0ustar See debian/changelog portslave-2010.04.19.1/extract_and_patch.in0000664000000000000000000000041307422044570015163 0ustar #!/bin/sh -e if [ ! -d @pppdir@ ]; then tar xzf @pppsourcedir@/@pppdir@.t*gz cd @pppdir@ for n in ../patches/@pppdir@/* @callback_patch@ do if [ -f $n ]; then echo "Applying patch $n" patch -p1 < $n fi done cd .. make -C src dep fi portslave-2010.04.19.1/ctlportslave.10000664000000000000000000000200311354242244013756 0ustar .TH "ctlportslave" "1" "2010.03.30" "Russell Coker " "Portslave" .SH "NAME" ctlportslave \- terminal server control and monitor program. .SH "SYNOPSIS" .B ctlportslave .I [\-f [\-p password] [\-r password]] .SH "DESCRIPTION" This manual page documents briefly the .BR ctlportslave , program. .P This program is a management program for the .B portslave program. .SH "OPTIONS" .TP .B \-f act as finger daemon. .TP .B \-p password specify the finger password. .TP .B \-r password specify the password to reset a port through the finger daemon. .SH "FINGER OPERATION" This program can be run as a finger daemon. Just set it up in your inetd configuration to be listening on the finger port. Then run .B finger help@nas to get more information. .SH "AUTHOR" This man page was written by Russell Coker . May be freely used and distributed without restriction. .SH "SEE ALSO" .BR pslave.conf (5), .BR pppd (8), .BR portslave (8) .BR http://doc.coker.com.au/projects/portslave/ portslave-2010.04.19.1/portslave.8.in0000664000000000000000000000373611354242246013707 0ustar .TH "portslave" "8" "2010.03.30" "Russell Coker " "Portslave" .SH "NAME" portslave \- terminal server program. .SH "SYNOPSIS" .B portslave .I [+config\-file] port|\- .SH "DESCRIPTION" This manual page documents briefly the .BR portslave , program. .P This program is a getty replacement that will run it's own version of pppd, the user can specify their user\-name via a login: prompt or PPP PAP negotiation. After the username and password have been supplied the user will be authenticated by the RADIUS protocol. .SH "OPTIONS" An optional first parameter is '+config\-file' to specify an alternate config file. The default is @sysconfdir@/pslave.conf . The next parameter is either the port number or '\-'. The value '\-' means that portslave is to use it's controlling tty as the serial device and inspect the config file to find the RADIUS port number which matches that. This was originally written for telnetd support (telnetd puts a '\-' as the first command line parameter) but can be used for other things. To run over the telnet protocol put a config entry similar to the following in your inetd configuration: .B telnet stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.telnetd -L /usr/sbin/portslave Then in the pslave.conf file put a series of entries specifying every pseudo-tty device (either ptyp0, ptyp1, etc or pts/1, pts/2 etc depending on which type of device naming you use). For the RADIUS port numbers which are to be used for telnet connections you must specify the initchat as an empty string. If you want to run portslave over a clean TCP connection (no telnet protocol) then put the following in your inetd configuration: .B telnet stream tcp nowait root /usr/sbin/tcpd /usr/sbin/portslave - .SH "AUTHOR" This man page was written by Russell Coker . May be freely used and distributed without restriction. .SH "SEE ALSO" .BR pslave.conf (5), .BR pppd (8), .BR ctlportslave (1) .BR http://doc.coker.com.au/projects/portslave/ portslave-2010.04.19.1/src/0000775000000000000000000000000012051676525011756 5ustar portslave-2010.04.19.1/src/Makefile.in0000664000000000000000000000173712051676525014033 0ustar CC = @CC@ CFLAGS = @CFLAGS@ -I../@pppdir@/pppd ${EXTRA_CFLAGS} ALL: libpsr.so portslave ctlportslave LIBOBJS = radclient.o lib.o rwconf.o chat.o tstr.o md5.o syslog.o utmp.o auth.o OBJS = main.o getty.o rot_getty.o spawnit.o slip.o ctlp-subs.o #OBJS = main.o getty.o rot_getty.o spawnit.o slip.o ctlp-subs.o sock_src.o #LIBS = $(LIBOBJS) #LIBDEP = $(LIBOBJS) LIBS = -L. -lportslave LIBDEP = libportslave.so libpsr.so: libpsr_pic.o $(LIBDEP:.o=_pic.o) $(CC) -shared $(CFLAGS) -o $@ $< $(LIBS:.o=_pic.o) libportslave.so: $(LIBOBJS:.o=_pic.o) $(CC) -shared $(CFLAGS) -o $@ $^ $(LDFLAGS) -lradiusclient -lcrypt portslave: $(OBJS) libpsr.so $(LIBDEP) $(CC) -o portslave $(OBJS) $(LIBS) ctlportslave: ctlportslave.o ctlp-subs.o $(CC) -o ctlportslave ctlportslave.o ctlp-subs.o %_pic.o: %.c $(CC) $(CFLAGS) -fPIC -DPIC -c -o $@ $< clean: rm -f *~ *.o *.a *.so portslave ctlportslave make -C tacc clean dep: -makedepend -Y -f depends *.c 2> /dev/null include depends portslave-2010.04.19.1/src/server.h0000664000000000000000000000576607550422620013444 0ustar #ifndef __server_h #define __server_h #define _GNU_SOURCE #include "../pslave_cfg.h" #include #include "rwconf.h" #include "auth.h" #include #ifndef HAVE_IPV6 #define in_port_t uint16_t #endif void nsyslog(int pri, const char *fmt, ...); void nopenlog(const char *ident, int logstat, int logfac); char *check_device(const char *file); #define P_IDLE 0 #define P_INCOM 5 #define P_LOGIN 10 /* Range of normal, non escape ascii chars */ #define Fascii 32 /* Space */ #define Lascii 126 /* Tilde */ /* Some syntatic sugar */ #define true 1 #define false 0 /* defined in ppp headers typedef unsigned char bool; */ /* * Global functions for the portslave. */ int do_socket(struct auth *ai); void tstr(char *out, int sending, const char *input); int dolock(const char *lock_name); void dolock_and_wait(int sleep_time); int islocked(const char *lock_name); int tty_copy(int crnl, int in, int out); void xsleep(unsigned int seconds); void xusleep(unsigned long usec); void *xmalloc(int size); void *xrealloc(void *ptr, int size); char *xstrdup(const char *str); void block(int sig); void unblock(int sig); char *static_num(int i); int get_sessiontime(const struct auth *ai); long chktimes(); typedef enum { eNoErr = 0, eInterrupt, eTimeOut, eAbort, eStupidAdmin } CHAT_ERR; CHAT_ERR chat(int fd, const char *str, struct auth *ai); void unescape(char *); const char *dotted(unsigned int ipno); const char *dotted_sa(const struct sockaddr *sa, bool port); int sa_len(const struct sockaddr *sa); in_port_t *get_port_ptr(struct sockaddr *sa); typedef enum { eLocModem = 0, eLocBuf = 1, eLocSocket = 2, eLocSocSrv = 3 } LOCATION; int serial_open(LOCATION location); void serial_close(); int lockfile(char **lock_name, const char *lockdir, const char *tty , LOCATION location); int getty(struct auth *ai, LOCATION location); int emumodem(struct auth *ai, LOCATION location); void maketermsane(void); int do_login(struct auth *ai); int spawnit(struct auth *ai); void expand_format(char *buffer, size_t size, const char *format, const struct auth *ai); int do_slip(const struct auth * const ai); int update_utmp(const char *login_fmt, const char *from_fmt, const struct auth *ai, bool wtmp); /* GetPortNo should be used by the rest of the code to get the * "current" port number. ONLY main.c should call SetPortNo(). */ int GetPortNo(); void SetPortNo(int num); int GetChatTimeout(); void SetChatTimeout(int num); int GetChatSendDelay(); void SetChatSendDelay(int num); /* Global variables. */ extern void (*chat_debug_printf)(const char *, ...); /* used to compact sets of strings with '#' separators and store them in * environment variables, and to unpack them on retrieval. */ int setenv_from_rad(const char *name, const char **val, unsigned int num); int getenv_from_rad(const char *name, char **val, unsigned int max, unsigned int *num); #ifdef PORTSLAVE_CALLBACK #ifndef CB_CONF_USER #define CB_CONF_USER 2 #endif #ifndef CB_CONF_ADMIN #define CB_CONF_ADMIN 3 #endif #endif #endif /* __server_h */ portslave-2010.04.19.1/src/utmp.c0000664000000000000000000000307707466653756013135 0ustar /* * utmp.c Write system and radius utmp files. * * Version: #(#)utmp.c 1.00 12-Nov-1997 miquels@cistron.nl * */ #include #include #include #include #include #include "server.h" int update_utmp(const char *login_fmt, const char *from_fmt, const struct auth *ai, bool wtmp) { struct utmp tmp, *utmptr; FILE *fp; pid_t pid; char tmp_str [256]; char *tty; if(!lineconf.sysutmp) return 0; pid = getpid(); /* * Init should have setup this for us, so we * only update the entry if it exists (and only * at login - init does logout for us). */ setutent(); while((utmptr = getutent()) != NULL) { if (utmptr->ut_pid == pid) { break; } } if (utmptr) { tmp = *utmptr; } else { char id[8]; nsyslog(LOG_ERR, "No utmp entry found when expected for line %s.", lineconf.tty); snprintf(id, sizeof (id), "T%d", ai->nasport); memset(&tmp, 0, sizeof(tmp)); strncpy(tmp.ut_id, id, sizeof(tmp.ut_id)); tmp.ut_pid = getpid(); } tty = lineconf.tty; if(!strncmp(tty, "/dev/", 5)) tty += 5; expand_format (tmp_str, sizeof (tmp_str), login_fmt, ai); strncpy(tmp.ut_user, tmp_str, UT_NAMESIZE); expand_format (tmp_str, sizeof (tmp_str), from_fmt, ai); strncpy (tmp.ut_host, tmp_str, UT_HOSTSIZE); tmp.ut_type = USER_PROCESS; tmp.ut_time = time(NULL); strncpy(tmp.ut_line, tty, UT_LINESIZE); tmp.ut_addr = ai->address; setutent(); pututline(&tmp); endutent(); if (utmptr && wtmp && (fp = fopen(WTMP_FILE, "a")) != NULL) { fwrite(&tmp, sizeof(tmp), 1, fp); fclose(fp); } return 0; } portslave-2010.04.19.1/src/syslog.c0000664000000000000000000002050707411462147013443 0ustar /* * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94"; #endif /* LIBC_SCCS and not lint */ /* * SYSLOG -- print message on log file * * This routine looks a lot like printf, except that it outputs to the * log file instead of the standard output. Also: * adds a timestamp, * prints the module name in front of the message, * has some other formatting types (or will sometime), * adds a newline on the end of the message. * * The output of this routine is intended to be read by syslogd(8). * * Author: Eric Allman * Modified to use UNIX domain IPC by Ralph Campbell * Modified by Russell Coker to use the syslog() library function. I have * changed this so much that any blame or credit for this code is better * directed at me than at the above people. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "server.h" /* On libc5 writev() is not defined in sys/uio.h */ #ifndef _SYS_UIO_H extern int writev(int fd, const struct iovec *vector, size_t count); #endif /* value -1 means closed, value -2 means local logging */ static int LogFile = -1; /* fd for log */ static bool connected; /* have done connect */ static int LogStat = 0; /* status bits, set by openlog() */ static char *LogTag; /* string to tag the entry with */ static int LogFacility = LOG_LOCAL2; /* default facility code */ static int LogMask = 0xff; /* mask of priorities to be logged */ static void closelog_intern(int to_default) { if(LogFile == -2) closelog(); else close(LogFile); LogFile = -1; connected = false; if(to_default) { LogStat = 0; free(LogTag); LogTag = NULL; LogFacility = LOG_LOCAL2; LogMask = 0xff; } } static void nvsyslog(int pri, const char *fmt, va_list ap); /* * syslog, vsyslog -- * print message on log file; output is intended for syslogd(8). */ void nsyslog(int pri, const char *fmt, ...) { va_list ap; va_start(ap, fmt); nvsyslog(pri, fmt, ap); va_end(ap); } void nopenlog(const char *ident, int logstat, int logfac); static void nvsyslog(int pri, const char *fmt, va_list ap) { int cnt; char *tmp_ptr; time_t now; int saved_errno; char tbuf[2048], fmt_cpy[1024], *stdp = 0; char *real_message = tbuf; saved_errno = errno; /* See if we should just throw out this message. */ if(pri && LogMask < LOG_PRI(pri)) return; if(LogFile < 0 || !connected) nopenlog(NULL, LogStat | LOG_NDELAY, 0); /* Set default facility if none specified. */ if((pri & LOG_FACMASK) == 0) { pri |= LogFacility; } tmp_ptr = tbuf; if(LogFile != -2) /* If not doing local logging */ { /* Build the message. */ time(&now); snprintf(tbuf, sizeof(tbuf), "<%d>%.15s ", pri, ctime(&now) + 4); for(tmp_ptr = tbuf; *tmp_ptr; ++tmp_ptr); if(LogStat & LOG_PERROR) stdp = tmp_ptr; /* NB LogTag is no longer than 50 bytes so we won't run out of buffer */ if(LogTag) strcpy(tmp_ptr, LogTag); else strcpy(tmp_ptr, "portslave"); for (; *tmp_ptr; ++tmp_ptr); if(LogStat & LOG_PID) { snprintf(tmp_ptr, sizeof(tbuf)-(tmp_ptr-tbuf), "[%d]", getpid()); for (; *tmp_ptr; ++tmp_ptr); } *tmp_ptr++ = ':'; } /* end if(LogFile != -2) */ /* Substitute error message for %m. */ { /* We have to make sure we don't overrun fmt_cpy. */ int fmt_ind = 0, fmt_cpy_ind = 0; for (; fmt[fmt_ind] != '\0' && fmt_cpy_ind < ((int)sizeof(fmt_cpy) - 1); ) { if(fmt[fmt_ind] == '%' && fmt[fmt_ind + 1] == 'm') { fmt_ind++; strncpy(&fmt_cpy[fmt_cpy_ind], strerror(saved_errno), sizeof(fmt_cpy) - fmt_cpy_ind - 1); fmt_cpy[sizeof(fmt_cpy) - 1] = '\0'; fmt_cpy_ind = strlen(fmt_cpy); } else { fmt_cpy[fmt_cpy_ind] = fmt[fmt_ind]; fmt_cpy_ind++; } fmt_ind++; } fmt_cpy[fmt_cpy_ind] = '\0'; } real_message = tmp_ptr; tmp_ptr += vsnprintf(tmp_ptr, sizeof(tbuf) - (tmp_ptr - tbuf), fmt_cpy, ap); cnt = tmp_ptr - tbuf; /* Output to stderr if requested. */ if(LogStat & LOG_PERROR) { struct iovec iov[2]; struct iovec *v = iov; char c = '\n'; /* final new-line on string */ v->iov_base = stdp; v->iov_len = cnt - (stdp - tbuf); ++v; v->iov_base = &c; v->iov_len = 1; writev(STDERR_FILENO, iov, 2); } /* Output the message to the local logger. */ /* Use NULL as a message delimiter. */ if(LogFile == -2) { syslog(pri, "%s", real_message); } else if(write(LogFile, tbuf, cnt + 1) >= 1) { return; } else if(!lineconf.syslog) { /* If the write fails, we try to reconnect it next * time. */ closelog_intern (0); } } static int nsetlogmask(int pmask); /* * OPENLOG -- open system log */ void nopenlog(const char *ident, int logstat, int logfac) { struct sockaddr_in s_in; closelog(); if(LogTag) free(LogTag); if(ident) { LogTag = xstrdup(ident); if(strlen(LogTag) > 50) LogTag[50] = '\0'; } else { if(GetPortNo() >= 0) { char buf[64]; snprintf(buf, sizeof (buf), "port[S%d]", GetPortNo()); LogTag = xstrdup(buf); } else { LogTag = xstrdup("portslave"); } } switch(lineconf.debug) { case 1: nsetlogmask(LOG_INFO); break; case 2: nsetlogmask(LOG_DEBUG); break; default: nsetlogmask(LOG_NOTICE); } LogStat = logstat; if(logfac != 0 && (logfac &~ LOG_FACMASK) == 0) LogFacility = LOG_MAKEPRI(LOG_FAC(logfac), 0); else { if(lineconf.facility) LogFacility = LOG_MAKEPRI(LOG_FAC(LOG_LOCAL0) + lineconf.facility, 0); } if(LogFile >= 0) close(LogFile); if(lineconf.syslog) { s_in.sin_family = AF_INET; s_in.sin_port = htons(514); s_in.sin_addr.s_addr = lineconf.syslog; if((LogFile = socket(AF_INET, SOCK_DGRAM, 0)) != -1) { if(connect(LogFile, (const struct sockaddr *)&s_in, sizeof(s_in)) != -1) connected = true; } } else { openlog(LogTag, logstat, LogFacility); LogFile = -2; connected = true; } } /* * CLOSELOG -- close the system log */ void ncloselog() { closelog_intern(1); } /* * SETLOGMASK -- set the log mask level */ static int nsetlogmask(int pmask) { int omask; omask = LogMask; if(pmask != 0) LogMask = LOG_PRI(pmask); return (omask); } portslave-2010.04.19.1/src/tstr.c0000664000000000000000000000370707411462147013122 0ustar typedef unsigned char bool; #define true 1 #define false 0 /* * Parse string and replace escape sequences. * * sending: true if it's a chat-send string which has different escape syntax * out: string to write to, must point to a buffer the same size as * input, may point to the same buffer as input. */ void tstr(char *out, bool sending, const char *input) { while(*input) { /* Skip quotes. */ if (*input == '"') { input++; continue; } /* ^ for control character. */ if (*input == '^') { *out++ = *++input & 0x1f; if (*input) input++; /* Some escaped character. */ } else if (*input == '\\') { switch(*++input) { case '\n': break; case 'r': *out++ = '\r'; break; case 'n': *out++ = '\n'; break; case 'b': *out++ = '\b'; break; case 's': *out++ = ' '; break; case 't': *out++ = '\t'; break; case '-': /* Keep minus sign escaped. */ *out++ = '\\'; *out++ = *input; break; case '\\': case 'd': case 'p': case 'l': case 'c': case 'K': /* These are double escaped for chat_send(). */ if (sending) { *out++ = '\\'; *out++ = *input; break; } /*FALLTHRU*/ default: /* See if its an octal number. */ if (*input >= '0' && *input <= '7') { int val = *input - '0'; while(*++input >= '0' && *input <= '7') val = 8*val + (*input - '0'); input--; /* '\0' and '\\' are special. */ if (val == 0 || val == '\\') { *out++ = '\\'; *out++ = val ? '\\' : 'N'; } else *out++ = val; } else *out++ = *input; } if (*input) input++; } else /* Just a normal character. */ *out++ = *input++; } *out = 0; } /* * The tstr stuff is so useful that we export it. * * This function replaces "\n" with a new-line character etc. * The data pointed to by str is over-written. */ void unescape(char *str) { tstr(str, false, str); } portslave-2010.04.19.1/src/slip.c0000664000000000000000000001264007553275507013102 0ustar /* * slip.c Go into SLIP mode. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if !defined(__GLIBC__) # include # include # include #endif #include #include "server.h" static bool got_hup = false; /* * Note that we got the HUP signal. */ static void hup_handler() { got_hup = true; alarm(0); } /* * Setup the interface. */ static int slip_ifconfig(const struct auth * const ai, char *slname) { char cmd[100]; char local[16]; char remote[16]; char slip_netmask[16]; strcpy(remote, dotted(ai->host)); if(ai->address) strcpy(local, dotted(ai->address)); else strcpy(local, dotted(lineconf.loc_host)); strcpy(slip_netmask, dotted(ai->netmask)); /* Ifconfig the interface. */ if(ai->mtu > 0) { snprintf(cmd, sizeof (cmd), "exec %s %s %s pointopoint %s " "netmask %s mtu %d", PATH_IFCONFIG, slname, local , remote, slip_netmask, ai->mtu); } else { snprintf(cmd, sizeof (cmd), "exec %s %s %s pointopoint %s netmask %s" , PATH_IFCONFIG, slname, local, remote, slip_netmask); } return system(cmd); } /* * Add a route to this address. */ static int slip_addroute(const struct auth * const ai, char *slname) { char cmd[100]; char slip_netmask[16]; char network[16]; char remote[16]; unsigned int nw; int ret; /* Add a host pointopoint route. */ snprintf(cmd, sizeof (cmd), "exec %s add -host %s dev %s", PATH_ROUTE , dotted(ai->address), slname); if((ret = system(cmd)) != 0) return ret; /* See if we need to add a route to a whole network. */ if(ai->netmask && ai->netmask != 0xFFFFFFFF) { nw = ai->address & ai->netmask; strcpy(slip_netmask, dotted(ai->netmask)); strcpy(network, dotted(nw)); strcpy(remote, dotted(ai->address)); snprintf(cmd, sizeof (cmd), "exec %s add -net %s netmask %s gw %s" , PATH_ROUTE, network, slip_netmask, remote); ret = system(cmd); } return ret; } /* * Add a proxy arp entry. * * FIXME: we are very simplistic here. We should loop over * all interfaces and pick the right one (like pppd does). * */ static int slip_addproxy(const struct auth * const ai) { struct ifreq ifr; struct sockaddr *sa; int s; char ethaddr[16]; char cmd[100]; /* * First we have to find out our ethernet address. */ strcpy(ifr.ifr_name, "eth0"); if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { nsyslog(LOG_ERR, "slip_addproxy: socket: %m"); return -1; } if(ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { nsyslog(LOG_ERR, "slip_addproxy: SIOCGIFADDR: %m"); return -1; } sa = &(ifr.ifr_hwaddr); snprintf(ethaddr, sizeof (ethaddr), "%02x:%02x:%02x:%02x:%02x:%02x", (unsigned char)sa->sa_data[0], (unsigned char)sa->sa_data[1], (unsigned char)sa->sa_data[2], (unsigned char)sa->sa_data[3], (unsigned char)sa->sa_data[4], (unsigned char)sa->sa_data[5]); /* Add an proxy arp entry. */ if(ai->netmask && ai->netmask != 0xFFFFFFFF) { snprintf(cmd, sizeof (cmd), "exec %s -s %s %s netmask %s pub", PATH_ARP, dotted(ai->address), ethaddr, dotted(ai->netmask)); } else { snprintf(cmd, sizeof (cmd), "exec %s -s %s %s pub", PATH_ARP, dotted(ai->address), ethaddr); } return system(cmd); } /* * Delete proxy arp entry. */ static int slip_delproxy(const struct auth * const ai) { char cmd[100]; snprintf(cmd, sizeof (cmd), "exec %s -d %s pub", PATH_ARP, dotted(ai->address)); return system(cmd); } /* * Put port into SLIP mode. */ int do_slip(const struct auth * const ai) { struct termios tty, orig_tty; int disc, odisc; char slname[16]; int mode; struct sigaction sa; int time_limit = get_sessiontime(ai); /* * Catch SIGHUP and friends. */ got_hup = false; sa.sa_handler = hup_handler; sa.sa_flags = SA_RESTART; sigaction(SIGHUP, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); if(time_limit > 0) { alarm(time_limit); sigaction(SIGALRM, &sa, NULL); unblock(SIGALRM); } unblock(SIGHUP); unblock(SIGINT); unblock(SIGTERM); /* * First set terminal into raw mode */ tcgetattr(0, &tty); tcgetattr(0, &orig_tty); tty.c_lflag = 0; tty.c_iflag = 0; tty.c_oflag = 0; tcsetattr(0, TCSANOW, &tty); /* * Now set line discipline to SLIP. */ ioctl(0, TIOCGETD, &odisc); disc = N_SLIP; if(ioctl(0, TIOCSETD, &disc) < 0) { tcsetattr(0, TCSANOW, &orig_tty); if(errno == EINVAL) printf("Sorry - SLIP is not available on this system\r\n"); else perror("SLIP mode"); nsyslog(LOG_ERR, "TIOCSETD(SLIP): %m"); return -1; } /* * Now set to either SLIP or CSLIP. */ mode = (ai->proto == P_SLIP ? SL_MODE_SLIP : SL_MODE_CSLIP); (void) ioctl(0, SIOCSIFENCAP, &mode); /* * Find out the name of the interface, ifconfig it, * add routes, and set up proxyarp. */ ioctl(0, SIOCGIFNAME, slname); slip_ifconfig(ai, slname); slip_addroute(ai, slname); slip_addproxy(ai); /* * Now keep waiting for a SIGHUP. */ while(!got_hup) pause(); ioctl(0, TIOCSETD, &odisc); tcsetattr(0, TCSANOW, &orig_tty); slip_delproxy(ai); return 0; } portslave-2010.04.19.1/src/chat.c0000664000000000000000000004407010027251422013030 0ustar /* * chat.c This is a generic chat handler * for initialization of the modems. * * Version: (@)#chat.c 1.00 12-Sep-1995 MvS. * */ #include #include #include #include #include #include #include #include #include #include "../pslave_cfg.h" #include "server.h" enum special_code { SPECIAL_NONE = -1, SPECIAL_TIMEOUT = 0, /* change the timeout for the next expect string */ SPECIAL_WAIT, /* wait for carrier detect, parm must be DCD */ SPECIAL_STATUS, /* sets status in utmp, two params. */ SPECIAL_ABORT, /* sets abort string, one param. */ SPECIAL_SETVAR /* sets a string variable after receiving certain text, two params. */ }; struct special_chat { const char *word; enum special_code code; int req_words; /* params + 1 */ }; struct special_chat sw [] = { {"TIMEOUT", SPECIAL_TIMEOUT, 2}, {"WAIT", SPECIAL_WAIT, 2}, {"STATUS", SPECIAL_STATUS, 3}, {"ABORT", SPECIAL_ABORT, 2}, {"SETVAR", SPECIAL_SETVAR, 2}, {NULL, SPECIAL_NONE, 0} }; /* * Send a string to the remote side. Process any * left-over escape sequences. */ static void chat_send(int fd, const char *p) { char *s, *start, *end; bool addcr = true; /* whether to add a '\r' to the end of the string */ int flags, val; char c; nsyslog (LOG_DEBUG, "chat_send(%s)", p); /* Translate escape characters, pass 1 */ s = xstrdup(p); tstr(s, true, s); /* Delay a bit and then flush the input. */ xusleep(GetChatSendDelay() * 100000); tcflush(0, TCIFLUSH); /* Now send the string. */ start = end = s; while(1) { /* Collect characters till backslash or end of string. */ while(*end != '\\' && *end) end++; if(end != start) write(fd, start, end - start); if(*end == 0) { if(addcr) { c = '\r'; write(fd, &c, 1); } free(s); return; } /* Special escape sequence. */ val = -1; switch (*++end) { case 'd': /* delay */ xsleep(1); break; case 'p': /* pause */ xusleep(100000); break; case 'l': /* lower DTR */ ioctl(fd, TIOCMGET, &flags); flags &= ~TIOCM_DTR; ioctl(fd, TIOCMSET, &flags); xsleep(1); flags |= TIOCM_DTR; ioctl(fd, TIOCMSET, &flags); break; case 'c': /* Don't add CR */ addcr = false; break; case 'K': /* Send a break */ tcsendbreak(fd, 0); break; default: /* Just fill in character. */ val = *end; break; } /* Write character if needed. */ if(val >= 0) { c = val; write(fd, &c, 1); } /* And continue after escape character. */ if (*end) end++; start = end; } } /* * Wait until fd is readable or timeout/error occurs. If fd is readable, try * to read 1 char. */ static int read_char(char *c_ptr, int fd, bool *timed_out) { struct pollfd read_fd; time_t poll_timeout; struct itimerval left; int ret; /* * We don't enclose all poll code in if(GetChatTimeout()) {...}, * because we want to be able to specify infinite timeouts on * non-blocking sockets too. */ if(GetChatTimeout()) { if(timed_out && *timed_out) return (-1); if(getitimer (ITIMER_REAL, &left)) { nsyslog(LOG_DEBUG, "read_char: getitimer: %d(%m)", errno); return -1; } if((! left.it_value.tv_sec) && (! left.it_value.tv_usec)) { nsyslog(LOG_DEBUG, "read_char: timed out outside of poll"); if(timed_out) *timed_out = true; return -1; } poll_timeout = left.it_value.tv_sec*1000+(left.it_value.tv_usec ? 1 : 0); } else { poll_timeout = -1; } read_fd.fd = fd; read_fd.events = POLLIN; read_fd.revents = 0; switch (ret = poll (&read_fd, 1, poll_timeout)) { case -1: nsyslog(LOG_DEBUG, "read_char: poll: %d(%m)", errno); return -1; case 0: if(GetChatTimeout()) { nsyslog(LOG_DEBUG, "read_char: timed out in poll"); if(timed_out) *timed_out = true; } else { nsyslog(LOG_DEBUG, "read_char: bad thing" "happened: timed out in poll after" "infinite timeout had been specified"); } return -1; case 1: break; default: nsyslog(LOG_DEBUG, "read_char: poll returned: %d", ret); return -1; } if((read_fd.revents & POLLIN) == 0) { nsyslog(LOG_DEBUG, "read_char: bad poll mask: %d", read_fd.revents); return -1; } switch (ret = read (fd, c_ptr, 1)) { case -1: nsyslog(LOG_DEBUG, "read_char: read: %d(%m)", errno); return -1; case 1: break; default: nsyslog(LOG_DEBUG, "read_char: read %d chars", ret); return -1; } return 0; } struct abort { char *str; int len; }; #define MAX_ABORT 16 static struct abort abort_arr[MAX_ABORT]; static const char *check_abort(const char *str, int len) { int i; for(i = 0; i < MAX_ABORT && abort_arr[i].str; i++) { if(abort_arr[i].len < len) { const char *tmp_str = str + len - 1 - abort_arr[i].len; if(!strncmp(tmp_str, abort_arr[i].str, abort_arr[i].len)) return abort_arr[i].str; } } return NULL; } /* * Add an abort string to the list. A string of "CLEAN" will remove all * entries. */ static void special_chat_abort(const char *str) { int i; if(!strcmp(str, "CLEAN")) { for(i = 0; i < MAX_ABORT; i++) { if(abort_arr[i].str) free(abort_arr[i].str); memset(&abort_arr[i], 0, sizeof(struct abort)); } nsyslog(LOG_DEBUG, "Cleaned abort list."); return; } for(i = 0; i < MAX_ABORT; i++) { if(abort_arr[i].str == NULL) { abort_arr[i].str = xstrdup(str); abort_arr[i].len = strlen(str); nsyslog(LOG_DEBUG, "Added abort string \"%s\" at %d.", str, i); return; } } nsyslog(LOG_ERR, "No space for abort string \"%s\"", str); } typedef enum { eAssign = '?', eOverRule = '=', eAppend = '+' } VAR_TYPE; struct setvar { char *str; int len; char *var_buf; int var_len; VAR_TYPE type; }; #define MAX_SETSTR 16 static struct setvar setvar_arr[MAX_ABORT]; static unsigned int abort_setvar_max_len() { unsigned int len = 0; int i; for(i = 0; i < MAX_ABORT && abort_arr[i].str; i++) len = MAX(len, strlen(abort_arr[i].str)); for(i = 0; i < MAX_SETSTR && setvar_arr[i].str; i++) len = MAX(len, strlen(setvar_arr[i].str)); return len + 1; } static void check_setvar(const char *str, int str_len, int fd) { int i; for(i = 0; i < MAX_SETSTR && setvar_arr[i].str; i++) { if(setvar_arr[i].len < str_len) { const char *tmp_str = str + str_len - 1 - setvar_arr[i].len; if(!strncmp(tmp_str, setvar_arr[i].str, setvar_arr[i].len)) { int len = 0; bool start = true; char c; if(setvar_arr[i].var_buf[0] && setvar_arr[i].type == eAssign) { nsyslog(LOG_DEBUG , "Match on setvar string \"%s\", but already set to \"%s\"." , setvar_arr[i].str, setvar_arr[i].var_buf); return; } nsyslog(LOG_DEBUG, "Match on setvar string \"%s\".", setvar_arr[i].str); if(setvar_arr[i].type == eAppend) len = strlen(setvar_arr[i].var_buf); while(1) { if(read_char(&c, fd, NULL)) break; if(start && c == ' ') continue; start = false; if(c == '\r' || c == '\n') break; if(len < setvar_arr[i].var_len - 1) setvar_arr[i].var_buf[len++] = c; } setvar_arr[i].var_buf[len] = '\0'; } } } } /* macro to set the variable for the setvar operation */ #define SET_VAR_BUF(XX) \ { \ setvar_arr[i].var_buf = ai->XX; \ setvar_arr[i].var_len = sizeof(ai->XX); \ } /* * Add a setvar string to the list. A string of "CLEAN" will remove all * entries. */ static void special_chat_setvar(const char *str, struct auth *ai) { int i; if(!strcmp(str, "CLEAN")) { for(i = 0; i < MAX_SETSTR; i++) { if(setvar_arr[i].str) free(setvar_arr[i].str); memset(&setvar_arr[i], 0, sizeof(struct setvar)); } nsyslog(LOG_DEBUG, "Cleaned setvar list."); return; } if((str[1] != eAssign && str[1] != eOverRule && str[1] != eAppend) || !str[2]) { nsyslog(LOG_ERR, "Setvar string \"%s\" unparsable.", str); return; } for(i = 0; i < MAX_ABORT; i++) { if(setvar_arr[i].str == NULL) { switch(str[0]) { case 'C': SET_VAR_BUF(conn_info); break; case 'S': SET_VAR_BUF(cli_src); break; case 'D': SET_VAR_BUF(cli_dst); break; default: nsyslog(LOG_ERR, "Setvar string \"%s\" unparsable.", str); return; } setvar_arr[i].str = xstrdup(str + 2); setvar_arr[i].len = strlen(setvar_arr[i].str); setvar_arr[i].type = str[1]; nsyslog(LOG_DEBUG, "Added setvar string \"%s\" at %d.", setvar_arr[i].str, i); return; } } nsyslog(LOG_ERR, "No space for setvar string \"%s\"", str); } /* * Expect a string. */ static CHAT_ERR real_chat_expect(int fd, char *buf, unsigned int buf_len , const char *expect) { /* buf: buffer for storing last buf_len - 2 bytes of data read, it is * checked for a match with expect after every byte. * timed_out: whether a timeout has occurred * expect: the string we look for * */ unsigned int expect_len; char c; int retries = 0; bool timed_out = false; while(1) { nsyslog(LOG_DEBUG, "chat_expect(%s, %d)", expect, GetChatTimeout()); expect_len = strlen(expect); if(expect_len > buf_len - 1) expect_len = buf_len - 1; /* Empty expects always succeed. */ if(*expect == 0) { nsyslog(LOG_DEBUG, "chat_expect - got it"); return eNoErr; } /* Wait for string to arrive, or timeout. */ if(GetChatTimeout()) { signal (SIGALRM, SIG_IGN); timed_out = false; alarm(GetChatTimeout()); } memset(buf, 0, buf_len); /* Put every char in a buffer and shift. */ while(1) { if(read_char(&c, fd, &timed_out)) { if(timed_out) break; nsyslog(LOG_DEBUG, "chat_expect (%s) - got (%s) with error", expect, (buf + buf_len - 1 - expect_len)); if(retries++ >= 3) break; continue; } /* Insert character at the end of the string (buf_len - 2, buf_len - 1 is '\0') * and move everything left. */ memmove(buf, buf + 1, buf_len - 2); buf[buf_len - 2] = c; /* first see if we got a setvar string */ check_setvar(buf, buf_len, fd); /* See if we got it. */ if(strncmp(expect, buf + buf_len - 1 - expect_len, expect_len) == 0) { nsyslog(LOG_DEBUG, "chat_expect - got it"); return eNoErr; } else { const char *abort_msg = check_abort(buf, buf_len); if(abort_msg) { nsyslog(LOG_ERR, "initchat failed, ABORT \"%s\".", abort_msg); return eAbort; } } } /* end while */ if(!timed_out) { nsyslog(LOG_DEBUG, "chat_expect(%s): interrupted", expect); return eInterrupt; } nsyslog(LOG_DEBUG, "chat_expect(%s): timeout (retry)", expect); return eTimeOut; } /*NOTREACHED*/ return eNoErr; } static char *sub_expect_tok(char *buf, const char *end) { char *str = buf; if(buf > end) return NULL; while(str < end && *str) { if(*str == '\\' && *(str + 1)) { str += 2; } else { if(*str == '-') *str = '\0'; else str++; } } return buf; } /* buf: temporary buffer for real_chat_expect() to use, it's easier to clean * up memory in one place here than in multiple places in real_chat_expect * str: the string passed to real_chat_expect() */ static CHAT_ERR chat_expect(int fd, const char *expect) { char *buf; char *str = xstrdup(expect); char *end = str + strlen(str); char *exp_tmp; CHAT_ERR rc; unsigned int buf_len; tstr(str, false, str); buf_len = MAX((strlen(expect) + 1), abort_setvar_max_len()); buf = xmalloc(buf_len); exp_tmp = sub_expect_tok(str, end); rc = real_chat_expect(fd, buf, buf_len, exp_tmp); if(rc == eTimeOut) { exp_tmp = sub_expect_tok(exp_tmp + strlen(exp_tmp) + 1, end); if(exp_tmp) { chat_send(fd, exp_tmp); exp_tmp = sub_expect_tok(exp_tmp + strlen(exp_tmp) + 1, end); if(exp_tmp) rc = real_chat_expect(fd, buf, buf_len, exp_tmp); } } free(str); free(buf); alarm(0); return rc; } /* * Return its index in sw array of special chat word or -1 if not special */ static int get_special_index(const char *word) { int i; for(i = 0; sw[i].word; ++i) { if (!strcmp(word, sw[i].word)) return i; } return -1; } /* * Given a string, converts it to integer and sets chat timeout */ static int set_chat_timeout(const char *str) { char *end_conv; long int val; val = strtol(str, &end_conv, 10); if(*end_conv != 0) { nsyslog (LOG_DEBUG, "set_chat_timeout: bad integer %s", str); return -1; } if(val < 0) { nsyslog (LOG_DEBUG, "set_chat_timeout: negative timeout %ld", val); return -1; } SetChatTimeout((int)val); return 0; } /* * Implements special chat keyword "WAIT" */ static int special_chat_wait(const char *str) { struct itimerval left; int TIO_flags; if(strcmp (str, "DCD")) { nsyslog (LOG_DEBUG, "special_chat_wait: bad wait parameter: %s", str); return (-1); } if(GetChatTimeout() == 0) { if(ioctl(0, TIOCMIWAIT, TIOCM_CD) == -1) { nsyslog(LOG_DEBUG, "special_chat_wait: ioctl" "(0, TIOCMIWAIT, TIOCM_CD): %d(%m)", errno); return (-1); } } else { signal (SIGALRM, SIG_IGN); alarm(GetChatTimeout()); while(1) { if(getitimer(ITIMER_REAL, &left)) { nsyslog(LOG_DEBUG, "special_chat_wait: getitimer: %d(%m)", errno); alarm(0); return -1; } if(ioctl(0, TIOCMGET, &TIO_flags)) { nsyslog (LOG_DEBUG, "special_chat_wait:" "ioctl(0, TIOCMGET, ...): %d(%m)", errno); alarm(0); return -1; } if(TIO_flags & TIOCM_CAR) break; if((left.it_value.tv_sec == 0) && (left.it_value.tv_usec == 0)) { nsyslog(LOG_DEBUG, "special_chat_wait: timed out"); return -1; } xsleep(1); } } nsyslog(LOG_DEBUG, "Carrier detected"); alarm(0); return 0; } /* * This is the main chat loop; * you have to feed it with an argument * vector and a count. */ static int chatarray(int fd, int argc, const char * const * const argv, struct auth *ai) { /* ind: the special chat index, val is SPECIAL_NONE(-1), SPECIAL_TIMEOUT, * SPECIAL_WAIT, SPECIAL_STATUS, or SPECIAL_ABORT. * c: the index to the argv[] array */ int c; int ind; nsyslog(LOG_DEBUG, "chatarray: %d words", argc); special_chat_abort("CLEAN"); special_chat_setvar("CLEAN", NULL); /* * Now do alternative expect-sends. Before each expect check if current * expect string is a special word. */ for(c = 0; c != argc; ) { ind = get_special_index(argv[c]); if(ind == -1) { CHAT_ERR rc; rc = chat_expect(fd, argv[c++]); if(rc != eNoErr) return rc; if(c == argc) break; chat_send(fd, argv[c++]); } else { nsyslog(LOG_DEBUG, "chatarray: special word: %s, " "index: %d, code: %d, req. words: %d", sw[ind].word, ind, sw[ind].code, sw[ind].req_words); if((argc - c) < sw[ind].req_words) { nsyslog(LOG_DEBUG, "Special chat word %s is missing parameter(s)", argv[c]); return -1; } switch (ind) { case SPECIAL_TIMEOUT: if(set_chat_timeout(argv[c+1])) return -1; break; case SPECIAL_WAIT: if(special_chat_wait(argv[c+1])) return -1; break; case SPECIAL_STATUS: update_utmp(argv[c+1], argv[c+2], ai, 0); break; case SPECIAL_ABORT: special_chat_abort(argv[c+1]); break; case SPECIAL_SETVAR: special_chat_setvar(argv[c+1], ai); break; default: break; } c += sw[ind].req_words; } } return 0; } /* * This is a generic chat; you can * just pass a string to it. * The string will be split into send/expect pairs, if it becomes more * than NUM_ARGS-2 parts then the rest will be ignored. */ #define NUM_ARGS 128 CHAT_ERR chat(int fd, const char *str, struct auth *ai) { /* args: pointers to an array of expect/send strings for the chat * s: copy of the input string str that is split and has args[] point to it * i: index to args[] * rc: return code from the real work */ const char *args[NUM_ARGS]; char *strbuf; char *strptr; int i = 0; CHAT_ERR rc; memset(args, 0, sizeof(args)); if(str == NULL || str[0] == '\0') return eNoErr; strbuf = xstrdup(str); strptr = strbuf; /* Split string up in expect-send pairs. */ while(*strptr && (i + 1) < NUM_ARGS) { if(*strptr == ' ' || *strptr == '\t' || i == 0) { if(i) { /* End of a string. */ *strptr++ = '\0'; } /* Skip until next non-space. */ while(*strptr == ' ' || *strptr == '\t') strptr++; if(*strptr == '\0') continue; args[i++] = strptr; } if(*strptr == '"') { if(strptr != args[i - 1]) { nsyslog(LOG_ERR, "Quote not at begin of string in chat."); return eStupidAdmin; } args[i - 1]++; /* Don't include the quote in the string */ strptr++; while(*strptr && *strptr != '"') { if(*strptr == '\\' && *(strptr+1)) strptr++; strptr++; } if(*strptr != '"') { nsyslog(LOG_ERR, "Unterminated quote in chat."); return eStupidAdmin; } *strptr = '\0'; strptr++; } else { if(*strptr) strptr++; } } args[i] = NULL; /* Now call the real routine. */ rc = chatarray(fd, i, args, ai); free(strbuf); return rc; } portslave-2010.04.19.1/src/rot_getty.c0000664000000000000000000001660307411462147014145 0ustar /* * getty.c This is the part that talks with the modem, * does the login stuff etc. * * Version: @(#)getty.c 1.34 13-Jan-1998 MvS. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "server.h" int tc_getattr(int fd, struct termios *termios_p) { if(tcgetattr(fd, termios_p)) { nsyslog(LOG_ERR, "Can't get serial attributes:%m"); return -1; } return 0; } int tc_setattr(int fd, int optional_actions, struct termios *termios_p) { if(tcsetattr(fd, optional_actions, termios_p)) { nsyslog(LOG_ERR, "Can't set serial attributes:%m"); return -1; } return 0; } /* * Reset the terminal to a reasonably sane state. */ void maketermsane() { struct termios tty; tcflush(0, TCIFLUSH); tcflush(1, TCOFLUSH); tcflush(2, TCOFLUSH); if(tc_getattr(0, &tty)) return; tty.c_iflag &= ~IGNCR; tty.c_oflag |= OPOST|ONLCR; tty.c_lflag |= ISIG|IEXTEN|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE; tc_setattr(0, TCSANOW, &tty); } /* * Get the lockfile. */ int lockfile(char **lock_name, const char *lockdir, const char *tty , LOCATION location) { struct stat st; char *p; /* tmp variable for parsing */ char buf[MAXPATHLEN + 1]; /* * First some checks to see if we do want to * use a lockdir and if it exists. */ if(lockdir == NULL || lockdir[0] != '/') { *lock_name = NULL; return -1; } if(stat(lockdir, &st) < 0 || !S_ISDIR(st.st_mode)) { *lock_name = NULL; return -1; } if((p = strrchr(tty, '/')) != NULL) tty = p + 1; if(snprintf(buf, MAXPATHLEN, "%s/%s..%s" , lockdir, (location == eLocBuf ? "BUF" : "LCK"), tty) == -1) { *lock_name = NULL; return (-1); } *lock_name = xstrdup(buf); return 0; } /* * See if a device is locked. */ int islocked(const char *lock_name) { FILE *fp; int pid; if(!*lock_name) return 0; if((fp = fopen(lock_name, "r")) == NULL) return 0; if(fscanf(fp, "%d", &pid) != 1 || (kill(pid, 0) < 0 && errno == ESRCH)) { fclose(fp); if(unlink(lock_name)) { nsyslog(LOG_CRIT, "Can't remove stale lockfile \"%s\".", lock_name); xsleep(30); } return 0; } fclose(fp); return pid; } /* * Create a lockfile. * Returns: -1 some error * 0 success * 1 already locked. */ int dolock(const char *lock_name) { char tmp[MAXPATHLEN+1]; FILE *fp; int i; if (!*lock_name) return 0; snprintf(tmp, sizeof (tmp), "%s.%d", lock_name, getpid ()); unlink(tmp); /* * Already locked? */ if(islocked(lock_name)) return 1; /* * Try to lock. */ if((fp = fopen(tmp, "w")) == NULL) { nsyslog(LOG_ERR, "%s: %m", tmp); return -1; } fprintf(fp, "%10d portslave root\n", getpid()); fclose(fp); for(i = 0; i < 5; i++) { if(i > 0) xsleep(5); islocked(lock_name); /* removes the file if no process */ if(link(tmp, lock_name) == 0) break; } unlink(tmp); return (i == 5) ? 1 : 0; } /* repeatedly try to create a lock, wait sleep_time seconds between attempts */ void dolock_and_wait(int sleep_time) { while(dolock(lineconf.lockfile) == 1) { while(islocked(lineconf.lockfile)) xsleep(sleep_time); } } #ifdef CYCLADES static char *term_in_use(LOCATION location) { if(!lineconf.lockfile) lockfile(&lineconf.lockfile, lineconf.lockdir, lineconf.tty, location); #ifndef CYCLADES dolock_and_wait(10); #else if(dolock(lineconf.lockfile) == 1 && islocked(lineconf.lockfile)) { snprintf(buf, sizeof(buf), "\r\n*\r\n* * * %s is being used !!!\r\n*\r\n", lc->tty); return(buf); } #endif return (NULL); } #endif /* * Close the serial line */ void serial_close() { maketermsane(); close(0); close(1); close(2); } /* * Open the serial line and put it into raw/no echo mode. */ int serial_open(LOCATION location) { int fd, fl; struct termios tio, old; char *tty = lineconf.tty; tcflag_t PDataSize; speed_t Speed; int MLines; if(tty == NULL || tty[0] == 0) { nsyslog(LOG_ERR, "no tty specified"); return -1; } if(tty[0] != '/') { nsyslog(LOG_ERR, "Coding error, tty should be canonical"); exit(1); } if((fd = open(tty, O_RDWR|O_NONBLOCK|O_NOCTTY)) < 0) { nsyslog(LOG_ERR, "%s: %m", tty); return -1; } if(location == eLocModem) { /* Toggle DTR in case of modem hang */ if(tc_getattr(fd, &tio) || tc_getattr(fd, &old) ) return -1; cfsetospeed(&tio, B0); cfsetispeed(&tio, B0); if(tc_setattr(fd, TCSANOW, &tio)) return -1; xusleep(500000); if(tc_setattr(fd, TCSANOW, &old)) return -1; /* REALLY Make sure, toggle it again */ if(tc_setattr(fd, TCSANOW, &tio)) return -1; xusleep(500000); if(tc_setattr(fd, TCSANOW, &old)) return -1; fl = fcntl(fd, F_GETFL, 0); fl &= ~O_NONBLOCK; fcntl(fd, F_SETFL, fl); xusleep(500000); if(tc_setattr(fd, TCSANOW, &old)) return -1; } ioctl(fd,TIOCMGET,&MLines); MLines = MLines | TIOCM_DTR; ioctl(fd,TIOCMSET,&MLines); if(tc_getattr(fd, &tio)) return -1; tio.c_iflag = IGNPAR|ICRNL|IGNBRK; tio.c_oflag = OPOST|ONLCR; tio.c_lflag = 0; /* ICANON|ECHO|ECHONL*/ if(location != eLocModem) tio.c_cflag = CREAD|CS8; else tio.c_cflag = CREAD|CS8|HUPCL; if(location == eLocBuf) tio.c_cflag |= CLOCAL; else if(!lineconf.dcd) tio.c_cflag |= CLOCAL; switch (lineconf.flow) { case FLOW_NONE: break; case FLOW_HARD: tio.c_cflag |= CRTSCTS; break; case FLOW_SOFT: tio.c_iflag |= IXON|IXOFF; tio.c_cc[VSTART] = 17; tio.c_cc[VSTOP] = 19; break; } switch(lineconf.speed) { case 1200: Speed = B1200; break; case 2400: Speed = B2400; break; case 4800: Speed = B4800; break; case 9600: Speed = B9600; break; case 19200: Speed = B19200; break; case 38400: Speed = B38400; break; case 57600: Speed = B57600; break; case 115200: Speed = B115200; break; case 230400: Speed = B230400; break; case 460800: Speed = B460800; break; case 921600: Speed = B921600; break; default: nsyslog(LOG_WARNING, "%d: line speed not supported (using 9600)", lineconf.speed); Speed = B9600; break; } switch(lineconf.stopbits) { case 2: tio.c_cflag = tio.c_cflag | CSTOPB; break; case 1: default: /* there is no support to 1.5 stop bits defaults to 1 */ tio.c_cflag = tio.c_cflag & ~CSTOPB; break; } switch(lineconf.parity) { case 2: tio.c_cflag = tio.c_cflag | PARENB | PARODD; break; case 3: tio.c_cflag = (tio.c_cflag | PARENB) & ~PARODD; break; case 1: default: /* There's no support for MARK/SPACE parity so sets no parity */ tio.c_cflag = tio.c_cflag & ~PARENB; break; } switch(lineconf.datasize) { case 5: PDataSize = CS5; break; case 6: PDataSize = CS6; break; case 7: PDataSize = CS7; break; case 8: default: PDataSize = CS8; break; } tio.c_cflag = tio.c_cflag & ((tio.c_cflag & ~CSIZE) | PDataSize); /* Setting speed above 38400 correctly */ cfsetospeed(&tio, Speed); cfsetispeed(&tio, Speed); for(fl=0; fl < 3 && tcsetattr(fd, TCSANOW, &tio) != 0; fl++) { if(fl == 2) { nsyslog(LOG_ERR, "tcsetattr %s: %m", tty); return -1; } xsleep(1); } if(lineconf.protocol != P_SOCKET_SERVER && lineconf.protocol != P_SOCKET_SSH) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if(fd > 2) { close(fd); fd = 0; } } tcflush(fd, TCIOFLUSH); return fd; } portslave-2010.04.19.1/src/lib.c0000664000000000000000000003515507550422457012702 0ustar /* * lib.c Generic functions. * * Version: @(#)lib.c 1.36 13-Jan-1998 miquels@cistron.nl * */ #include "server.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int thisport = -1; /* port number */ static int chat_timeout; /* Chat timeout, in seconds */ static int chat_send_delay; /* Send delay, in 10th seconds */ /* GetPortNo should be used by the rest of the code to get the * "current" port number. ONLY main.c should call SetPortNo(). */ int GetPortNo() { return thisport; /* declared static above */ } void SetPortNo(int num) { thisport = num; } int GetChatTimeout() { return chat_timeout; /* again, static to lib.c */ } void SetChatTimeout(int num) { chat_timeout = num; } int GetChatSendDelay() { return chat_send_delay; /* You guessed it */ } void SetChatSendDelay(int num) { chat_send_delay = num; } /* * Malloc and die if failed. */ void *xmalloc(int size) { void *p; if((p = malloc(size)) == NULL) { nsyslog(LOG_ERR, "Virtual memory exhausted.\n"); exit(1); } memset(p, 0, size); return p; } /* * Realloc and die if failed. */ void *xrealloc(void *ptr, int size) { void *p; if((p = realloc(ptr, size)) == NULL) { nsyslog(LOG_ERR, "Virtual memory exhausted.\n"); exit(1); } return p; } void xsleep(unsigned int seconds) { struct timespec ts; ts.tv_nsec = 0; ts.tv_sec = seconds; nanosleep(&ts, NULL); } void xusleep(unsigned long usec) { struct timespec ts; ts.tv_nsec = usec * 1000; ts.tv_sec = 0; nanosleep(&ts, NULL); } /* * Strdup and die if failed. */ char *xstrdup(const char *str) { char *p; if((p = strdup(str)) == NULL) { nsyslog(LOG_ERR, "Virtual memory exhausted.\n"); exit(1); } return p; } /* * Signal functions. */ void block(int sig) { sigset_t set; sigemptyset(&set); sigaddset(&set, sig); sigprocmask(SIG_BLOCK, &set, NULL); } void unblock(int sig) { sigset_t set; sigemptyset(&set); sigaddset(&set, sig); sigprocmask(SIG_UNBLOCK, &set, NULL); } /* Check for the existance of a device node and return the absolute name * returned by dereferencing all sym-links. */ char *check_device(const char *file) { char *real_name; if(file[0] != '/') { char *str = xmalloc(strlen(file) + 6); strcpy(str, "/dev/"); strcat(str, file); real_name = canonicalize_file_name(str); free(str); } else real_name = canonicalize_file_name(file); return real_name; } /* * Print number in static buffer (itoa). */ char *static_num(int i) { static char buf[16]; snprintf(buf, sizeof (buf), "%d", i); return buf; } /* * Print dotted IP address. */ const char *dotted(unsigned int ipno) { struct in_addr ia; ia.s_addr = ipno; return inet_ntoa(ia); } in_port_t *get_port_ptr(struct sockaddr *sa) { #ifdef HAVE_IPV6 if(sa->sa_family == AF_INET6) return &((struct sockaddr_in6 *)sa)->sin6_port; #endif return &((struct sockaddr_in *)sa)->sin_port; } static const void *get_addr_ptr(const struct sockaddr *sa) { #ifdef HAVE_IPV6 if(sa->sa_family == AF_INET6) return &((struct sockaddr_in6 *)sa)->sin6_addr; #endif return &((struct sockaddr_in *)sa)->sin_addr; } const char *dotted_sa(const struct sockaddr *sa, bool port) { #ifdef HAVE_IPV6 static char buf[INET6_ADDRSTRLEN + 8]; #else static char buf[INET_ADDRSTRLEN + 8]; #endif char *ptr = buf; if(port) { *ptr = '['; ptr++; } if(!inet_ntop(sa->sa_family, get_addr_ptr(sa), ptr, sizeof(buf) - 2)) { return "address error"; } if(!port) return buf; ptr += strlen(ptr); snprintf(ptr, sizeof(buf) - (ptr - buf), "]%d", ntohs(*get_port_ptr((struct sockaddr *)sa)) ); buf[sizeof(buf) - 1] = '\0'; return buf; } int sa_len(const struct sockaddr *sa) { #ifdef HAVE_IPV6 if(sa->sa_family == AF_INET6) return sizeof(struct sockaddr_in6); #endif return sizeof(struct sockaddr_in); } /* * Strips login name and writes it to buffer. */ static void strip_login(char *buffer, int buf_size, const char *login) { char *ptr; if(strchr("PCS!L", login [0])) { snprintf (buffer, buf_size, "%s", login+1); } else { snprintf (buffer, buf_size, "%s", login); ptr = strrchr (buffer, '.'); if(ptr) { if(!strcmp(ptr, ".slip") || !strcmp(ptr, ".cslip") || !strcmp(ptr, ".ppp") ) *ptr = 0; } } } int get_sessiontime(const struct auth *ai) { int limit; if(!lineconf.login_time_limited) return ai->sessiontime; limit = chktimes() * 60; if(!ai->sessiontime || limit > ai->sessiontime) return limit; return ai->sessiontime; } /* * * Expands a format string * * %l: login name * %L: stripped login name * %p: NAS port number * %P: protocol * %b: port speed * %H: host for telnet/ssh connections * %i: local IP * %j: remote IP * %1: first byte (MSB) of remote IP * %2: second byte of remote IP * %3: third byte of remote IP * %4: fourth (LSB) byte of remote IP * %c: connect-info * %m: netmask * %M: "multilink" if the RADIUS server has PW_NAS_PORT_LIMIT set to > 1 * %t: MTU * %r: MRU * %I: idle timeout * %T: session timeout * %h: hostname * %g: PID * %S: session timeout (other versions of Portslave implement this). * %d: DCD setting, "modem" if dcd is true, "local" if false. * %%: % * * Everything else is copied unchanged. * */ void expand_format(char *buffer, size_t size, const char *format, const struct auth *ai) { char ch; int done; char str [256]; unsigned long int byte_val; if(size-- == 0) return; while(size) { if((ch = *format++) == '%') { switch (*format) { case 'l': snprintf (str, sizeof(str), "%s", ai->login); break; case 'L': strip_login (str, sizeof (str), ai->login); break; case 'p': snprintf (str, sizeof(str), "%03d", ai->nasport); break; case 'P': snprintf (str, sizeof(str), "%c", (char) ai->proto); break; case 'b': snprintf (str, sizeof(str), "%d", lineconf.speed); break; case 'H': if(ai->host) snprintf (str, sizeof(str), "%s", dotted(ai->host)); break; case 'i': snprintf(str, sizeof(str), "%s", dotted(lineconf.loc_host)); break; case 'j': snprintf (str, sizeof(str), "%s", dotted(ai->address)); break; case '1': byte_val = (ntohl (ai->address) >> (3*BITSPERBYTE)) & 0xFF; snprintf (str, sizeof(str), "%ld", byte_val); break; case '2': byte_val = (ntohl (ai->address) >> (2*BITSPERBYTE)) & 0xFF; snprintf (str, sizeof(str), "%ld", byte_val); break; case '3': byte_val = (ntohl (ai->address) >> BITSPERBYTE) & 0xFF; snprintf (str, sizeof(str), "%ld", byte_val); break; case '4': byte_val = ntohl (ai->address) & 0xFF; snprintf (str, sizeof(str), "%ld", byte_val); break; case 'c': snprintf (str, sizeof(str), "%s", ai->conn_info); break; case 'm': snprintf (str, sizeof(str), "%s", dotted(ai->netmask)); break; case 'M': snprintf (str, sizeof(str), "%s", (ai->port_limit > 1) ? "multilink" : ""); break; case 't': snprintf (str, sizeof(str), "%d", ai->mtu); break; case 'r': snprintf (str, sizeof(str), "%d", ai->mru); break; case 'I': snprintf (str, sizeof(str), "%d", ai->idletime); break; case 'S': case 'T': snprintf (str, sizeof(str), "%d", get_sessiontime(ai)); break; case 'h': snprintf(str, sizeof(str), "%s", lineconf.hostname); break; case 'g': snprintf(str, sizeof(str), "%d", getpid()); break; case 'd': snprintf(str, sizeof(str), "%s", lineconf.dcd ? "modem" : "local"); break; case '%': snprintf (str, sizeof(str), "%c", '%'); break; default: *buffer++ = '?'; --size; continue; } ++format; if((done = snprintf (buffer, size+1, "%s", str)) == -1) return; buffer += done; size -= done; } else { if((*buffer = ch) == '\0') return; ++buffer; --size; } } *buffer = '\0'; } #ifdef PORTSLAVE_CLIENT_IP_RULES /* * Convert the valid ip string into the list of rules. * * Multiple rules may reside in the string, separated by commas. * * NOTES: * * - The previous contents of the auth structure for IP rules will be * ignored and lost. */ static void conv_ip_rules(struct auth *ai, const char *rule_str) { int num_rule; int cur; const char *ptr; const char *start; /* If the rule string is empty, just return now. */ if(rule_str == NULL || rule_str[0] == '\0') return; /* Count the number of rules in order to size the array. */ num_rule = 1; ptr = rule_str; while(ptr != NULL) { ptr = strchr(ptr, ','); if(ptr != NULL) { num_rule++; ptr++; } } /* Allocate the memory for the list of strings. */ ai->valid_ip_rules = xmalloc(sizeof (char *) * num_rule); ai->num_ip_rules = num_rule; /* Save each rule */ ptr = rule_str; start = rule_str; cur = 0; /* Loop until the last rule is copied. Check the size */ /* of the array for robustness; this should not be */ /* necessary. */ while(ptr != NULL && cur < num_rule) { char *one_rule; ptr = strchr(start, ','); /* If the end of the string was found, just save the */ /* string from the last saved point; otherwise, */ /* save only the string up to the comma. */ if(ptr == NULL) { one_rule = xstrdup(start); } else { /* Check for the empty string. */ if(ptr == start) { one_rule = xmalloc(sizeof (char)); one_rule[0] = '\0'; } else { size_t len; /* Find the length of the string. */ /* Note that ptr is one character */ /* past the end of the string. */ len = ptr - start; one_rule = xmalloc(sizeof (char) * (len + 1)); strncpy(one_rule, start, len); one_rule[len] = '\0'; } start = ptr + 1; } ai->valid_ip_rules[cur] = one_rule; cur++; } } #endif /* * Create a new session id. */ static char *rad_sessionid() { char *id = xmalloc(13); snprintf(id, 13, "%08X%04X", (unsigned int)time(NULL), getpid() & 0xffff); return id; } /* * Fill in the auth struct for now. */ static void fill_auth_struct(struct auth *ai) { memset(ai, 0, sizeof(struct auth)); strcpy(ai->login, "NONE"); /* login is >4 chars long) */ ai->nasport = GetPortNo(); ai->proto = lineconf.protocol; ai->address = lineconf.rem_host; ai->netmask = lineconf.netmask; ai->mtu = lineconf.mtu; ai->mru = lineconf.mru; ai->porttype = lineconf.porttype; ai->localip = lineconf.loc_host; /* first set the Acct-Session-Id to be used for auth and for acct */ ai->acct_session_id = rad_sessionid(); ai->start = time(NULL); if(ai->netmask == 0) ai->netmask = 0xFFFFFFFF; #ifdef PORTSLAVE_CLIENT_IP_RULES conv_ip_rules(ai, lineconf.valid_ip); #endif } /********************************************************************** * %FUNCTION: radius_init * %ARGUMENTS: * msg -- buffer of size BUF_LEN for error message * %RETURNS: * negative on failure; non-negative on success * %DESCRIPTION: * Initializes radiusclient library ***********************************************************************/ static int radius_init() { if(rc_read_config(lineconf.radclient_config_file) != 0) { nsyslog(LOG_ERR, "RADIUS: Can't read config file %s", lineconf.radclient_config_file); return -1; } if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) { nsyslog(LOG_ERR, "RADIUS: Can't read dictionary file %s", rc_conf_str("dictionary")); return -1; } if (rc_read_mapfile(rc_conf_str("mapfile")) != 0) { nsyslog(LOG_ERR, "RADIUS: Can't read map file %s", rc_conf_str("mapfile")); return -1; } return 0; } /* * Initialize struct and read config file. */ int rad_init(const char *config_file, int port, struct auth *ai, const char *tty) { /* * Read the config file. */ initcfg(); SetPortNo(port); if(readcfg(config_file, tty) < 0) return -1; if(GetPortNo() < 0) { nsyslog(LOG_ERR, "\"%s\": not in config file", tty); return -1; } /* * Fill in the auth struct for now. */ fill_auth_struct(ai); if(ai->proto == P_PPP_ONLY) ai->proto = P_AUTOPPP; if(radius_init() != 0) return -1; return GetPortNo(); } /* when access is denied it returns a negative number indicating the amount of time in minutes until a call is permitted. When access is allowed it will return 0 if the call can have unrestricted duration, or a positive number specifying the length of the call in minutes if there is a limit to the length. Currently does not coalesce times. So if today we don't allow calls after 2000 and tomorrow we don't allow them before 0800 then at 2200 it will sleep for 2 hours and then sleep for 8 hours. However if you limit the call time based on the time allowed then it will give the wrong time unless you make sure that every allowed time is part of exactly one range. */ long chktimes() { time_t time_now; struct tm now; int now_hhmm; struct time_ent *te = &lineconf.login_time[0]; int rc = -1440; if(!te || te->days == 0) return 0; /* skip time check if not defined or malformed time definition */ time_now = time(NULL); /* get current time */ now = *(localtime(&time_now)); /* Break it into bits */ now_hhmm = now.tm_hour * 60 + now.tm_min; while(te->days) { if((1 << now.tm_wday) & lineconf.login_time->days) { /* Date within range */ if(now_hhmm >= te->start_time && now_hhmm <= te->end_time) { if(lineconf.login_time_limited) return te->end_time - now_hhmm; return 0; } if(now_hhmm < te->start_time) { int tmp = now_hhmm - te->start_time; if(tmp > rc) rc = tmp; } } te++; } return rc; } portslave-2010.04.19.1/src/ctlportslave.c0000664000000000000000000003544407510762243014653 0ustar /* * ctlportslave.c Command line interface to running portslaves. * Basically this is to accomodate the pmmon * program, but it might have some more uses too. * * Version: ctlportslave 1.01 22-Nov-1997 miquels@cistron.nl * 1.2.0 1999-01-22 dcinege@psychosis.com * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "server.h" #define SESS 1 #define WHO 2 #define DETAIL 3 #define QUIET 10 static int do_show(int argc, const char **argv); static int do_c_show(int argc, const char **argv); static int do_reset(int argc, const char **argv); static int do_quit(/* int argc, const char **argv */); static int do_help(/* int argc, const char **argv */); static int do_help_finger(void); static int read_utmp(void); static char* get_passwd(char* p); struct utmp *lines; int max_port_ever = 0; int port_array_size = 0; const char *eol = "\n"; int finger_prog = false; char fpasswd[256]; char rpasswd[256]; char passwd_in[256]; #ifndef BIGUTMP char eth0_classB[32]; #endif int sock_fd; extern int traffic_stats(int sockfd, struct in_addr ina, int *in, int *out); extern int idle_stat(char *dev); /* * Header for the 2 formats: sessions and who. */ const char * const hdr_sess = "Port User Host/Inet/Dest Type Dir Status Start Idle"; const char * const sep_sess = "---- --------------- ---------------- ------- --- ------------- ------ ------"; #ifdef PRINT_IDLE const char * const idle_sess = "S%-3d - - Log/Net In IDLE 0 0%s"; #endif const char * const hdr_who = "Port User Host/Inet/Dest Type Stat Start In Out Idle"; const char * const sep_who = "---- ------------ --------------- ------- ---- ----- --------- --------- -----"; #ifdef PRINT_IDLE const char * const idle_who = "S%-3d - - - IDLE 0 0 0 0%s%"; #endif const char * const hdr_detail = "Port User Host/Inet/Dest Type Status"; const char * const sep_detail = "---------------------------------------------------------------------------"; #ifdef PRINT_IDLE const char * const idle_detail = "S%-3d - - IDLE%s%s%s"; #endif /* * Commands we support. */ struct commands { const char *cmd; int (*fun)(int, const char **); } commands[] = { { "show", do_show }, { "s", do_show }, { "cshow", do_c_show }, { "c", do_c_show }, { "reset", do_reset }, { "r", do_reset }, { "help", do_help }, { "h", do_help }, { "?", do_help }, { "exit", do_quit }, { "e", do_quit }, { "quit", do_quit }, { "q", do_quit }, { NULL, NULL }, }; /* * Return extended type. */ const char *xtype(char t) { if (t == 'x') return("Network"); if (t == 'E') return("Telnet"); if (t == 'R') return("Rlogin"); if (t == 'L') return("Local"); if (t == 'X') return("Local"); if (t == 'C') return("CSLIP"); if (t == 'S') return("SLIP"); if (t == 'P') return("PPP"); if (t == 'A') return("APPP"); if (t == 'H') return("SSH"); if (t == 'I') return("Logon"); return ("unknown"); } /* * Return address. */ static char *address(struct utmp *ut, struct in_addr *ina) { #ifdef __linux__ ina->s_addr = ut->ut_addr; return(inet_ntoa(*ina)); #else static char buf[256]; char *p; int i = 0; ina->s_addr = 0; # ifndef BIGUTMP if ((p = strchr(ut->ut_host, ':')) == NULL || p[1] == 0) return(""); p++; if (p[0]) p++; snprintf(buf, sizeof (buf), "%s%s", eth0_classB, p + 1); # else p = ut->ut_host + 6; while (*p && *p != ':') { buf[i++] = *p; p++; } buf[i] = '\0'; if (*p == 0) return(""); # endif ina->s_addr = inet_addr(buf); return buf; #endif } static void got_hup(/* int sig */) { } /* * Show logged in users continuously updating. */ static int do_c_show(int argc, const char **argv) { struct sigaction sa, old_sa; struct stat stat_buf; int rc; time_t last; last = time(NULL); rc = do_show(argc, argv); if(rc) return rc; sa.sa_handler = got_hup; sa.sa_flags = SA_ONESHOT; if(sigaction(SIGINT, &sa, &old_sa)) return 1; while(1) { struct timespec req; req.tv_sec = 1; req.tv_nsec = 0; if(nanosleep(&req, NULL)) break; if(stat(_PATH_UTMP, &stat_buf)) break; if(stat_buf.st_mtime > last) { last = time(NULL); rc = do_show(argc, argv); if(rc) break; } } sigaction(SIGINT, &old_sa, NULL); return rc; } /* * Show logged in users. If arg is `sessions', use the * portmaster format. If arg is `who', use our own format. */ static int do_show(int argc, const char **argv) { int style = 0; int i; const char *type = NULL, *p; char name[UT_NAMESIZE]; char show_status[UT_HOSTSIZE]; const char *addr = NULL; struct in_addr ina; time_t now; int tm; int in, out, idle; if(argc > 1) { switch (argv[1][0]) { case 's': style = SESS; break; case 'w': style = WHO; break; case 'd': style = DETAIL; break; default: printf("Error: usage: show sessions,who,detailed\n"); return 1; } } read_utmp(); now = time(NULL); switch(style) { case SESS: printf("%s%s%s%s", hdr_sess, eol, sep_sess, eol); break; case WHO: printf("%s%s%s%s", hdr_who, eol, sep_who, eol); break; case DETAIL: printf("%s%s%s%s", hdr_detail, eol, sep_detail, eol); break; } for(i = 0; i <= max_port_ever; i++) { p = strchr(lines[i].ut_host, ':'); if(p == NULL || lines[i].ut_name[0] == 0) { #ifdef PRINT_IDLE if(!finger_prog) { switch (style) { case SESS: printf(idle_sess, i, eol); break; case WHO: printf(idle_who, i, eol); break; case DETAIL: printf(idle_detail, i, eol, sep_detail, eol); break; } } #endif continue; } strncpy(name, lines[i].ut_name, UT_NAMESIZE); name[UT_NAMESIZE - 1] = 0; tm = (now - lines[i].ut_time) / 60; p++; ina.s_addr = 0; if(strchr("xERSCPLXAI", *p)) { if(strchr("I", *p)) { addr = ""; strncpy(show_status, lines[i].ut_host + 6, UT_HOSTSIZE - 6); show_status[UT_HOSTSIZE - 6] = 0; } else { addr = address(&lines[i], &ina); strncpy(show_status, "ESTABLISHED", UT_HOSTSIZE); show_status[UT_HOSTSIZE - 1] = '\0'; } type = xtype(*p); #ifdef BIGUTMP /* Override with new values */ if (style != WHO) { strncpy(show_status, lines[i].ut_host + strlen(addr) + 7, UT_HOSTSIZE); show_status[UT_HOSTSIZE - 1] = '\0'; } #endif } in = out = idle = 0; if(style >= WHO && ina.s_addr) traffic_stats(sock_fd, ina, &in, &out); idle = idle_stat(lines[i].ut_line); if(idle > 0) idle /= 60; switch (style) { case SESS: printf("S%-3d %-15.15s %-16.16s %-7.7s In %-13.13s %6d %6d%s", i, name, addr, type, show_status, tm, idle, eol); break; case WHO: printf("S%-3d %-12.12s %-15.15s %-7.7s %-4.4s %5d %9d %9d %5d%s", i, name, addr, type, show_status, tm, in, out, idle, eol); break; case DETAIL: printf("S%-3d %-15.15s %-16.16s %-7.7s %-28.28s%s", i, name, addr, type, show_status, eol); printf(" IOT: %10d %10d %7d KB Start:%6d Idle:%5d%s", in, out, (in + out) / 1024, tm, idle, eol); printf("%s%s", sep_detail, eol); break; } } return 0; } /* * Reset a terminal line (send SIGHUP) */ static int do_reset(int argc, const char **argv) { int port; if(argc < 2 || (argv[1][0] != 's' && argv[1][0] != 'S')) { printf("Error: Usage: reset Port_Name\n"); return 0; } port = atoi(argv[1] + 1); read_utmp(); if(lines[port].ut_pid > 0) { printf("Resetting port S%d (line %s, pid %d)\n", port, lines[port].ut_line, lines[port].ut_pid); kill(lines[port].ut_pid, SIGHUP); } else { printf("Port S%d does not appear to be active. Can not reset...\n", port); } return 0; } /* * Exit from this program. */ static int do_quit(/* int argc, const char **argv */) { return -1; } /* * Pretend we're the finger daemon. */ static int do_finger(void) { char buf[256]; char port[16]; const char *args[3] = {NULL, "sessions", NULL}; /* set default style */ char *p; eol = "\r\n"; memset(passwd_in,'\0',sizeof(passwd_in)); fgets(buf, sizeof(buf) / 2, stdin); /* Just paranoid about an overflow. */ switch (buf[0]) { case 'h': do_help_finger(); return 1; case 'r': if (strcmp(rpasswd, "") == 0 ) { printf("Reset access disabled. (no password defined)\n"); break; } p = get_passwd(buf); if(strcmp(rpasswd,passwd_in) != 0) { printf("Permission denied.\n"); break; } memset(port,'\0',sizeof(port)); strncpy(port,++p,3); args[0] = "reset"; args[1] = port; args[2] = NULL; do_reset(2,args); break; case 's': args[1] = "sessions"; goto def; break; case 'w': args[1] = "who"; goto def; break; case 'd': args[1] = "detailed"; goto def; break; default: def: if(strcmp(fpasswd,"") != 0) { get_passwd(buf); if(strcmp(fpasswd,passwd_in) != 0) { printf("Permission denied.\n"); return 1; } } args[0] = "show"; args[2] = NULL; do_show(2, args); break; } return 0; } static char* get_passwd(char *p) { int len = 0, i = 0; while(*p >= Fascii && *p <= Lascii) { /* strlen up to non-escape chars */ p++; len++; } if (len <= 2) goto bad_usage; p -= len; while((*++p != ':') && (--len > 0)); if(len <= 1) goto bad_usage; p++; len--; while(*p != ':' && len > 1) { passwd_in[i++] = *p++; len--; } return (p); bad_usage: printf("Permission denied.\n"); exit(1); } /* * Short help text. */ static int do_help(/* int argc, const char **argv */) { printf("\nCtlportslave v%s help:\n\n", PORTSLAVE_VERSION); printf(" show \n"); printf(" cshow \n"); printf(" reset Sxx\n"); printf(" exit\n"); printf(" quit\n\n"); return 0; } static int do_help_finger(void) { printf("\nCtlportslave v%s as finger help:\n\n", PORTSLAVE_VERSION); printf(" [:password]@ show active ports\n"); printf(" reset:password:Sxx@ reset port Sxx\n"); return 0; } /* * Decipher portslave port from ut_host. */ static int ps_port(char *data) { if(isdigit(data[0]) && isdigit(data[1]) && isdigit(data[2]) && data[3] == ':') return (atoi(data)); return -1; } /* * Read the portslave UTMP file.. */ static int read_utmp(void) { struct utmp *ut; int port; setutent(); if(port_array_size) { memset(lines, 0, sizeof(struct utmp) * port_array_size); } else { port_array_size = 16; lines = xmalloc(sizeof(struct utmp) * port_array_size); } while((ut = getutent()) != NULL) { if((port = ps_port(ut->ut_host)) < 0) continue; if(port > max_port_ever) max_port_ever = port; if(port >= port_array_size) { int new_array_size = port_array_size * 2; struct utmp *new_arr; if(new_array_size <= port) new_array_size = port + 1; new_arr = xmalloc(sizeof(struct utmp) * new_array_size); memcpy(new_arr, lines, sizeof(struct utmp) * port_array_size); free(lines); port_array_size = new_array_size; lines = new_arr; } if(ut->ut_type != LOGIN_PROCESS && ut->ut_type != USER_PROCESS) continue; if(kill(ut->ut_pid, 0)) { if(errno == ESRCH) continue; } lines[port] = *ut; } endutent(); return 0; } int main(int argc, char **argv) { char ps_hostname[128]; char buf[64]; const char *args[16]; char *p=0; int i, n; bool ps_quit = false; #ifndef __linux__ #ifndef BIGUTMP struct ifreq ifr; struct sockaddr_in *sin; #endif #endif while(( i = getopt(argc, argv, "+fp:r:")) != -1) { switch(i) { case 'f': finger_prog = true; break; case 'p': strncpy(fpasswd, optarg, sizeof(fpasswd)); fpasswd[sizeof(fpasswd) - 1] = '\0'; break; case 'r': strncpy(rpasswd, optarg, sizeof(rpasswd)); rpasswd[sizeof(rpasswd) - 1] = '\0'; break; case '?': exit (1); } } /* * See if we we're called as `fingerd'. */ if((strstr(argv[0], "finger")) || finger_prog) { while (argc > 1) { /* Clear displayed command line */ p = argv[--argc]; while (*p) *p++ = '\0'; } finger_prog = true; } /* * Find out our ethernet address. We only need * the first two octets. This is because that's missing * from the information in the utmp file... */ if((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } #ifndef __linux__ #ifndef BIGUTMP memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, "eth0"); ifr.ifr_addr.sa_family = AF_INET; if(ioctl(sock_fd, SIOCGIFADDR, &ifr) < 0) { perror("SIOCGIFADDR(eth0)"); exit(1); } sin = (struct sockaddr_in *)&(ifr.ifr_addr); strcpy(eth0_classB, inet_ntoa(sin->sin_addr)); /*printf("ether is at %s\n", eth0_classB);*/ p = eth0_classB; i = 0; while(*p && i < 2) if (*p++ == '.') i++; *p = 0; #endif #endif if(finger_prog) exit(do_finger()); /* * Do some network/socket initialization. */ gethostname(ps_hostname, sizeof(ps_hostname)); /* * Command Loop. */ while(!ps_quit) { printf("%s> ", ps_hostname); fflush(stdout); if(fgets(buf, sizeof(buf), stdin) == NULL) { printf("\n"); break; } i = 0; p = strtok(buf, " \t\r\n"); while(p && i < 15) { args[i++] = p; p = strtok(NULL, " \t\r\n"); } args[i] = NULL; if (args[0] == NULL) continue; for(n = 0; commands[n].cmd; n++) { if(strcmp(args[0], commands[n].cmd) == 0) { if(commands[n].fun(i, args) < 0) ps_quit = true; break; } } if(commands[n].cmd == NULL) printf("Invalid command.\n"); } printf("Goodbye....\n"); return 0; } /* * Malloc and die if failed. * this is for ctlp-subs */ void *xmalloc(int size) { void *p; if((p = malloc(size)) == NULL) { syslog(LOG_ERR, "Virtual memory exhausted.\n"); exit(1); } memset(p, 0, size); return p; } portslave-2010.04.19.1/src/spawnit.c0000664000000000000000000002433207550422516013610 0ustar /* * spawnit.c Spawn the appropriate protocol. * * Version: @(#)spawnit.c 1.30 24-Oct-1997 MvS. * */ #include "server.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_SPAWN_ARGV 256 extern int traffic_stats(int sockfd, struct in_addr ina, struct traffic_stat *t_stat); /* * Get an utmp entry by process id. * This should be a standard function IMHO. */ static struct utmp *getutpid(struct utmp *in) { struct utmp *u; while((u = getutent()) != NULL) { if(u->ut_type != INIT_PROCESS && u->ut_type != LOGIN_PROCESS && u->ut_type != USER_PROCESS) continue; if(u->ut_pid == in->ut_pid) break; } return u; } /* * Relay the SIGHUP to our process group. */ static void got_hup(int sig) { struct sigaction sa; pid_t pgrp = getpgrp(); signal(sig, SIG_IGN); unblock(sig); if(sig == SIGALRM) alarm(0); if(pgrp > 0) { if(sig == SIGALRM) kill(-pgrp, SIGTERM); else kill(-pgrp, sig); } sa.sa_handler = got_hup; sa.sa_flags = SA_RESTART; sigaction(sig, &sa, NULL); } /* * Execute but split command line args first. */ static int doexec(char *cmd, const char *argv0, char *args) { char *argv[MAX_SPAWN_ARGV]; int argc = 1; int rc; char *s; argv[0] = xstrdup(argv0); s = strtok(args, " \t\n"); while(s && argc < MAX_SPAWN_ARGV - 1) { argv[argc++] = s; s = strtok(NULL, " \t\n"); } argv[argc] = NULL; rc = execv(cmd, argv); free(argv[0]); /* only happens if we can't exec() */ return rc; } /* * Execute a rlogin session. */ static int do_rlogin(const struct auth *ai) { int i = 0; const char *args[10]; args[i++] = "rlogin"; if(ai->login && ai->login[0] && strcmp(ai->login, "NONE")) { args[i++] = "-i"; args[i++] = ai->login; args[i++] = "-l"; args[i++] = ai->login; } args[i++] = "-8"; #ifndef CYCLADES args[i++] = "-E"; #endif args[i++] = dotted(ai->host); args[i] = NULL; maketermsane(); execv(lineconf.rlogin, (char **)args); nsyslog(LOG_ERR, "%s: %m", lineconf.rlogin); return -1; } /* * Execute a telnet session. */ static int do_telnet(const struct auth *ai) { int i = 0; const char *args[10]; args[i++] = "telnet"; args[i++] = "-8"; #ifndef CYCLADES args[i++] = "-E"; #endif if(ai->login && ai->login[0] && strcmp(ai->login, "NONE")) { args[i++] = "-l"; args[i++] = ai->login; } args[i++] = dotted(ai->host); if(ai->loginport) args[i++] = static_num(ai->loginport); else if(lineconf.socket_port) args[i++] = static_num(lineconf.socket_port); args[i] = NULL; maketermsane(); execv(lineconf.telnet, (char **)args); nsyslog(LOG_ERR, "%s: %m", lineconf.telnet); return -1; } /* * Execute a secure shell session. */ static int do_ssh(const struct auth *ai) { int i = 0; const char *args[10]; char *tmp_port = NULL; args[i++] = "ssh"; if(ai->proto != P_SSH1) args[i++] = "-2"; else args[i++] = "-1"; if(ai->login && ai->login[0] && strcmp(ai->login, "NONE")) { args[i++] = "-l"; args[i++] = ai->login; } if(ai->loginport) { args[i++] = "-p"; args[i++] = tmp_port = xstrdup(dotted(ai->loginport)); } args[i++] = dotted(ai->host); args[i] = NULL; maketermsane(); execv(lineconf.ssh, (char **)args); if(tmp_port) free(tmp_port); nsyslog(LOG_ERR, "%s: %m", lineconf.ssh); return -1; } /* * Execute a PPP session. */ static int do_ppp(const struct auth *ai) { char *s; char options [1024]; setenv("PORTSLAVELOGNAME", ai->login, 1); setenv("PORTSLAVE_SESSION", ai->acct_session_id, 1); setenv("PORTSLAVE_START_TIME", static_num(ai->start), 1); setenv("PORTSLAVE_PORT", static_num(GetPortNo()), 1); if(ai->do_acct || lineconf.do_acct) setenv("PORTSLAVE_DO_ACCT", "1", 1); if (ai->conn_info[0]) setenv("CONNECT_INFO", ai->conn_info, 1); s = ai->proto == P_AUTOPPP ? lineconf.autoppp : lineconf.pppopt; expand_format (options, sizeof(options), s, ai); if(setenv_from_rad("PORTSLAVE_FRAMED_ROUTE", (const char **)ai->framed_route, ai->frn)) return -1; if(setenv_from_rad("PORTSLAVE_FILTER", (const char **)ai->filterid, ai->fln)) return -1; if(ai->cli_src[0]) setenv("PORTSLAVE_CLI_SRC", ai->cli_src, 1); if(ai->cli_dst[0]) setenv("PORTSLAVE_CLI_DST", ai->cli_dst, 1); doexec(lineconf.pppd, "pppd", options); nsyslog(LOG_ERR, "%s: %m", lineconf.pppd); return -1; } /* * Execute a local login. */ static int do_local(struct auth *ai, char *id, pid_t parent) { struct utmp ut, *u; char *tty; char lhost[UT_HOSTSIZE]; /* * Prevent hacking. */ if(ai->login[0] == '-') return -1; /* * If we forked we have to pull some tricks to * become process group leader etc. */ if(parent) { setsid(); ioctl(0, TIOCSCTTY, (char *)1); } /* * First fill out an utmp struct. * ttyname() returns a pointer to a static buffer that should not * be free()'d! */ tty = ttyname(0); memset(&ut, 0, sizeof(ut)); if(ai->authenticated) ut.ut_type = USER_PROCESS; else ut.ut_type = LOGIN_PROCESS; ut.ut_pid = getpid(); ut.ut_time = time(NULL); strncpy(ut.ut_line, tty, sizeof(ut.ut_line)); strncpy(ut.ut_user, ai->login, sizeof(ut.ut_user)); strncpy(ut.ut_id, id, sizeof(ut.ut_id)); /* * Now try to find the existing struct.. */ if(parent) ut.ut_pid = parent; if((u = getutpid(&ut)) != NULL) strncpy(ut.ut_id, u->ut_id, sizeof(ut.ut_id)); if(parent) ut.ut_pid = getpid(); setutent(); pututline(&ut); if(ai->address) { const char *p = dotted(ai->address); int i = 0; while(*p && i < 2) { if(*p++ == '.') i++; } snprintf(lhost, sizeof (lhost), "%03d:%c.%s", ai->nasport, ai->proto, p); } else { snprintf(lhost, sizeof (lhost), "%03d:", ai->nasport); } maketermsane(); /* * If we are already authenticated don't ask for a password. */ if(ai->authenticated) execl("/bin/login", "login", "-f", ai->login, "-h", lhost, NULL); else execl("/bin/login", "login", ai->login, "-h", lhost, NULL); nsyslog(LOG_ERR, "/bin/login: %m"); return -1; } static int get_traffic_stats(struct auth *ai) { struct traffic_stat t_stat; int sockfd; struct in_addr spawned_ip; memset(&t_stat, 0, sizeof(t_stat)); if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { nsyslog(LOG_ERR,"socket(sockfd): %m"); return 1; } spawned_ip.s_addr=ai->address; traffic_stats(sockfd, spawned_ip, &t_stat); if(t_stat.recv_bytes) ai->traffic.recv_bytes = t_stat.recv_bytes; if(t_stat.sent_bytes) ai->traffic.sent_bytes = t_stat.sent_bytes; if(t_stat.recv_pkts) ai->traffic.recv_pkts = t_stat.recv_pkts; if(t_stat.sent_pkts) ai->traffic.sent_pkts = t_stat.sent_pkts; return 0; } /* * Spawn an extra process to do the work, if needed. */ int spawnit(struct auth *ai) { pid_t pid; int st; struct sigaction sa; char id[8]; struct utmp ut, *u; int time_limit; /* * Make up an id field if needed. */ snprintf(id, sizeof (id), "T%d", ai->nasport); /* * We only fork if we are going to exec another program * to do the work and we need to send a RADIUS logout * packets afterwards. */ pid = -1; if(ai->proto != P_LOCAL && ai->proto != P_AUTOPPP && ai->proto != P_PPP) { if((pid = fork()) < 0) { nsyslog(LOG_ERR, "fork: %m"); return -1; } if(pid > 0) { /* * Catch SIGHUP. */ sa.sa_handler = got_hup; sa.sa_flags = SA_RESTART; sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); unblock(SIGHUP); unblock(SIGTERM); unblock(SIGINT); time_limit = get_sessiontime(ai); if(time_limit > 0) { alarm(time_limit); sigaction(SIGALRM, &sa, NULL); unblock(SIGALRM); } signal(SIGUSR1, SIG_IGN); /* Ignore stray SIGUSR1 */ /* * Wait for the child to exit. Query traffic stats. */ if(ai->proto == P_SLIP || ai->proto == P_CSLIP) { while(waitpid(pid, &st, WNOHANG) != pid) { xsleep(STATS_SLEEP); get_traffic_stats(ai); errno = 0; } get_traffic_stats(ai); } else { while(waitpid(pid, &st, 0) != pid && errno == EINTR) errno = 0; } /* * Readjust the utmp entry for P_SHELL. */ if(ai->proto == P_SHELL) { setutent(); ut.ut_pid = pid; if((u = getutpid(&ut)) != NULL) { u->ut_pid = getpid(); setutent(); pututline(u); } } return 0; } /* * If a signal was pending, it will be delivered now. */ unblock(SIGHUP); unblock(SIGTERM); unblock(SIGINT); } /* * Set the TERM environment variable. */ if(lineconf.term && lineconf.term[0]) { char aux_speed[16]; setenv("TERM", lineconf.term, 1); sprintf(aux_speed, "%d", lineconf.speed); setenv("TSPEED", aux_speed, 1); } /* * Catch sighup so that we can be killed. */ signal(SIGHUP, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGINT, SIG_DFL); /* * Find the protocol. */ switch(ai->proto) { case P_TCPCLEAR: #if 0 /* XXX - unimplemented protocols */ case P_TCPLOGIN: do_tcp(ai); break; case P_CONSOLE: do_console(ai); break; #endif case P_SLIP: case P_CSLIP: do_slip(ai); break; case P_PPP: case P_PPP_ONLY: case P_AUTOPPP: do_ppp(ai); break; case P_RLOGIN: do_rlogin(ai); break; case P_TELNET: do_telnet(ai); break; case P_SSH1: case P_SSH2: do_ssh(ai); break; case P_LOCAL: case P_SHELL: do_local(ai, id, pid == 0 ? getppid() : 0); break; default: printf("protocol `%c' unsupported\n", ai->proto); fflush(stdout); xusleep(500000); break; } if(pid == 0) exit(0); return 0; } portslave-2010.04.19.1/src/auth.c0000664000000000000000000001424110027271565013061 0ustar /* * auth.c Authentication for socket port * * 1st Version: @(#)auth.c 1.00 19-Jan-2001 EAS * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef NO_CHAP #include "chap.h" #ifdef CHAPMS #include "chap_ms.h" #endif #endif #include "server.h" #ifdef PORTSLAVE_TACACS #include "tacc/libtac.h" #endif #ifdef HAS_SHADOW #include #endif #define CRYPT_EP_SIZE 35 /* Maximum encrypted password size (34 bytes for MD5)*/ static char *pw_encrypt(const char *clear, const char *salt) { static char cipher[CRYPT_EP_SIZE]; char *cp; cp = (char *) crypt(clear, salt); /* if crypt (a nonstandard crypt) returns a string too large, truncate it so we don't overrun buffers and hope there is enough security in what's left */ strncpy(cipher, cp, CRYPT_EP_SIZE); cipher[CRYPT_EP_SIZE - 1] = 0; return cipher; } /* login_local can't be static: called by other modules */ int login_local(struct auth *pai) { struct passwd *pwd; char *password; int rtn; #ifdef HAS_SHADOW struct spwd *spwd = NULL; #endif pwd = getpwnam(pai->login); if(!pwd) { /* No username info */ if(pai->message[0]) free(pai->message[0]); pai->message[0] = xstrdup("Invalid Login.\n"); pai->msn = 1; return(1); } #ifdef HAS_SHADOW if( !strcmp(pwd->pw_passwd, "x") || !strcmp(pwd->pw_passwd, "*") ) { spwd = getspnam(pai->login); if(!spwd) { /* No username info */ if(pai->message[0]) free(pai->message[0]); pai->message[0] = xstrdup("Invalid Login.\n"); pai->msn = 1; return(1); } password = spwd->sp_pwdp; } else #endif /* HAS_SHADOW */ { password = pwd->pw_passwd; } if(*password == '\0' && pai->passwd == '\0') { rtn = 0; } else { char salt[12]; if(!strncmp(password, "$1$", 3)) { memcpy(salt, password, sizeof(salt) - 1); salt[sizeof(salt) - 1] = '\0'; } else { memcpy(salt, password, 2); salt[2] = '\0'; } if((rtn = strcmp(pw_encrypt(pai->passwd, salt), password))) { /* No username info */ if(pai->message[0]) free(pai->message[0]); pai->message[0] = xstrdup("Invalid Login.\n"); pai->msn = 1; } } endpwent(); /* stop access to password file */ endgrent(); /* stop access to group file */ #ifdef HAS_SHADOW endspent(); /* stop access to shadow passwd file */ #endif if(!rtn && pai->proto == P_AUTOPPP) { pai->proto = P_PPP; if(pai->address == 0 && lineconf.rem_host) pai->address = lineconf.rem_host; } if(rtn == 0) pai->authenticated = 1; return(rtn); } static int tac_client(struct auth *pai) { if(pai->message[0]) free(pai->message[0]); pai->message[0] = xstrdup("Authentication protocol is not available yet\n"); pai->msn = 1; return(1); } #ifdef UNUSED /* This isn't ready yet */ static int check_users_access(char *users, char *the_user) { char *p, ch[32]; int deny_access; if(users == NULL || *users == 0) return 0; deny_access = strchr(users, '!') ? 1 : 0; for(p=ch; users; users++) { switch(*users) { case 0: users = (char *)-1; /* fall through */ case '!': case ',': case ' ': case '\t': if(p != ch) { *p = 0; if (!strcmp(ch, the_user)) return(deny_access); p = ch; } break; default: *p++ = *users; break; } } /* user not found only accept if users should be denied */ return(!deny_access); } #endif int do_local_or_server_authentication(struct auth *pai, bool ppp) { unsigned int x; pai->msn = 0; pai->do_acct = false; pai->authenticated = false; switch (lineconf.authtype) { case AUTH_NONE: return(0); case AUTH_RADIUS_LOCAL: if(!rad_client(pai, ppp)) { pai->do_acct = 1; goto check_access; } if(!login_local(pai)) goto check_access; break; case AUTH_LOCAL_RADIUS: if(!login_local(pai)) goto check_access; if(!rad_client(pai, ppp)) { pai->do_acct = 1; goto check_access; } break; case AUTH_RADIUS: if(!rad_client(pai, ppp)) { pai->do_acct = 1; goto check_access; } break; case AUTH_TACACS: if(tac_client(pai)) goto check_access; break; case AUTH_LOCAL_TACACS: if(!login_local(pai)) goto check_access; if(tac_client(pai)) goto check_access; break; case AUTH_TACACS_LOCAL: if(tac_client(pai)) goto check_access; if(!login_local(pai)) goto check_access; break; case AUTH_LOCAL: if(!login_local(pai)) goto check_access; break; case AUTH_REMOTE: goto check_access; } if(pai->msn) { for(x = 0; x < pai->msn; x++) write(STDOUT_FILENO, pai->message[x], strlen(pai->message[x])); write(STDOUT_FILENO, "\r\n", 2); } else { write(STDOUT_FILENO, "Authentication failure\r\n", 24); } return(1); check_access: /* if (check_users_access(lineconf.users, pai->login)) { write(STDOUT_FILENO, "Port access permission denied\r\n", 32); return(1); } */ return(0); } #ifndef NO_CHAP int do_chap_authentication(struct auth *pai, u_char *remmd, chap_state *cstate) { pai->msn = 0; pai->do_acct = false; pai->authenticated = false; switch (lineconf.authtype) { case AUTH_NONE: return CHAP_FAILURE; case AUTH_RADIUS_LOCAL: case AUTH_LOCAL_RADIUS: case AUTH_RADIUS: if(rad_client_chap(pai, remmd, cstate) == CHAP_SUCCESS) { pai->do_acct = 1; pai->done_chap_once++; if(pai->done_chap_once > 1) goto check_access; return CHAP_SUCCESS; } break; case AUTH_REMOTE: goto check_access; } return CHAP_FAILURE; check_access: /* if (check_users_access(lineconf.users, pai->login)) { write(STDOUT_FILENO, "Port access permission denied\r\n", 32); return CHAP_FAILURE; } */ return CHAP_SUCCESS; } #endif portslave-2010.04.19.1/src/tacc/0000775000000000000000000000000007412472207012664 5ustar portslave-2010.04.19.1/src/tacc/authen_r.c0000664000000000000000000000470507411455210014635 0ustar /* * Copyright 1997-98 by Pawel Krawczyk * * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html * for details. * * authen_r.c Read PAP authentication reply from server. */ #include #include #include #include #include "tacplus.h" #include "libtac.h" #include "messages.h" #include "../server.h" /* reads packet from TACACS+ server; returns: * NULL if the authentication succeded * string pointer if it failed */ char *tac_authen_pap_read(int fd) { HDR th; struct authen_reply *tb; int len_from_header, r, len_from_body; char *msg = NULL; int msg_len,data_len; /* read the reply header */ r=read(fd, &th, TAC_PLUS_HDR_SIZE); if(r < TAC_PLUS_HDR_SIZE) { nsyslog(LOG_ERR, "error reading PAP authen header, read %d of %d: %m", r, TAC_PLUS_HDR_SIZE); return(strdup(system_err_msg)); } /* check the reply fields in header */ msg = _tac_check_header(&th, TAC_PLUS_AUTHEN); if(msg != NULL) return(strdup(msg)); len_from_header=ntohl(th.datalength); tb=(struct authen_reply *) xmalloc(len_from_header); /* read reply packet body */ r=read(fd, tb, len_from_header); if(r < len_from_header) { nsyslog(LOG_ERR, "incomplete message body, %d bytes, expected %d: %m", r, len_from_header); return(strdup(system_err_msg)); } /* decrypt the body */ _tac_crypt((u_char *) tb, &th, len_from_header); msg_len = ntohs(tb->msg_len); data_len = ntohs(tb->data_len); /* check the length fields */ len_from_body=sizeof(tb->status) + sizeof(tb->flags) + sizeof(tb->msg_len) + sizeof(tb->data_len) + msg_len + data_len; if(len_from_header != len_from_body) { nsyslog(LOG_ERR, "invalid reply content, incorrect key?"); return(strdup(system_err_msg)); } /* save status and clean up */ r=tb->status; if(msg_len) { msg=(char *) xmalloc(msg_len + 1); bcopy((char *) tb + TAC_AUTHEN_REPLY_FIXED_FIELDS_SIZE, msg, msg_len); } else msg=xstrdup("Login incorrect"); /* I hope msg is freed somewhere */ free(tb); /* server authenticated username and password successfully */ if(r == TAC_PLUS_AUTHEN_STATUS_PASS) { TACDEBUG((LOG_DEBUG, "%s: authentication ok", __FUNCTION__)) return(NULL); } /* return pointer to server message */ nsyslog(LOG_DEBUG, "authentication failed, server reply was %d (%s)", r, msg); return(strdup(msg)); } /* tac_authen_pap_read */ portslave-2010.04.19.1/src/tacc/libtac.h0000664000000000000000000000240107411455210014262 0ustar /* * Copyright 1997 by Pawel Krawczyk * * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html * for details. * */ #ifndef _AUTH_TAC_H #define _AUTH_TAC_H #if defined(DEBUGTAC) && !defined(TACDEBUG) #define TACDEBUG(x) syslog x; #else #define TACDEBUG(x) #endif /* version.c */ extern int tac_ver_major; extern int tac_ver_minor; extern int tac_ver_patch; /* header.c */ extern int session_id; extern int tac_encryption; extern char *tac_secret; extern int tac_connect(u_long *server, int servers); extern int tac_authen_pap_send(int fd, char *User, char *Pass, char *tty); extern char *tac_authen_pap_read(int fd); extern HDR *_tac_req_header(u_char type); extern void _tac_crypt(u_char *buf, HDR *th, int length); extern u_char *_tac_md5_pad(int len, HDR *hdr); extern void tac_add_attrib(struct tac_attrib *attr, char *name, char *value); extern void tac_free_attrib(struct tac_attrib *attr); extern int tac_account_send(int fd, int type, char *User, char *tty, char *rem_addr, struct tac_attrib *attr); extern char *tac_account_read(int fd); extern char *_tac_check_header(HDR *th, int type); extern int tac_author_send(int fd, char *username, char *tty, struct tac_attrib *attr); extern struct areply *tac_author_read(int fd); #endif portslave-2010.04.19.1/src/tacc/attrib.c0000664000000000000000000000212707411455210014311 0ustar /* * Copyright 1997-98 by Pawel Krawczyk * * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html * for details. * * attrib.c Procedures for handling internal list of attributes * for accounting and authorization functions. */ #include #include #include "tacplus.h" #include "libtac.h" #include "../server.h" void tac_add_attrib(struct tac_attrib *attr, char *name, char *value) { struct tac_attrib *a; u_char l1, l2; a = attr; /* find last block in chain */ while((a->attr != 0) && (a->next != 0)) { a = a->next; } /* fill the block */ l1 = (u_char) strlen(name); l2 = (u_char) strlen(value); a->attr_len=l1+l2+1; a->attr = (char *) xmalloc(l1+l2+1); bcopy(name, a->attr, l1); *(a->attr+l1)='='; bcopy(value, (a->attr+l1+1), l2); /* allocate next structure */ a->next=(struct tac_attrib *) xmalloc(sizeof(struct tac_attrib)); } void tac_free_attrib(struct tac_attrib *attr) { struct tac_attrib *a; struct tac_attrib *b; a = attr; while(a->attr != 0 && a) { free(a->attr); b = a; a = a->next; free(b); } } portslave-2010.04.19.1/src/tacc/author_r.c0000664000000000000000000000723507411455210014654 0ustar /* * Copyright 1997-98 by Pawel Krawczyk * * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html * for details. * * author_r.c Reads authorization reply from the server. */ #include #include #include #include #include #include "tacplus.h" #include "../server.h" #include "libtac.h" #include "messages.h" /* This function returns structure containing 1. status (granted/denied) 2. message for the user 3. list of attributes returned by server The attributes should be applied to service authorization is requested for, but actually the aren't. Attributes are discarded. */ struct areply *tac_author_read(int fd) { HDR th; struct author_reply *tb; int len_from_header, r, len_from_body; char *pktp; char *msg = NULL; struct areply *re = (struct areply *) xmalloc(sizeof(struct areply)); r=read(fd, &th, TAC_PLUS_HDR_SIZE); if(r < TAC_PLUS_HDR_SIZE) { nsyslog(LOG_ERR, "short author header, %d of %d: %m", r, TAC_PLUS_HDR_SIZE); re->msg = system_err_msg; re->status = AUTHOR_STATUS_ERROR; return(re); } /* check header consistency */ msg = _tac_check_header(&th, TAC_PLUS_AUTHOR); if(msg != NULL) { /* no need to process body if header is broken */ re->msg = msg; re->status = AUTHOR_STATUS_ERROR; return(re); } len_from_header=ntohl(th.datalength); tb=(struct author_reply *) xmalloc(len_from_header); /* read reply packet body */ r=read(fd, tb, len_from_header); if(r < len_from_header) { nsyslog(LOG_ERR, "short author body, %d of %d: %m", r, len_from_header); re->msg = system_err_msg; re->status = AUTHOR_STATUS_ERROR; return(re); } /* decrypt the body */ _tac_crypt((u_char *) tb, &th, len_from_header); /* check consistency of the reply body * len_from_header = declared in header * len_from_body = value computed from body fields */ len_from_body = TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE + tb->msg_len + tb->data_len; pktp = (u_char *) tb + TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE; for(r = 0; r < tb->arg_cnt; r++) { len_from_body += sizeof(u_char); /* add arg length field's size*/ len_from_body += *pktp; /* add arg length itself */ } /* if(len_from_header != len_from_body) { nsyslog(LOG_ERR, "inconsistent author reply body, incorrect key?"); re->msg = system_err_msg; re->status = AUTHOR_STATUS_ERROR; return(re); } */ /* packet seems to be consistent, prepare return messages */ /* server message for user */ if(tb->msg_len) { re->msg = (char *) xmalloc(tb->msg_len+1); bcopy(tb+TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE + (tb->arg_cnt)*sizeof(u_char), msg, tb->msg_len); } /* server message to syslog */ if(tb->data_len) { char *smsg=(char *) xmalloc(tb->data_len+1); bcopy(tb + TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE + (tb->arg_cnt)*sizeof(u_char) + tb->msg_len, smsg, tb->data_len); nsyslog(LOG_ERR, "author failed: %s", smsg); free(smsg); } /* prepare status */ switch(tb->status) { /* success conditions */ case AUTHOR_STATUS_PASS_ADD: case AUTHOR_STATUS_PASS_REPL: if(!re->msg) re->msg=author_ok_msg; re->status=tb->status; break; /* authorization failure conditions */ /* failing to follow is allowed by RFC, page 23 */ case AUTHOR_STATUS_FOLLOW: case AUTHOR_STATUS_FAIL: if(!re->msg) re->msg=author_fail_msg; re->status=AUTHOR_STATUS_FAIL; break; /* error conditions */ case AUTHOR_STATUS_ERROR: default: if(!re->msg) re->msg=author_err_msg; re->status=AUTHOR_STATUS_ERROR; } free(tb); TACDEBUG((LOG_DEBUG, "%s: server replied '%s'", __FUNCTION__, \ re->msg)) return(re); } portslave-2010.04.19.1/src/tacc/depends0000664000000000000000000000110707411455210014222 0ustar # DO NOT DELETE attrib.o: tacplus.h libtac.h ../server.h ../../pslave_cfg.h attrib.o: ../../ppp-2.4.1/pppd/pppd.h ../../ppp-2.4.1/pppd/patchlevel.h attrib.o: ../rwconf.h ../auth.h authen_r.o: tacplus.h libtac.h authen_s.o: tacplus.h libtac.h author_r.o: tacplus.h ../server.h ../../pslave_cfg.h author_r.o: ../../ppp-2.4.1/pppd/pppd.h ../../ppp-2.4.1/pppd/patchlevel.h author_r.o: ../rwconf.h ../auth.h libtac.h author_s.o: tacplus.h libtac.h ../server.h ../../pslave_cfg.h author_s.o: ../../ppp-2.4.1/pppd/pppd.h ../../ppp-2.4.1/pppd/patchlevel.h author_s.o: ../rwconf.h ../auth.h portslave-2010.04.19.1/src/tacc/messages.c0000664000000000000000000000073207411455210014633 0ustar /* * Copyright 1997-98 by Pawel Krawczyk * * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html * for details. * * messages.c Various messages returned to user. */ const char *system_err_msg="Authentication error, please contact administrator."; const char *protocol_err_msg="Protocol error."; const char *author_ok_msg="Service granted."; const char *author_fail_msg="Service not allowed."; const char *author_err_msg="Protocol error."; portslave-2010.04.19.1/src/tacc/author_s.c0000664000000000000000000000626307411455210014655 0ustar /* * Copyright 1997-98 by Pawel Krawczyk * * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html * for details. * * author_s.c Send authorization request to the server. */ #include #include #include #include #include #include #include #include "tacplus.h" #include "libtac.h" #include "../server.h" /* Send authorization request to the server, along with attributes specified in attribute list prepared with tac_add_attrib. */ int tac_author_send(int fd, char *User, char *tty, struct tac_attrib *attr) { HDR *th; struct author tb; u_char user_len, port_len; struct tac_attrib *a; int i = 0; /* attributes count */ int pkt_len = 0; /* current packet length */ int pktl = 0; /* temporary storage for previous pkt_len values */ int w; /* write() return value */ u_char *pkt; /* packet building pointer */ int ret = 0; th=_tac_req_header(TAC_PLUS_AUTHOR); /* set header options */ th->version=TAC_PLUS_VER_0; th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED : TAC_PLUS_CLEAR; TACDEBUG((LOG_DEBUG, "%s: user '%s', tty '%s', encrypt: %s", \ __FUNCTION__, User, \ tty, tac_encryption ? "yes" : "no")) user_len=(u_char) strlen(User); port_len=(u_char) strlen(tty); tb.authen_method=AUTHEN_METH_TACACSPLUS; tb.priv_lvl=TAC_PLUS_PRIV_LVL_MIN; tb.authen_type=TAC_PLUS_AUTHEN_TYPE_PAP; tb.service=TAC_PLUS_AUTHEN_SVC_PPP; tb.user_len=user_len; tb.port_len=port_len; tb.rem_addr_len=0; /* allocate packet */ pkt=(u_char *) xmalloc(TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE); pkt_len=sizeof(tb); /* fill attribute length fields */ a = attr; while(a->attr != 0 && a) { pktl = pkt_len; pkt_len += sizeof(a->attr_len); pkt = xrealloc(pkt, pkt_len); /* bad method: realloc() is allowed to return different pointer with each call pktp=pkt + pkt_len; pkt_len += sizeof(a->attr_len); pkt = xrealloc(pkt, pkt_len); */ bcopy(&a->attr_len, pkt + pktl, sizeof(a->attr_len)); i++; a = a->next; } /* fill the arg count field and add the fixed fields to packet */ tb.arg_cnt = i; bcopy(&tb, pkt, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE); /* #define PUTATTR(data, len) \ pktp = pkt + pkt_len; \ pkt_len += len; \ pkt = xrealloc(pkt, pkt_len); \ bcopy(data, pktp, len); */ #define PUTATTR(data, len) \ pktl = pkt_len; \ pkt_len += len; \ pkt = xrealloc(pkt, pkt_len); \ bcopy(data, pkt + pktl, len); /* fill user and port fields */ PUTATTR(User, user_len) PUTATTR(tty, port_len) /* fill attributes */ a = attr; while(a->attr != 0 && a) { PUTATTR(a->attr, a->attr_len) a = a->next; } /* finished building packet, fill len_from_header in header */ th->datalength = htonl(pkt_len); /* write header */ w=write(fd, th, TAC_PLUS_HDR_SIZE); if(w < TAC_PLUS_HDR_SIZE) { nsyslog(LOG_ERR, "author hdr send failed: wrote %d of %d", w, TAC_PLUS_HDR_SIZE); ret = -1; } /* encrypt packet body */ _tac_crypt(pkt, th, pkt_len); /* write body */ w=write(fd, pkt, pkt_len); if(w < pkt_len) { nsyslog(LOG_ERR, "author body send failed: wrote %d of %d", w, pkt_len); ret = -1; } free(pkt); free(th); return(ret); } portslave-2010.04.19.1/src/tacc/messages.h0000664000000000000000000000022307411455210014633 0ustar extern char *system_err_msg; extern char *protocol_err_msg; extern char *author_ok_msg; extern char *author_fail_msg; extern char *author_err_msg; portslave-2010.04.19.1/src/tacc/Makefile0000664000000000000000000000076507411455210014326 0ustar # Generated automatically from Makefile.in by configure. CC = gcc CFLAGS = -O2 -Wall -W -Wshadow -Wpointer-arith -Wwrite-strings -pedantic -ffor-scope ${EXTRA_CFLAGS} ALL: tacc.a TACCSRC = attrib.c authen_r.c authen_s.c author_r.c author_s.c messages.c connect.c TACCOBJS = $(TACCSRC:.c=.o) tacc.a: $(TACCOBJS) $(CC) -shared $(CFLAGS) -o $@ $< %.o: %.c $(CC) $(CFLAGS) -fPIC -DPIC -c -o $@ $< clean: rm -f *~ *.o *.a dep: -makedepend -Y -f depends *.c 2> /dev/null include depends portslave-2010.04.19.1/src/tacc/authen_s.c0000664000000000000000000000516207411455210014634 0ustar /* * Copyright 1997-98 by Pawel Krawczyk * * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html * for details. * * authen_s.c Send PAP authentication request to the server. */ #include #include #include #include #include "tacplus.h" #include "libtac.h" #include "../server.h" /* this function sends a packet do TACACS+ server, asking * for validation of given username and password */ int tac_authen_pap_send(int fd, char *User, char *Pass, char *tty) { HDR *th; /* TACACS+ packet header */ struct authen_start tb; /* message body */ int user_len, port_len, pass_len, bodylength, w; int pkt_len=0; u_char *pkt; int ret=0; th=_tac_req_header(TAC_PLUS_AUTHEN); /* set some header options */ th->version=TAC_PLUS_VER_1; th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED : TAC_PLUS_CLEAR; TACDEBUG((LOG_DEBUG, "%s: user '%s', pass '%s', tty '%s', encrypt: %s", \ __FUNCTION__, User, Pass, tty, \ (tac_encryption) ? "yes" : "no")) /* get size of submitted data */ user_len=strlen(User); port_len=strlen(tty); pass_len=strlen(Pass); /* fill the body of message */ tb.action=TAC_PLUS_AUTHEN_LOGIN; tb.priv_lvl=TAC_PLUS_PRIV_LVL_MIN; tb.authen_type=TAC_PLUS_AUTHEN_TYPE_PAP; tb.service=TAC_PLUS_AUTHEN_SVC_PPP; tb.user_len=user_len; tb.port_len=port_len; tb.rem_addr_len=0; /* may be e.g Caller-ID in future */ tb.data_len=pass_len; /* fill body length in header */ bodylength=sizeof(tb) + user_len + port_len + pass_len; /* + rem_addr_len */ th->datalength= htonl(bodylength); /* we can now write the header */ w=write(fd, th, TAC_PLUS_HDR_SIZE); if(w < 0 || w < TAC_PLUS_HDR_SIZE) { nsyslog(LOG_ERR, "short write on PAP header: wrote %d of %d: %m", w, TAC_PLUS_HDR_SIZE); ret=-1; } /* build the packet */ pkt=(u_char *) xmalloc(bodylength+10); bcopy(&tb, pkt+pkt_len, sizeof(tb)); /* packet body beginning */ pkt_len+=sizeof(tb); bcopy(User, pkt+pkt_len, user_len); /* user */ pkt_len+=user_len; bcopy(tty, pkt+pkt_len, port_len); /* tty */ pkt_len+=port_len; bcopy(Pass, pkt+pkt_len, pass_len); /* password */ pkt_len+=pass_len; /* pkt_len == bodylength ? */ if(pkt_len != bodylength) { TACDEBUG((LOG_DEBUG, "tac_authen_send: bodylength %d != pkt_len %d", bodylength, pkt_len)); } /* encrypt the body */ _tac_crypt(pkt, th, bodylength); w=write(fd, pkt, pkt_len); if(w < 0 || w < pkt_len) { nsyslog(LOG_ERR, "short write on PAP body: wrote %d of %d: %m", w, pkt_len); ret=-1; } free(pkt); free(th); return(ret); } /* tac_authen_pap_send */ portslave-2010.04.19.1/src/tacc/tacplus.h0000664000000000000000000001542607411455210014512 0ustar /* Copyright (c) 1995-1998 by Cisco systems, Inc. Portions copyright 1997-98 by Pawel Krawczyk Permission to use, copy, modify, and distribute this software for any purpose and without fee is hereby granted, provided that this copyright and permission notice appear on all copies of the software and supporting documentation, the name of Cisco Systems, Inc. not be used in advertising or publicity pertaining to distribution of the program without specific prior permission, and notice be given in supporting documentation that modification, copying and distribution is by permission of Cisco Systems, Inc. Cisco Systems, Inc. makes no representations about the suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef _TACPLUS_H #define _TACPLUS_H #include #include struct tac_attrib { char *attr; u_char attr_len; struct tac_attrib *next; }; struct areply { struct tac_attrib *attr; char *msg; int status; }; #ifndef TAC_PLUS_MAXSERVERS #define TAC_PLUS_MAXSERVERS 4 #endif #ifndef TAC_PLUS_PORT #define TAC_PLUS_PORT 49 #endif #define TAC_PLUS_READ_TIMEOUT 180 /* seconds */ #define TAC_PLUS_WRITE_TIMEOUT 180 /* seconds */ /* All tacacs+ packets have the same header format */ struct tac_plus_pak_hdr { u_char version; #define TAC_PLUS_MAJOR_VER_MASK 0xf0 #define TAC_PLUS_MAJOR_VER 0xc0 #define TAC_PLUS_MINOR_VER_0 0x0 #define TAC_PLUS_VER_0 (TAC_PLUS_MAJOR_VER | TAC_PLUS_MINOR_VER_0) #define TAC_PLUS_MINOR_VER_1 0x01 #define TAC_PLUS_VER_1 (TAC_PLUS_MAJOR_VER | TAC_PLUS_MINOR_VER_1) u_char type; #define TAC_PLUS_AUTHEN 1 #define TAC_PLUS_AUTHOR 2 #define TAC_PLUS_ACCT 3 u_char seq_no; /* packet sequence number */ u_char encryption; /* packet is encrypted or cleartext */ #define TAC_PLUS_ENCRYPTED 0x0 /* packet is encrypted */ #define TAC_PLUS_CLEAR 0x1 /* packet is not encrypted */ int session_id; /* session identifier FIXME: Is this needed? */ int datalength; /* length of encrypted data following this * header */ /* datalength bytes of encrypted data */ }; #define TAC_PLUS_HDR_SIZE 12 typedef struct tac_plus_pak_hdr HDR; /* Authentication packet NAS sends to us */ struct authen_start { u_char action; #define TAC_PLUS_AUTHEN_LOGIN 0x1 #define TAC_PLUS_AUTHEN_CHPASS 0x2 #define TAC_PLUS_AUTHEN_SENDPASS 0x3 /* deprecated */ #define TAC_PLUS_AUTHEN_SENDAUTH 0x4 u_char priv_lvl; #define TAC_PLUS_PRIV_LVL_MIN 0x0 #define TAC_PLUS_PRIV_LVL_MAX 0xf u_char authen_type; #define TAC_PLUS_AUTHEN_TYPE_ASCII 1 #define TAC_PLUS_AUTHEN_TYPE_PAP 2 #define TAC_PLUS_AUTHEN_TYPE_CHAP 3 #define TAC_PLUS_AUTHEN_TYPE_ARAP 4 u_char service; #define TAC_PLUS_AUTHEN_SVC_LOGIN 1 #define TAC_PLUS_AUTHEN_SVC_ENABLE 2 #define TAC_PLUS_AUTHEN_SVC_PPP 3 #define TAC_PLUS_AUTHEN_SVC_ARAP 4 #define TAC_PLUS_AUTHEN_SVC_PT 5 #define TAC_PLUS_AUTHEN_SVC_RCMD 6 #define TAC_PLUS_AUTHEN_SVC_X25 7 #define TAC_PLUS_AUTHEN_SVC_NASI 8 u_char user_len; u_char port_len; u_char rem_addr_len; u_char data_len; /* */ /* */ /* */ /* */ }; #define TAC_AUTHEN_START_FIXED_FIELDS_SIZE 8 /* Authentication continue packet NAS sends to us */ struct authen_cont { u_short user_msg_len; u_short user_data_len; u_char flags; #define TAC_PLUS_CONTINUE_FLAG_ABORT 0x1 /* */ /* */ }; #define TAC_AUTHEN_CONT_FIXED_FIELDS_SIZE 5 /* Authentication reply packet we send to NAS */ struct authen_reply { u_char status; #define TAC_PLUS_AUTHEN_STATUS_PASS 1 #define TAC_PLUS_AUTHEN_STATUS_FAIL 2 #define TAC_PLUS_AUTHEN_STATUS_GETDATA 3 #define TAC_PLUS_AUTHEN_STATUS_GETUSER 4 #define TAC_PLUS_AUTHEN_STATUS_GETPASS 5 #define TAC_PLUS_AUTHEN_STATUS_RESTART 6 #define TAC_PLUS_AUTHEN_STATUS_ERROR 7 #define TAC_PLUS_AUTHEN_STATUS_FOLLOW 0x21 u_char flags; #define TAC_PLUS_AUTHEN_FLAG_NOECHO 0x1 u_short msg_len; u_short data_len; /* */ /* */ }; #define TAC_AUTHEN_REPLY_FIXED_FIELDS_SIZE 6 #define AUTHEN_METH_NONE 0x01 #define AUTHEN_METH_KRB5 0x02 #define AUTHEN_METH_LINE 0x03 #define AUTHEN_METH_ENABLE 0x04 #define AUTHEN_METH_LOCAL 0x05 #define AUTHEN_METH_TACACSPLUS 0x06 #define AUTHEN_METH_RCMD 0x20 struct acct { u_char flags; #define TAC_PLUS_ACCT_FLAG_MORE 0x1 #define TAC_PLUS_ACCT_FLAG_START 0x2 #define TAC_PLUS_ACCT_FLAG_STOP 0x4 #define TAC_PLUS_ACCT_FLAG_WATCHDOG 0x8 u_char authen_method; u_char priv_lvl; u_char authen_type; u_char authen_service; u_char user_len; u_char port_len; u_char rem_addr_len; u_char arg_cnt; /* the number of cmd args */ /* one u_char containing size for each arg */ /* */ /* */ /* */ /* char data for args 1 ... n */ }; #define TAC_ACCT_REQ_FIXED_FIELDS_SIZE 9 struct acct_reply { u_short msg_len; u_short data_len; u_char status; #define TAC_PLUS_ACCT_STATUS_SUCCESS 0x1 #define TAC_PLUS_ACCT_STATUS_ERROR 0x2 #define TAC_PLUS_ACCT_STATUS_FOLLOW 0x21 }; #define TAC_ACCT_REPLY_FIXED_FIELDS_SIZE 5 /* An authorization request packet */ struct author { u_char authen_method; u_char priv_lvl; u_char authen_type; u_char service; u_char user_len; u_char port_len; u_char rem_addr_len; u_char arg_cnt; /* the number of args */ /* */ /* */ /* */ /* */ /* */ }; #define TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE 8 /* An authorization reply packet */ struct author_reply { u_char status; u_char arg_cnt; u_short msg_len; u_short data_len; #define AUTHOR_STATUS_PASS_ADD 0x01 #define AUTHOR_STATUS_PASS_REPL 0x02 #define AUTHOR_STATUS_FAIL 0x10 #define AUTHOR_STATUS_ERROR 0x11 #define AUTHOR_STATUS_FOLLOW 0x21 /* */ /* */ /* */ /* */ }; #define TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE 6 #endif portslave-2010.04.19.1/src/tacc/connect.c0000664000000000000000000000332307411455210014454 0ustar /* * Copyright 1997-98 by Pawel Krawczyk * * See http://www.ceti.com.pl/~kravietz/progs/tacacs.html * for details. * * connect.c Open connection to server. */ #include #include #include #include #include #include #include #include #include "../server.h" #include "tacplus.h" #include "libtac.h" /* Returns file descriptor of open connection to the first available server from list passed in server table. */ int tac_connect(u_long *server, int servers) { struct sockaddr_in serv_addr; const struct servent *srv; int fd; int tries = 0; if(!servers) { nsyslog(LOG_ERR, "no TACACS+ servers defined"); return(-1); } while(tries < servers) { bzero( (char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = server[tries]; srv = getservbyname("tacacs", "tcp"); if(srv == NULL) serv_addr.sin_port = htons(TAC_PLUS_PORT); else serv_addr.sin_port = srv->s_port; if((fd=socket(AF_INET, SOCK_STREAM, 0)) < 0) { nsyslog(LOG_WARNING, "socket creation error for %s: %m", dotted(server[tries])); tries++; continue; } if(connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { nsyslog(LOG_WARNING, "connection to %s failed: %m", dotted(server[tries])); tries++; close(fd); continue; } /* connected ok */ TACDEBUG((LOG_DEBUG, "%s: connected to %s", __FUNCTION__, \ dotted(server[tries]))); return(fd); } /* all attempts failed */ nsyslog(LOG_ERR, "all possible TACACS+ servers failed"); return(-1); } /* tac_connect */ portslave-2010.04.19.1/src/depends0000664000000000000000000000152210027274073013314 0ustar # DO NOT DELETE auth.o: server.h ../pslave_cfg.h rwconf.h auth.h chat.o: ../pslave_cfg.h server.h rwconf.h auth.h ctlp-subs.o: server.h ../pslave_cfg.h rwconf.h auth.h ctlportslave.o: server.h ../pslave_cfg.h rwconf.h auth.h getty.o: server.h ../pslave_cfg.h rwconf.h auth.h lib.o: server.h ../pslave_cfg.h rwconf.h auth.h libpsr.o: server.h ../pslave_cfg.h rwconf.h auth.h main.o: server.h ../pslave_cfg.h rwconf.h auth.h md5.o: md5.h radclient.o: server.h ../pslave_cfg.h rwconf.h auth.h rot_getty.o: server.h ../pslave_cfg.h rwconf.h auth.h rwconf.o: server.h ../pslave_cfg.h rwconf.h auth.h slip.o: server.h ../pslave_cfg.h rwconf.h auth.h sock_srv.o: server.h ../pslave_cfg.h rwconf.h auth.h spawnit.o: server.h ../pslave_cfg.h rwconf.h auth.h syslog.o: server.h ../pslave_cfg.h rwconf.h auth.h utmp.o: server.h ../pslave_cfg.h rwconf.h auth.h portslave-2010.04.19.1/src/sock_srv.c0000664000000000000000000001665610027251456013762 0ustar #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "server.h" #include "rot_buffer.h" void do_telnet_options(void); int main_routine_socket(int DeviceFd, int poll_interval); void fill_auth_struct(struct auth *ai); struct auth *pai; /* Device file descriptor */ int DeviceFd; static int max_fd=0; static fd_set list_fds; /* Function executed when the program exits */ void ExitFunction(void) { int fd; /* Program termination notification */ nsyslog(LOG_NOTICE,"socket stopped"); if (pai->do_acct) { pai->do_acct = 0; rad_acct(pai, 0); } close(0); close(1); close(2); serial_close(DeviceFd); #ifdef FIXME stop_start_buffering(1); #endif /* Closes the sockets/ttySxx */ for(fd=0; fd < max_fd; fd++) { if (FD_ISSET(fd, &list_fds)) { close(fd); } } } /* Main function */ #define TELNET_PORT 23 #define MAX_RETRIES 5 #define MAX_WAIT_TIMER 8 void create_socket_server(struct sockaddr_in *sock, char *devname, fd_set *fds, int *max) { char str[40]; int fd, len = sizeof(struct sockaddr_in); int retries = 0, on = 1; struct linger LingerParm = {0, 0}; sprintf(str, "%s/%d", inet_ntoa(sock->sin_addr), sock->sin_port); while (++retries < MAX_RETRIES) { if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { nsyslog(LOG_ERR, "Create server socket [%s] error: %s", str, strerror(errno)); xsleep(MAX_WAIT_TIMER); continue; } /* Set socket options. We try to make the port reusable and have it close as fast as possible without waiting in unnecessary wait states on close. */ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); setsockopt(fd, SOL_SOCKET, SO_LINGER, &LingerParm, sizeof(LingerParm)); if (bind(fd, (struct sockaddr *)sock, len) < 0) { nsyslog(LOG_ERR, "Bind socket [%s] error: %s", str, strerror(errno)); close(fd); xsleep(MAX_WAIT_TIMER); continue; } if (listen(fd, 2) < 0) { nsyslog(LOG_ERR, "Listen socket [%s] error: %s", str, strerror(errno)); close(fd); xsleep(MAX_WAIT_TIMER); continue; } break; } if (retries >= MAX_RETRIES) { return; } FD_SET(fd, fds); if ((fd + 1) > *max) { *max = fd + 1; } nsyslog(LOG_INFO, "socket: listen to [%s] device /dev/%s\n", str, devname); } static bool got_int_flag = false; void got_int(int unused) { got_int_flag = true; } int do_socket_auth(struct auth *ai) { char s[1024]; int len, i, r; pai->do_acct = 0; if(lineconf.authtype == AUTH_NONE || ai->proto != P_SOCKET_SERVER) { update_utmp("%L", lineconf.utmpfrom, ai, lineconf.syswtmp); return(0); } /* * Show the banner and say hello. */ if(lineconf.issue && lineconf.issue[0]) { expand_format(s, sizeof(s), lineconf.issue, ai); if (s) { len = strlen(s); write(STDOUT_FILENO, s, len); } } for(i=0; i < 3; i++) { r = do_login(ai); if (r == 2) continue; if (r < 0) return(1); /* * Do authentication if needed. */ if (!do_local_or_server_authentication(ai, 0)) { break; } } if (i >= 3) { /* * 3 login failures - exit! */ xusleep(250000); maketermsane(); return(1); } if (ai->do_acct == 1) { /* * While messing around with accounting, we have to * block, but not ignore, SIGHUP and friends. */ block(SIGHUP); block(SIGTERM); rad_acct(ai, 1); unblock(SIGHUP); unblock(SIGTERM); } return(0); } int do_socket(struct auth *ai) { socklen_t addr_len; int server_fd, client_fd, signals; struct sockaddr_in sock_server, sock_client; struct sigaction sa; fd_set list_aux; memset(&sa, 0, sizeof(sa)); pai = ai; atexit(ExitFunction); sa.sa_handler = got_int; sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); unblock(SIGINT); unblock(SIGTERM); if(lineconf.protocol == P_SOCKET_SERVER) { FD_ZERO(&list_fds); /* create all socket to listen to */ if(lineconf.socket_port) { /* Socket with a especific port */ sock_server.sin_family = AF_INET; sock_server.sin_addr.s_addr = lineconf.loc_host; sock_server.sin_port = lineconf.socket_port; create_socket_server(&sock_server, lineconf.tty, &list_fds, &max_fd); } if(lineconf.rem_host) { /* Socket with a especific ip address */ sock_server.sin_addr.s_addr = lineconf.rem_host; sock_server.sin_family = AF_INET; sock_server.sin_port = TELNET_PORT; create_socket_server(&sock_server, lineconf.tty, &list_fds, &max_fd); } if (!max_fd) { nsyslog(LOG_ERR, "Socket: Could not create any socket to listen to..."); return(0); } list_aux = list_fds; if (select(max_fd, &list_aux, NULL, NULL, NULL) < 0) { return(0); } for(server_fd=0; server_fd < max_fd; server_fd++) { if ((FD_ISSET(server_fd, &list_aux))) { break; } } if (server_fd >= max_fd) { return(0); } /* Validate the connection request */ addr_len = sizeof(sock_client); close(0); close(1); close(2); client_fd = accept(server_fd, (struct sockaddr *)&sock_client, &addr_len); ai->address= sock_client.sin_addr.s_addr; dup(client_fd); dup(client_fd); #if 0 for(server_fd=0; server_fd < max_fd; server_fd++) { if (FD_ISSET(server_fd, &list_fds)) { close(server_fd); FD_CLR(server_fd, &list_fds); } } #endif #ifdef FIXME do_telnet_options(); #endif if (do_socket_auth(pai)) { nsyslog(LOG_NOTICE,"Authentication Failure"); return(0); } #ifdef FIXME stop_start_buffering(0); #endif if ((DeviceFd = getty(pai, eLocSocSrv)) < 0) { nsyslog(LOG_ERR,"Error when openning %s", lineconf.tty); return(0); } if(lineconf.dcd) { /* must check DCD */ ioctl(DeviceFd,TIOCMGET,&signals); signals = signals | TIOCM_DTR; ioctl(DeviceFd,TIOCMSET,&signals); ioctl(DeviceFd, TIOCMGET, &signals); if (!(signals & TIOCM_CD) ) { /* DCD is OFF */ nsyslog(LOG_NOTICE,"Fail to connect due to DCD OFF"); return(0); } } update_utmp("%L", lineconf.utmpfrom, ai, lineconf.syswtmp); #ifdef FIXME main_routine_socket(DeviceFd, lineconf.poll_interval); #endif } else { DeviceFd = dup(0); close(0); close(1); close(2); if(lineconf.dcd) { /* must check DCD */ ioctl(DeviceFd,TIOCMGET,&signals); signals = signals | TIOCM_DTR; ioctl(DeviceFd,TIOCMSET,&signals); while(1) { ioctl(DeviceFd, TIOCMGET, &signals); if (signals & TIOCM_CD) { /* DCD is ON */ break; } xsleep(1); if(got_int_flag) return(0); } } sock_client.sin_family = AF_INET; sock_client.sin_addr.s_addr = lineconf.host; sock_client.sin_port = lineconf.socket_port ? lineconf.socket_port : TELNET_PORT; addr_len = sizeof(sock_client); if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { nsyslog(LOG_ERR, "Create client socket error: %s", strerror(errno)); return(0); } if (connect(client_fd, (struct sockaddr *)&sock_client, addr_len) < 0) { nsyslog(LOG_ERR, "Connect socket error: %s", strerror(errno)); return(0); } nsyslog(LOG_INFO, "socket: connected to %s port %d device %s\n", inet_ntoa(sock_client.sin_addr), sock_client.sin_port, lineconf.tty); dup(client_fd); dup(client_fd); update_utmp("%L", lineconf.utmpfrom, ai, lineconf.syswtmp); #ifdef FIXME do_telnet_options(); main_routine_socket(DeviceFd, lineconf.poll_interval); #endif } return(0); } portslave-2010.04.19.1/src/getty.c0000664000000000000000000003134411352106011013240 0ustar /* * getty.c This is the part that talks with the modem, * does the login stuff etc. * * Version: @(#)getty.c 1.34 13-Jan-1998 MvS. * */ #include "server.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define GL_DO_ECHO 1 #define GL_ECHO2 2 #define GL_ECHO4 4 #define GL_ECHO8 8 /* * Turn CR translation on or off. */ static void crtrans(bool inon, bool outon) { struct termios tty; tcgetattr(0, &tty); if(inon) tty.c_iflag |= ICRNL|IGNCR; else tty.c_iflag &= ~(ICRNL|IGNCR); if(outon) tty.c_oflag |= ONLCR|OPOST; else tty.c_oflag &= ~(ONLCR|OPOST); tcsetattr(0, TCSANOW, &tty); } /* * Disassociate from our controlling tty. */ static void disass_ctty() { pid_t pid; int fl; /* * First let go of our old tty. * This looks like black magic. It is ;) */ pid = getpid(); #ifndef __ELF__ /* * a.out systems generally don't have getsid() */ setpgid(0, getpgid(getppid())); setsid(); #else if(getsid(pid) != pid) { if(setpgid(0, getpgid(getppid())) < 0) nsyslog(LOG_WARNING, "setpgid: %m"); if(setsid() < 0) nsyslog(LOG_WARNING, "setsid: %m"); } #endif if((fl = open("/dev/tty", O_RDWR)) >= 0) { signal(SIGHUP, SIG_IGN); if(ioctl(fl, TIOCNOTTY) < 0) nsyslog(LOG_WARNING, "ioctl TIOCNOTTY: %m"); signal(SIGHUP, SIG_DFL); close(fl); } } static void got_hup_exit() { nsyslog(LOG_ERR, "Got Hangup - exiting"); exit(1); } void show_issue(const struct auth * const ai) { char banner [1024]; /* * Show the banner and say hello. */ if(lineconf.issue && lineconf.issue[0]) { expand_format(banner, sizeof (banner), lineconf.issue, ai); fprintf(stdout, "%s\n", banner); fflush(stdout); #ifdef FIDO if(lineconf.fidonet) fprintf(stdout, "**EMSI_REQA77E\r\021 \r"); #endif } } /* * Run a getty on a port. */ int getty(struct auth *ai, LOCATION location) { CHAT_ERR rc; struct sigaction sa; int time_limit; while( (time_limit = chktimes()) < 0) { nsyslog(LOG_DEBUG, "Calls are not allowed for another %d minutes.", -time_limit); xsleep((-time_limit) * 60); } switch(lineconf.protocol) { case P_SOCKET_SERVER: if(location != eLocBuf && location != eLocSocSrv) return -1; break; case P_SOCKET_SSH: if(location != eLocBuf && location != eLocSocket) return -1; break; } if(location != eLocSocket) disass_ctty(); if(location == eLocModem) { close(0); close(1); close(2); } /* * First lock or wait if the port is busy. */ if(!lineconf.lockfile) { if(lockfile(&lineconf.lockfile, lineconf.lockdir, lineconf.tty, location)) { nsyslog(LOG_ERR, "Can't create lock"); return -1; } } dolock_and_wait(10); if(serial_open(location) < 0) { unlink(lineconf.lockfile); return -1; } if(ioctl(0, TIOCSCTTY, 1) < 0) nsyslog(LOG_WARNING, "TIOCSCTTY: %m"); sa.sa_handler = got_hup_exit; sa.sa_flags = SA_RESTART; sigaction(SIGHUP, &sa, NULL); crtrans(false, false); rc = chat(1, lineconf.initchat, ai); if(rc != eNoErr) { crtrans(true, true); switch(rc) { case eInterrupt: nsyslog(LOG_ERR, "initchat failed - interrupted"); break; case eTimeOut: nsyslog(LOG_ERR, "initchat failed - timeout"); break; case eAbort: default: break; } serial_close(); unlink(lineconf.lockfile); return -1; } crtrans(true, true); /* * Delay just a little bit and flush junk. */ xusleep(250000); tcflush(0, TCIOFLUSH); show_issue(ai); return 0; } typedef enum { eGotAlarm = -2, eGotEOF = -1, eGotSuccess = 0, eGotPPP = 1 #ifdef FIDO , eGotEMSI = 2 #endif } GET_LINE_TYPE; static GET_LINE_TYPE get_line(bool ppp, const char *prompt, int echo , char *buffer, int size #ifdef CYCLADES , int flag_telnet #endif ); /* * Imitate a modem on a port. */ int emumodem(struct auth *ai, LOCATION location) { char buf[128]; disass_ctty(); if(!lineconf.lockfile) { if(lockfile(&lineconf.lockfile, lineconf.lockdir, lineconf.tty, location)) { nsyslog(LOG_ERR, "Can't create lock"); return -1; } } close(0); close(1); close(2); /* * First lock or wait if the port is busy. */ dolock_and_wait(10); if(serial_open(location) < 0) { unlink(lineconf.lockfile); return -1; } /* * Now force the new tty into becoming our * controlling tty. This will also kill other * processes hanging on this tty. */ if(ioctl(0, TIOCSCTTY, 1) < 0) nsyslog(LOG_WARNING, "TIOCSCTTY: %m"); /* * Loop, and emulate a modem. */ crtrans(false, false); printf("\r\nNO CARRIER\r\n"); while(1) { fflush(stdout); get_line(false, "", GL_DO_ECHO, buf, sizeof(buf) #ifdef CYCLADES , 0 #endif ); if(strncasecmp(buf, "ATD", 3) == 0) { xsleep(3); printf("CONNECT 115200\r\n"); snprintf (ai->conn_info, sizeof(ai->conn_info), "115200/DIRECT"); fflush(stdout); break; } if(strncasecmp(buf, "AT&V", 4) == 0) { printf("OK - Portslave Modem emulator\r\n"); continue; } if(strncasecmp(buf, "AT", 2) == 0) { printf("OK\r\n"); continue; } if(buf[0]) printf("ERROR\r\n"); } crtrans(true, true); /* * Delay just a little bit and flush junk. */ xusleep(250000); tcflush(0, TCIOFLUSH); show_issue(ai); return 0; } /* * Alarm handler for the login timeout. */ static bool got_alrm; static void alrm_handler() { got_alrm = true; } /* * We've got a connection. Now let the user login. */ int do_login(struct auth *ai) { /* r is ret from get_line(), -1 on EOF, 0 on success, 1 on AutoPPP. */ GET_LINE_TYPE r = 0; const char *p = lineconf.prompt ? lineconf.prompt : "login: "; char prompt[1024]; int to = 60; #ifdef CYCLADES int flag = lineconf.protocol == P_SOCKET_SERVER; #endif got_alrm = false; signal(SIGALRM, alrm_handler); if(lineconf.dcd == 0) to = 0; expand_format(prompt, sizeof (prompt), p, ai); alarm(to); crtrans(false, true); do { r = get_line(true, prompt, GL_DO_ECHO | GL_ECHO2, ai->login, sizeof(ai->login) #ifdef CYCLADES , flag #endif ); } while(r == eGotSuccess && ai->login[0] == '\0'); alarm(0); crtrans(true, true); if(r == eGotSuccess && ai->login[0] == '\0') return 2; if(r == eGotSuccess) nsyslog(LOG_INFO, "Detected login for %s", ai->login); else if(r != eGotPPP) nsyslog(LOG_INFO, "Login timed out / quit"); if(r == eGotPPP) { strncpy(ai->login, "AutoPPP", sizeof(ai->login)-1); ai->login [sizeof(ai->login)-1] = '\0'; ai->passwd[0] = '\0'; return 0; } #ifdef FIDO if(r == eGotEMSI) { if(lineconf.fidonet) { strncpy(ai->login, lineconf.fidologin, sizeof(ai->login) - 1); ai->login [sizeof(ai->login) - 1] = '\0'; strncpy(ai->passwd, lineconf.fidopasswd, sizeof(ai->passwd) - 1); ai->passwd [sizeof(ai->passwd) - 1] = '\0'; } else fprintf(stdout,"\n\nFidoNet calls denied.\n"); return 0; } #endif if(lineconf.locallogins && ai->login[0] == '!') return 0; alarm(to); crtrans(false, true); if(r != eGotSuccess || (r = get_line(true, "Password: ", GL_ECHO4, ai->passwd, sizeof(ai->passwd) #ifdef CYCLADES , flag #endif )) != eGotSuccess) { if(r == eGotPPP) { strncpy(ai->login, "AutoPPP", sizeof(ai->login)-1); ai->login [sizeof(ai->login)-1] = '\0'; ai->passwd[0] = '\0'; r = 0; } #ifdef FIDO if(r == eGotEMSI) { if (lineconf.fidonet) { strncpy(ai->login, lineconf.fidologin, sizeof(ai->login) - 1); ai->login[sizeof(ai->login) - 1] = '\0'; strncpy(ai->passwd, lineconf.fidopasswd, sizeof(ai->passwd) - 1); ai->passwd[sizeof(ai->passwd) - 1] = '\0'; } else fprintf(stdout, "\n\nFidoNet calls denied.\n"); r = 0; } #endif } alarm(0); crtrans(true, true); return r; } #ifdef FIDO /* This is so ugly, gotta fix it and integrate it with the other checking */ #define EMSI "**EMSI" static int emsiseen(int ch) { static char buf[16]; if(ch == -1) { memset(buf, 0, sizeof(buf)); return 0; } memmove(buf, buf + 1, 15); buf[14] = ch; if(strcmp(buf + 15 - 6, EMSI) == 0) return 1; return 0; } #endif /* FIDO */ /* * This part is for the automatic PPP detection. * get_line() can check for it. */ const char * const PPP1 = "\x7e\xff\x03\xc0\x21"; const int PPP1_LEN = 5; const char * const PPP2 = "\x7e\xff\x7d\x23\xc0\x21"; const int PPP2_LEN = 6; const char * const PPP3 = "\x7e\x7d\xdf\x7d\x23\xc0\x21"; const int PPP3_LEN = 7; static int pppseen(int ch) { static char buf[8]; if(ch == -1) { memset(buf, 0, sizeof(buf)); return 0; } memmove(buf, buf + 1, sizeof(buf) - 1); buf[sizeof(buf) - 2] = ch; if(!strcmp(buf + (sizeof(buf) - 1 - PPP1_LEN), PPP1) || !strcmp(buf + (sizeof(buf) - 1 - PPP2_LEN), PPP2) || !strcmp(buf + (sizeof(buf) - 1 - PPP3_LEN), PPP3) ) return 1; return 0; } /* * Read and echo a line. * * Returns -1 on EOF, 0 on success and 1 on PPP detect. */ static GET_LINE_TYPE get_line(bool ppp, const char *prompt, int echo , char *buffer, int size #ifdef CYCLADES , int flag_telnet #endif ) { int pos = 0; unsigned char c; bool echonl = true; static bool crseen = false; int len; GET_LINE_TYPE rc = eGotSuccess; struct sigaction sa; memset(&sa, 0, sizeof(sa)); if(ppp) pppseen(-1); if(prompt && prompt[0]) { len = strlen(prompt); write(STDOUT_FILENO, prompt, len); if(prompt[len - 1] != ' ') write(STDOUT_FILENO, " ", 1); } buffer[0] = '\0'; if(echo & (GL_ECHO2|GL_ECHO4) ) { got_alrm = false; sa.sa_handler = alrm_handler; sigaction(SIGALRM, &sa, NULL); unblock(SIGALRM); } while(1) { if(echo & GL_ECHO8) alarm(60); if(read(STDIN_FILENO, &c, 1) != 1) { rc = eGotEOF; if(got_alrm) { rc = eGotAlarm; write(STDOUT_FILENO, "\r\n", 2); } goto ret_back; } if(echo & GL_ECHO2) echo |= GL_ECHO8; #ifdef CYCLADES if(flag_telnet) { if(!HandleChar(STDOUT_FILENO, DeviceFd, c)) continue; } #endif if(ppp && pppseen(c)) { buffer[0] = '\0'; rc = eGotPPP; goto ret_back; } #ifdef FIDO if(emsiseen(c)) { buffer[0] = '\0'; rc = eGotEMSI; goto ret_back; } #endif if(c == '\n' && crseen) { crseen = false; continue; } crseen = false; switch(c) { case '\n': case '\r': if(c == '\r') crseen = true; buffer[pos] = '\0'; if(echonl) write(STDOUT_FILENO, "\r\n", 2); rc = eGotSuccess; goto ret_back; case 4: /* Control-D */ if(pos == 0) { if(echonl) write(STDOUT_FILENO, "\r\n", 2); rc = eGotEOF; } break; case 5: /* Control-E */ echo ^= ~GL_DO_ECHO; echonl = false; break; case 127: case 8: /* Backspace. */ if(pos == 0) { write(STDOUT_FILENO, "\007", 1); break; } if(echo & GL_DO_ECHO) write(STDOUT_FILENO, "\010 \010", 3); pos--; break; default: if(c < Fascii || c > Lascii || pos >= size - 1) { write(STDOUT_FILENO, "\007", 1); break; } if(echo & GL_DO_ECHO) write(STDOUT_FILENO, &c, 1); buffer[pos++] = c; break; } } rc = eGotEOF; ret_back: alarm(0); if(echo & (GL_ECHO2 | GL_ECHO4) ) signal(SIGALRM, SIG_DFL); buffer[pos] = 0; return rc; } #if 0 /* * Get challenge-response */ static int do_challenge(struct auth *ai) { /* r is ret from get_line(), -1 on EOF, 0 on success, 1 on AutoPPP. */ GET_LINE_TYPE r = 0; int to = 60; #ifdef CYCLADES int flag = lineconf.protocol == P_SOCKET_SERVER; #endif got_alrm = false; signal(SIGALRM, alrm_handler); if(lineconf.dcd == 0) to = 0; nsyslog(LOG_INFO, "Waiting for challenge-response for user %s (%s)" , ai->login, ai->message[0]); alarm(to); crtrans(false, true); r = get_line(true, ai->message[0], GL_DO_ECHO | GL_ECHO2, ai->passwd , sizeof(ai->passwd) #ifdef CYCLADES , flag #endif ); alarm(0); crtrans(true, true); nsyslog(LOG_INFO, "Got challenge-response for user %s: %s (%i)", ai->login , ai->passwd, sizeof(ai->passwd)); return r; } #endif portslave-2010.04.19.1/src/rwconf.c0000664000000000000000000005660310027271674013427 0ustar /* * conf.c Read the configuration file. * * Version: @(#)conf.c 1.25 08-Nov-1997 MvS. * */ #include #include #include #include #include #include #include #include #include #include #include #define EXTERN #include "server.h" #define C_INT 1 #define C_STR 2 #define C_HOST 3 #define C_IPNO 4 #define C_IPDY 5 #define C_IP6NO 6 #define C_CHAT 7 #define C_REALM 8 #define C_INDY 9 #define C_BOOL 10 #define C_HSRV 11 #define C_DEV 12 #define C_LIST 13 #ifdef CYCLADES #define C_XSTR 200 #define C_XIPNO 201 #define C_XINT 202 #endif typedef enum { parseOK = 0, parseErr = -1, parseFatal = -2 } PARSE_RC; /* * For option lists. */ struct lst { const char *name; int value; }; /* * Define type of config variables. */ struct conf { const char *name; int type; const struct lst *opts; void *ptr; bool really_set; }; /* * Types of authentication. */ const struct lst radlst[] = { { "none", AUTH_NONE }, { "radius", AUTH_RADIUS }, { "tacacs", AUTH_TACACS }, { "remote", AUTH_REMOTE }, { "local", AUTH_LOCAL }, { "radius/local", AUTH_RADIUS_LOCAL }, { "tacacs/local", AUTH_TACACS_LOCAL }, { "local/radius", AUTH_LOCAL_RADIUS }, { "local/tacacs", AUTH_LOCAL_TACACS }, #ifdef CYCLADES { "RadiusDownLocal", AUTH_RADIUS_DOWN_LOCAL }, { "TacacsDownLocal", AUTH_TACACS_DOWN_LOCAL }, #endif { NULL, 0 } }; /* * Types of flow control. */ const struct lst flowlst[] = { { "none", FLOW_NONE }, { "hard", FLOW_HARD }, { "soft", FLOW_SOFT }, { NULL, 0 } }; /* * Types of parity. */ const struct lst paritylst[] = { { "none", 1 }, { "odd", 2 }, { "even", 3 }, { NULL, 0} }; /* * Protocols. */ const struct lst prlst[] = { { "login", P_LOCAL }, { "rlogin", P_RLOGIN }, { "telnet", P_TELNET }, { "ssh1", P_SSH1 }, { "ssh2", P_SSH2 }, { "ssh", P_SSH2 }, { "slip", P_SLIP }, { "cslip", P_CSLIP }, { "ppp", P_PPP }, { "ppp_only", P_PPP_ONLY }, { "tcpclear", P_TCPCLEAR }, { "tcplogin", P_TCPLOGIN }, { "console", P_CONSOLE }, { "socket_client", P_SOCKET_CLIENT }, { "socket_server", P_SOCKET_SERVER }, { "socket_ssh", P_SOCKET_SSH }, { NULL, 0 } }; const struct lst ptypelst[] = { { "0", 0 }, { "async", 0 }, { "1", 1 }, { "sync", 1 }, { "2", 2 }, { "isdn", 2 }, { "3", 3 }, { "isdn-v120", 3 }, { "4", 4 }, { "isdn-v110", 4 }, { NULL, 0 } }; const struct lst daylst[] = { { "sun", 1 }, { "mon", 2 }, { "tue", 4 }, { "wed", 8 }, { "thu", 16 }, { "fri", 32 }, { "sat", 64 }, { "week", 62 }, { "weekend", 65 }, { "all", 127 } }; static PARSE_RC setlist(const char *val, const struct lst *lst, void *ptr); /* set a single time range (set of days and hhmm-hhmm time range) */ static PARSE_RC a_login_time(struct time_ent *t_ent, char *str) { int tmp_ind; unsigned sh, sm, eh, em; PARSE_RC rc; char *tmp_str = strtok(str, " "); while(tmp_str && isalpha(tmp_str[0])) { rc = setlist(tmp_str, daylst, &tmp_ind); if(rc) return rc; t_ent->days |= tmp_ind; tmp_str = strtok(NULL, " "); } if(!tmp_str) return parseErr; if(sscanf(tmp_str, "%2u%2u-%2u%2u", &sh, &sm, &eh, &em) != 4) return parseErr; if(sh > 23 || eh > 23 || sm > 59 || em > 59) return parseErr; t_ent->start_time = sh * 60 + sm; t_ent->end_time = eh * 60 + em; if(t_ent->start_time >= t_ent->end_time || t_ent->end_time > 24 * 60) return parseErr; return parseOK; } static void set_login_times(const char * const time_str) { int i = 0; int ar_size = 2; char *time_range; char *time_tmp_str; while (time_str[i]) if (time_str[i++] == ',') ar_size++; lineconf.login_time = (struct time_ent *)xmalloc(ar_size * sizeof(struct time_ent)); time_tmp_str = xstrdup(time_str); time_range = strtok(time_tmp_str, ","); i = 0; while(time_range) { PARSE_RC rc; rc = a_login_time(&lineconf.login_time[i], time_range); if(rc) { free(lineconf.login_time); lineconf.login_time = NULL; free(time_tmp_str); nsyslog(LOG_ERR, "Can't parse time string \"%s\".", time_str); return; } i++; time_range = strtok(NULL, ","); } lineconf.login_time[i].days = 0; free(time_tmp_str); } /* * Define structure for the per-line configuration. */ static struct conf line_cfg[] = { { "hostname", C_STR, NULL, &lineconf.hostname, 0 }, { "radclient_config_file", C_STR, NULL, &lineconf.radclient_config_file, 0 }, { "loc_host", C_IPNO, NULL, &lineconf.loc_host, 0 }, #ifdef HAVE_IPV6 { "loc_host6", C_IP6NO,NULL, &lineconf.loc_host6, 0 }, { "use_v6", C_BOOL, NULL, &lineconf.use_v6, 0 }, #endif { "lockdir", C_STR, NULL, &lineconf.lockdir, 0 }, { "rlogin", C_STR, NULL, &lineconf.rlogin, 0 }, { "telnet", C_STR, NULL, &lineconf.telnet, 0 }, { "ssh", C_STR, NULL, &lineconf.ssh, 0 }, { "pppd", C_STR, NULL, &lineconf.pppd, 0 }, { "locallogins", C_BOOL, NULL, &lineconf.locallogins, 0 }, { "syslog", C_HOST, NULL, &lineconf.syslog, 0 }, { "facility", C_INT, NULL, &lineconf.facility, 0 }, { "filterdir", C_STR, NULL, &lineconf.filterdir, 0 }, { "stripnames", C_BOOL, NULL, &lineconf.stripnames, 0 }, { "debug", C_INT, NULL, &lineconf.debug, 0 }, { "sysutmp", C_BOOL, NULL, &lineconf.sysutmp, 0 }, { "syswtmp", C_BOOL, NULL, &lineconf.syswtmp, 0 }, { "utmpfrom", C_STR, NULL, &lineconf.utmpfrom, 0 }, { "emumodem", C_BOOL, NULL, &lineconf.emumodem, 0 }, { "porttype", C_LIST, ptypelst,&lineconf.porttype, 0 }, { "authtype", C_LIST, radlst, &lineconf.authtype, 0 }, { "radnullpass", C_BOOL, NULL, &lineconf.radnullpass, 0 }, #ifdef PORTSLAVE_TACACS { "tacauthhost1",C_HOST, NULL, &lineconf.tacauthhost1, 0 }, { "tacauthhost2",C_HOST, NULL, &lineconf.tacauthhost2, 0 }, #endif { "protocol", C_LIST, prlst, &lineconf.protocol, 0 }, { "host", C_HOST, NULL, &lineconf.host, 0 }, { "rem_host", C_IPDY, NULL, &lineconf.rem_host, 0 }, { "netmask", C_IPNO, NULL, &lineconf.netmask, 0 }, { "mtu", C_INT, NULL, &lineconf.mtu, 0 }, { "mru", C_INT, NULL, &lineconf.mru, 0 }, { "autoppp", C_STR, NULL, &lineconf.autoppp, 0 }, { "pppopt", C_STR, NULL, &lineconf.pppopt, 0 }, { "tty", C_DEV, NULL, &lineconf.tty, 0 }, { "issue", C_STR, NULL, &lineconf.issue, 0 }, { "prompt", C_STR, NULL, &lineconf.prompt, 0 }, { "term", C_STR, NULL, &lineconf.term, 0 }, { "speed", C_INT, NULL, &lineconf.speed, 0 }, { "socket_port", C_INDY, NULL, &lineconf.socket_port, 0 }, { "parity", C_LIST, paritylst,&lineconf.parity, 0}, { "stopbits", C_INT, NULL, &lineconf.stopbits, 0}, { "datasize", C_INT, NULL, &lineconf.datasize, 0}, { "dcd", C_BOOL, NULL, &lineconf.dcd, 0 }, { "flow", C_LIST, flowlst, &lineconf.flow, 0 }, { "initchat", C_CHAT, NULL, &lineconf.initchat, 0}, #ifdef FIDO { "fidonet", C_BOOL, NULL, &lineconf.fidonet, 0}, { "fidologin", C_STR, NULL, &lineconf.fidologin, 0}, { "fidopasswd", C_STR, NULL, &lineconf.fidopasswd, 0}, #endif #ifdef PORTSLAVE_CLIENT_IP_RULES { "valid_ip", C_STR, NULL, &lineconf.valid_ip, 0 }, #endif { "logpassword", C_REALM,NULL, &lineconf.logpassword, 0 }, { "fixedlogin", C_STR, NULL, &lineconf.fixedlogin, 0 }, { "do_acct", C_BOOL, NULL, &lineconf.do_acct, 0 }, #ifndef NO_CHAP { "allow_chap", C_BOOL, NULL, &lineconf.allow_chap, 0 }, #endif { "login_time", C_STR, NULL, &lineconf.login_time_str, 0 }, { "login_time_limited", C_BOOL, NULL, &lineconf.login_time_limited, 0 }, { NULL, 0, NULL, NULL, 0 } }; /* * Set an integer. */ static PARSE_RC setint(const char *val, void *ptr) { if(sscanf(val, "%d", (int *)ptr) != 1) return parseErr; return parseOK; } /* * Set a dynamic integer. */ static PARSE_RC setintdy(const char *val, void *ptr) { int n; if(sscanf(val, "%d", &n) != 1) return parseErr; if(val[strlen(val) - 1] == '+') n += GetPortNo(); *(int *)ptr = n; return parseOK; } /* Actually copy a string to the data structures, used by setstr() and setdev() * We own the data pointed to by val!!! */ static PARSE_RC real_setstr(char *val, void *ptr) { char **sptr; sptr =(char **)ptr; if(*sptr) free(*sptr); *sptr = val; return parseOK; } /* * Set a string. * do_unescape is a boolean, if set then we replace \n with a new line, \r with * CR, etc. */ static PARSE_RC setstr(const char *val, void *ptr, bool do_unescape) { char *myval = xstrdup(val); /* * Specialcase "" as the empty string. */ if(do_unescape) { unescape(myval); } else if (strcmp(myval, "\"\"") == 0) { free(myval); myval = xstrdup(""); } return real_setstr(myval, ptr); } /* Set a device name */ static PARSE_RC setdev(const char *val, void *ptr) { char *dev_name; if(strcmp(val, "\"\"") == 0) return parseErr; dev_name = check_device(val); if(!dev_name) { nsyslog(LOG_ERR, "Device \"%s\" doesn't exist.", val); return parseFatal; } return real_setstr(dev_name, ptr); } /* * Set a hostname. Return ipno. */ static PARSE_RC sethost(const char *val, void *ptr) { unsigned int n; struct hostent *h; if (val[0] == 0) { n = 0; } else { if ((int)(n = inet_addr(val)) == -1) { if((h = gethostbyname(val)) == NULL) { nsyslog(LOG_ERR, "Can't resolve host: %s", val); return parseFatal; } n = *(unsigned int *)h->h_addr_list[0]; } } *(unsigned int *)ptr = n; return parseOK; } /* * Set a hostname. Return ipno. * Modifies val. */ static PARSE_RC sethost_srv(char *val, void *ptr) { char *tmp = NULL; struct sockaddr **sptr_ptr = (struct sockaddr **)ptr; struct sockaddr_in *sptr = NULL; #ifdef HAVE_IPV6 struct sockaddr_in6 *sptr6 = NULL; #endif if(*val == '[') { val++; tmp = strchr(val, ']'); if(!tmp) return parseErr; *tmp = '\0'; tmp++; } if(*sptr_ptr) free(*sptr_ptr); if( (val[0] < '0' || val[0] > '9') #ifdef HAVE_IPV6 && !strchr(val, ':') #endif ) { struct hostent *h; #ifdef HAVE_IPV6 h = gethostbyname2(val, AF_INET6); if(h) { *sptr_ptr = xmalloc(sizeof(struct sockaddr_in6)); sptr6 = (struct sockaddr_in6*)*sptr_ptr; sptr6->sin6_family = AF_INET6; memcpy(&sptr6->sin6_addr, h->h_addr_list[0], sizeof(sptr6->sin6_addr) ); } else #endif { h = gethostbyname2(val, AF_INET); if(!h) return parseErr; *sptr_ptr = xmalloc(sizeof(struct sockaddr_in)); sptr = (struct sockaddr_in*)*sptr_ptr; sptr->sin_family = AF_INET; memcpy(&sptr->sin_addr, h->h_addr_list[0], sizeof(sptr->sin_addr) ); } } else { #ifdef HAVE_IPV6 if(strchr(val, ':')) { *sptr_ptr = xmalloc(sizeof(struct sockaddr_in6)); sptr6 = (struct sockaddr_in6*)*sptr_ptr; sptr6->sin6_family = AF_INET6; if(inet_pton(AF_INET6, val, &sptr6->sin6_addr) <= 0) return parseErr; } else #endif { *sptr_ptr = xmalloc(sizeof(struct sockaddr_in)); sptr = (struct sockaddr_in*)*sptr_ptr; sptr->sin_family = AF_INET; if(inet_pton(AF_INET, val, &sptr->sin_addr) <= 0) return parseErr; } } if(tmp) { unsigned short port_num; if(isdigit(tmp[0])) { port_num = htons(atoi(tmp)); } else { struct servent *svp = getservbyname(tmp, "udp"); if(!svp) return parseErr; port_num = svp->s_port; } #ifdef HAVE_IPV6 if(sptr6) sptr6->sin6_port = port_num; else #endif sptr->sin_port = port_num; } return parseOK; } /* * Set an IP address. */ static PARSE_RC setipno(const char *val, void *ptr) { unsigned int n; if((int)(n = inet_addr(val)) == -1 && strcmp(val, "255.255.255.255") != 0) return parseErr; *(unsigned int *)ptr = n; return parseOK; } /* * Set a dynamic IP address. * If the IP address ends in '+' then ip address is base + line num. */ static PARSE_RC setipdy(const char *val, void *ptr) { int len; unsigned int base_h, base; int dy = 0; int port; char *myval = xstrdup(val); port = GetPortNo(); len = strlen(myval); if(len > 0 && myval[len - 1] == '+') { dy = 1; myval[len - 1] = 0; } if((base = inet_addr(myval)) == INADDR_NONE && strcmp(myval, "255.255.255.255") != 0) { free(myval); return parseErr; } base_h = ntohl(base); /* base_h is base IP in host byte order */ if(port >= 0 && dy) base = htonl(base_h + port); *(unsigned int *)ptr = base; free(myval); return parseOK; } /* * Set an IPv6 address. */ static PARSE_RC setip6no(const char *val, void *ptr) { if(inet_pton(AF_INET6, val, ptr) <= 0) return parseErr; return parseOK; } /* * Set an integer, from a list of string values. */ static PARSE_RC setlist(const char *val, const struct lst *lst, void *ptr) { int n = 0, i; for(i = 0; lst[i].name; i++) { if(strcasecmp(val, lst[i].name) == 0) { n = lst[i].value; break; } } if(lst[i].name == NULL) return parseErr; *(int *)ptr = n; return parseOK; } static PARSE_RC setbool(const char *val, void *ptr) { if(!strcmp("0", val) || !strcmp("false", val) || !strcmp("no", val)) *(bool *)ptr = false; else if(!strcmp("1", val) || !strcmp("true", val) || !strcmp("yes", val)) *(bool *)ptr = true; else return parseErr; return parseOK; } /* if the word is "s1" and our port number is 1 then return 0. * if the word if "s{5-9} and our port number is s7 then return 2 (the index * into the list). * If the word is for another port then return -1. * If a parse error then return -2; * */ static int isLineForOurPort(const char *word, int *list_size) { int start, end; if(tolower(*word) != 's') return -2; word++; if(*word == '{') { if(2 != sscanf(word + 1, "%d-%d", &start, &end) || start >= end) return -2; } else { if( !(start = atoi(word)) && *word != '0') return -2; *list_size = 0; if(GetPortNo() == start) return 0; return -1; } if(start <= GetPortNo() && GetPortNo() <= end) { *list_size = end - start; return GetPortNo() - start; } return -1; } /* replaces a {start-end} string in the arguement with the list_index number. * writes over the same string data as the result will be shorter and the * caller is only going to strdup() it and free it afterwards. */ static int convert_argument(char *arg, int list_index, int list_size) { int start, end; char *argument, *end_ptr; argument = strchr(arg, '{'); end_ptr = strchr(arg, '}'); if(!argument && !end_ptr) return parseOK; if(!argument || !end_ptr) return parseErr; end_ptr++; if(2 != sscanf(argument + 1, "%d-%d", &start, &end) || start >= end) return parseErr; if(list_size != (end - start) || end <= start ) return parseErr; sprintf(argument, "%d", start + list_index); argument += strlen(argument); if(argument < end_ptr + 1 && *end_ptr != 0) memmove(argument, end_ptr, strlen(end_ptr) + 1); return parseOK; } /* * Parse one line from the configuration file. */ static PARSE_RC parseline(const char *line) { char *dup_line = xstrdup(line); char *s = dup_line; bool all_entry = false; char *word, *argument, *command; struct conf *x; int n = parseErr; int list_index = 0, list_size = 0; /* * Remove the trailing newline and spaces etc. */ for(word = s + strlen(s) - 1; isspace(*word) || *word == '\n' || *word == '\r'; word--) { *word = '\0'; if(word <= s) break; } /* * Get word, command and argument. */ while(isspace(*s)) s++; word = s; while(*s && !isspace(*s)) s++; if(*word == 0) { parseline_error: free(dup_line); return n; } if (*s) *s++ = 0; while(isspace(*s)) s++; argument = s; if((command = strchr(word, '.')) == NULL || command[1] == 0) goto parseline_error; *command++ = 0; /* * See what class of command this is. */ if(!strcasecmp(word, "conf") || !strcasecmp(word, "all")) { all_entry = true; } else { list_index = isLineForOurPort(word, &list_size); switch(list_index) { case -2: free(dup_line); return parseErr; case -1: free(dup_line); return parseOK; break; } } /* * Parse the line and fill in the right structure(s). */ for(x = line_cfg; x->name != NULL; x++) { if(strcasecmp(command, x->name) != 0) continue; /* if we are already set and this is an all entry then return OK */ if(x->really_set && all_entry) { free(dup_line); return parseOK; } if(x->type != C_STR && x->type != C_CHAT) { n = convert_argument(argument, list_index, list_size); if(n != parseOK) goto parseline_error; } x->really_set = 1; switch(x->type) { case C_INDY: n = setintdy(argument, x->ptr); break; case C_INT: n = setint(argument, x->ptr); break; case C_BOOL: n = setbool(argument, x->ptr); break; case C_STR: n = setstr(argument, x->ptr, true); break; case C_DEV: n = setdev(argument, x->ptr); break; case C_CHAT: n = setstr(argument, x->ptr, false); break; case C_HOST: n = sethost(argument, x->ptr); break; case C_HSRV: n = sethost_srv(argument, x->ptr); break; case C_LIST: n = setlist(argument, x->opts, x->ptr); break; case C_IPNO: n = setipno(argument, x->ptr); break; case C_IP6NO: n = setip6no(argument, x->ptr); break; case C_IPDY: n = setipdy(argument, x->ptr); break; default: n = parseFatal; break; } break; } if(x->name == NULL || n != parseOK) goto parseline_error; free(dup_line); return parseOK; } /* * Check if the line specifies the port we use */ static int check_portno(const char *buf, const char *tty) { int port; int rc = 0; char *dev; int start, end, list_size = 0; char *argument, *end_ptr; int i; if(buf[0] != 's') return -1; buf++; if(buf[0] == '{') { end_ptr = strstr(buf, "}."); if(!end_ptr) return -1; buf++; if(2 != sscanf(buf, "%d-%d", &port, &end) || port >= end) return -1; list_size = end - port; } else { if(strchr(buf, '{') || strchr(buf, '}') ) return -1; port = atoi(buf); if(port < 0) return -1; } buf = strchr(buf, '.'); if(!buf) return -1; if(!strncmp(buf, ".tty", 4)) buf += 4; else return -1; while(isspace(*buf)) buf++; if(list_size != 0) { argument = strchr(buf, '{'); end_ptr = strchr(buf, '}'); if(!argument || !end_ptr) return -1; end_ptr++; if(2 != sscanf(argument + 1, "%d-%d", &start, &end) || start >= end || list_size != (end - start) ) return -1; end_ptr = xstrdup(end_ptr); for(i = start; i <= end; i++) { sprintf(argument, "%d%s", start + i, end_ptr); dev = check_device(buf); if(dev && !strcmp(dev, tty)) { SetPortNo(port + i); rc = 0; free(dev); return 0; } } free(end_ptr); return -1; } dev = check_device(buf); if(!dev) return -1; if(strcmp(dev, tty)) rc = -1; else SetPortNo(port); free(dev); return rc; } /* * Read the configuration file. */ int readcfg(const char *config_file, const char *tty) { FILE *fp; char buf[2048]; int lineno = 0; char *s, *p; if(!tty) tty = ttyname(0); lineconf.tty = xstrdup(tty); if((fp = fopen(config_file, "r")) == NULL) { nsyslog(LOG_ERR, "%s: %m", config_file); return -1; } p = buf; if(GetPortNo() == RAD_INIT_PPPD) { const char *env_data = getenv("PORTSLAVE_PORT"); if(env_data) SetPortNo(atoi(env_data)); } if(GetPortNo() == RAD_INIT_PPPD) { while(fgets(p, sizeof(buf) - (p - buf), fp)) { if (p[0] == '#' || p[0] == '\n') continue; s = p + strlen(p); if (s > p && *--s == '\n' && *--s == '\\') { p = s; continue; } if (buf[0] == '\n' || buf[0] == 0) { p = buf; continue; } strtok(buf, "\r\n"); p = buf + strlen(buf) - 1; while(isspace(*p)) { *p = '\0'; p--; } if(!check_portno(buf, tty) ) break; p = buf; } if(GetPortNo() == RAD_INIT_PPPD) { fclose(fp); nsyslog(LOG_ERR, "Port %s not defined in %s.\n" , lineconf.tty, config_file); return -1; } /* reopen the log after setting the port */ nopenlog(NULL, LOG_NDELAY, 0); if(fseek(fp, 0, SEEK_SET)) { fclose(fp); nsyslog(LOG_ERR, "%s: seek error\n", config_file); return -1; } } p = buf; while(fgets(p, sizeof(buf) - (p - buf), fp)) { int rc; lineno++; if (p[0] == '#' || p[0] == '\n') continue; s = p + strlen(p); if (s > p && *--s == '\n' && *--s == '\\') { p = s; continue; } if (buf[0] == '\n' || buf[0] == 0) { p = buf; continue; } rc = parseline(buf); if(rc == parseFatal) { nsyslog(LOG_ERR, "%s[%d]: fatal parse error\n", config_file, lineno); fclose(fp); return -1; } if(rc < 0) nsyslog(LOG_WARNING, "%s[%d]: syntax error\n", config_file, lineno); p = buf; } fclose(fp); /* reopen the log after getting all the config data */ nopenlog(NULL, LOG_NDELAY, 0); if(lineconf.fixedlogin && !strlen(lineconf.fixedlogin)) { free(lineconf.fixedlogin); lineconf.fixedlogin = NULL; } if(lineconf.login_time_str) { set_login_times(lineconf.login_time_str); free(lineconf.login_time_str); lineconf.login_time_str = NULL; } return 0; } #define REPLACE_STR(Xdest, Xsrc) { if(Xdest) free(Xdest); Xdest = Xsrc; } /* * Initialize the configuration stuff with defaults. */ void initcfg(void) { struct hostent *h; char buf[256]; char telnet [] = PATH_TELNET; char ssh [] = PATH_SSH; char rlogin [] = PATH_RLOGIN; char pppd [] = PATH_PPP_RADIUS; gethostname(buf, sizeof(buf)); if(lineconf.hostname) free(lineconf.hostname); lineconf.hostname = xstrdup(buf); if(( h = gethostbyname(buf)) != NULL) lineconf.loc_host = *(unsigned int *)(h->h_addr); REPLACE_STR(lineconf.prompt, xstrdup("%h login: ")); lineconf.radnullpass = 1; REPLACE_STR(lineconf.utmpfrom, xstrdup("%p:%P.%3.%4")); lineconf.sysutmp = 1; lineconf.syswtmp = 1; setlist("ppp", prlst, &lineconf.protocol); if(strlen(telnet)) { REPLACE_STR(lineconf.telnet, xstrdup(telnet)); } if(strlen(ssh)) { REPLACE_STR(lineconf.ssh, xstrdup(ssh)); } if(strlen(rlogin)) { REPLACE_STR(lineconf.rlogin, xstrdup(rlogin)); } REPLACE_STR(lineconf.pppd, xstrdup(pppd)); REPLACE_STR(lineconf.lockdir, xstrdup("/var/lock")); REPLACE_STR(lineconf.term, xstrdup("vt100")); REPLACE_STR(lineconf.radclient_config_file, xstrdup(RADCLIENT_CFG)); lineconf.stripnames = 1; lineconf.debug = 0; setlist("none", paritylst, &lineconf.parity); lineconf.stopbits = 1; lineconf.datasize = 8; SetChatTimeout(10); SetChatSendDelay(1); } portslave-2010.04.19.1/src/radclient.c0000664000000000000000000005233210027271662014066 0ustar /* * radclient A client-side implementation of the RADIUS protocol. * * Version: @(#)radclient.c 1.43 08-Nov-1997 miquels@cistron.nl * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef NO_CHAP #include #ifdef CHAPMS #include #endif #endif #include "server.h" #include extern void radius_md5_calc(unsigned char *, unsigned char *, unsigned int); /* * This is an "attribute". */ typedef struct _attr_ { unsigned char type; unsigned char len; union { char str[254]; unsigned int num; } val; unsigned char pwtype; struct _attr_ *next; } ATTR; static int update_framed_route(const struct auth *ai, bool islogin); static int update_filter_id(const struct auth *ai, bool islogin); /* Add the basic data to an accounting or authorization packet */ static bool rad_add_base_data(VALUE_PAIR *pkt, const struct auth *ai) { /* * Now we finish off with the client id (our ip address), */ rc_avpair_add(&pkt, PW_NAS_PORT_TYPE, (void *)&ai->porttype, 0); /* * Add connection info on login AND logout. That's what * a portmaster does too.. */ if(ai->conn_info[0]) rc_avpair_add(&pkt, PW_CONNECT_INFO, (void *)ai->conn_info, 0); if(ai->cli_src[0]) rc_avpair_add(&pkt, PW_CALLING_STATION_ID, (void *)ai->cli_src, 0); if(ai->cli_dst[0]) rc_avpair_add(&pkt, PW_CALLED_STATION_ID, (void *)ai->cli_dst, 0); /* * We have to add a unique identifier, the same * for login as for logout. */ rc_avpair_add(&pkt, PW_ACCT_SESSION_ID, ai->acct_session_id, 0); return 0; } /* * Build an authentication request. */ static VALUE_PAIR *rad_buildauth(const struct auth *ai, int ppp) { VALUE_PAIR *pkt; UINT4 av_type; pkt = NULL; /* * Add the login name. */ rc_avpair_add(&pkt, PW_USER_NAME, (void *)ai->login, 0); if(ai->called_station) { rc_avpair_add(&pkt, PW_CALLED_STATION_ID, ai->called_station, 0); } if(ai->calling_station) { rc_avpair_add(&pkt, PW_CALLING_STATION_ID, ai->calling_station, 0); } if(rad_add_base_data(pkt, ai)) return NULL; /* * We add the protocol type if this is PPP. */ if(ppp) { av_type = htonl(PW_PPP); rc_avpair_add(&pkt, PW_FRAMED_PROTOCOL, &av_type, 0); av_type = htonl(PW_FRAMED); rc_avpair_add(&pkt, PW_SERVICE_TYPE, &av_type, 0); } return pkt; } /* * Build an accounting request. */ static VALUE_PAIR *rad_buildacct(const struct auth *ai, bool islogin) { int i, s, p, c; unsigned int h; VALUE_PAIR *pkt = NULL; UINT4 av_type; /* * Tell the server what kind of request this is. */ av_type = islogin ? PW_STATUS_START : PW_STATUS_STOP; rc_avpair_add(&pkt, PW_ACCT_STATUS_TYPE, &av_type, 0); /* * Add the login name. */ if(ai->login && ai->login[0]) rc_avpair_add(&pkt, PW_USER_NAME, (void *)ai->login, 0); if(rad_add_base_data(pkt, ai)) return NULL; if(!islogin) { /* * Add input and output octets. */ if(ai->traffic.sent_bytes || ai->traffic.recv_bytes) { rc_avpair_add(&pkt, PW_ACCT_OUTPUT_OCTETS, (void *)&ai->traffic.sent_bytes, 0); rc_avpair_add(&pkt, PW_ACCT_INPUT_OCTETS, (void *)&ai->traffic.recv_bytes, 0); } /* * Add input and output packets. */ if(ai->traffic.sent_pkts || ai->traffic.recv_pkts) { rc_avpair_add(&pkt, PW_ACCT_OUTPUT_PACKETS, (void *)&ai->traffic.sent_pkts, 0); rc_avpair_add(&pkt, PW_ACCT_INPUT_PACKETS, (void *)&ai->traffic.recv_pkts, 0); } } /* * Include session time if this is a logout. */ if(!islogin) { av_type = time(NULL) - ai->start; rc_avpair_add(&pkt, PW_ACCT_SESSION_TIME, &av_type, 0); } /* * We'll have to add some more fields here: * - service type * - login service * - framed protocol * - framed IP address * - framed compression * - login IP host * */ i = -1; s = -1; p = -1; c = -1; h = 0; switch(ai->proto) { case P_SHELL: s = PW_ADMINISTRATIVE; break; case P_TELNET: s = PW_LOGIN; i = PW_TELNET; h = ai->address; break; case P_RLOGIN: s = PW_LOGIN; i = PW_RLOGIN; h = ai->address; break; case P_SSH1: case P_SSH2: s = PW_LOGIN; i = PW_SSH; h = ai->address; break; case P_TCPCLEAR: case P_TCPLOGIN: s = PW_LOGIN; i = PW_TCP_CLEAR; h = ai->address; break; case P_PPP: case P_PPP_ONLY: case P_SLIP: case P_CSLIP: { unsigned long address = htonl(ai->address); s = PW_FRAMED; rc_avpair_add(&pkt, PW_FRAMED_IP_ADDRESS, &address, 0); } break; } switch(ai->proto) { case P_PPP: case P_PPP_ONLY: p = PW_PPP; c = PW_VAN_JACOBSON_TCP_IP; break; case P_SLIP: p = PW_SLIP; break; case P_CSLIP: p = PW_SLIP; c = PW_VAN_JACOBSON_TCP_IP; } if(s > 0) { av_type = s; rc_avpair_add(&pkt, PW_SERVICE_TYPE, &av_type, 0); } if(i >= 0) { av_type = i; rc_avpair_add(&pkt, PW_LOGIN_SERVICE, &av_type, 0); } if(p >= 0) { av_type = p; rc_avpair_add(&pkt, PW_FRAMED_PROTOCOL, &av_type, 0); } if(c >= 0) { av_type = c; rc_avpair_add(&pkt, PW_FRAMED_COMPRESSION, &av_type, 0); } if(h > 0) { rc_avpair_add(&pkt, PW_LOGIN_IP_HOST, &h, 0); } return pkt; } static void free_arrray(char **messages, int num) { int i; for(i = 0; i < num; i++) { if(messages[i]) free(messages[i]); messages[i] = NULL; } } /* * set environment variable name with a representation of the array val of * the number of strings represented by num */ int setenv_from_rad(const char *name, const char **val, unsigned int num) { unsigned int i; int size = 0; char *buf; int rc = 0; if(num == 0) return 0; for(i = 0; i < num; i++) size += strlen(val[i]); buf = xmalloc(size + num); for(i = 0; i < num; i++) { strcat(buf, val[i]); if(i != num - 1) strcat(buf, "#"); } if(setenv(name, buf, 1)) { nsyslog(LOG_ERR, "Can't set environment variable %s.", name); rc = -1; } free(buf); return rc; } /* * get data from environment variable name and put it in the array val of * the maximum number of strings represented by max, too many strings cause * an error. Puts the number of strings in num. */ int getenv_from_rad(const char *name, char **val, unsigned int max, unsigned int *num) { char *buf, *ptr, *next; *num = 0; buf = getenv(name); if(!buf) return 0; ptr = buf; next = buf; while(next) { if(*num >= max) { nsyslog(LOG_ERR, "Error extracting variable %s.", name); return -1; } next = strchr(ptr, '#'); if(!next) { val[*num] = xstrdup(ptr); } else { val[*num] = xmalloc(next - ptr + 1); memcpy(val[*num], ptr, next - ptr); val[*num][next - ptr] = '\0'; } (*num)++; ptr = next; } return 0; } void unpack_radius_auth_reply(const VALUE_PAIR * const received, struct auth *ai); /* * Ask a radius server to authenticate us, * * ppp parameter is whether the protocol is PPP. * for adding PPP attribute to packet */ int rad_client(struct auth *ai, bool ppp) { int ret; VALUE_PAIR *pkt, *received; int def_auth_port; struct servent *svp; int result; if((ai->passwd[0] == '\0') && (lineconf.radnullpass == 0)) return (-1); /* Get radauth port, or use default */ svp = getservbyname ("radius", "udp"); if(svp == NULL) def_auth_port = PW_AUTH_UDP_PORT; else def_auth_port = ntohs(svp->s_port); /* * Set the message to some error in case we fail. */ if(ai->message[0]) free(ai->message[0]); ai->message[0] = xmalloc(4096); ai->msn = 1; /* * First, build the request. */ if ((pkt = rad_buildauth(ai, ppp)) == NULL) return -1; if(lineconf.logpassword) nsyslog(LOG_DEBUG, "passwd: %s", ai->passwd); rc_avpair_add(&pkt, PW_USER_PASSWORD, (void *)ai->passwd, 0); result = rc_auth(GetPortNo(), pkt, &received, ai->message[0]); if(!ai->message[0][0]) { free(ai->message[0]); ai->message[0] = NULL; } /* free value pairs */ rc_avpair_free(pkt); ret = (result == OK_RC) ? 0 : -1; free_arrray(ai->message, MAX_RADIUS_MESSAGES); ai->msn = 0; free_arrray(ai->filterid, MAX_FILTERS); ai->fln = 0; unpack_radius_auth_reply(received, ai); if(ret == 0) { ai->start = time(NULL); } else { nsyslog(LOG_INFO, "authentication failed (%s/%s) %s", ai->login, ai->passwd, ai->message[0] ? ai->message[0] : ""); } /* free value pairs */ rc_avpair_free(received); return ret; } #ifndef NO_CHAP int rad_client_chap(struct auth *ai, u_char *remmd, chap_state *cstate) { int ret = CHAP_SUCCESS; VALUE_PAIR *pkt, *received; int def_auth_port; struct servent *svp; int result; char cpassword[MAX_RESPONSE_LENGTH + 1]; /* if((ai->passwd[0] == '\0') && (lineconf.radnullpass == 0)) return CHAP_FAILURE; */ /* Get radauth port, or use default */ svp = getservbyname ("radius", "udp"); if(svp == NULL) def_auth_port = PW_AUTH_UDP_PORT; else def_auth_port = ntohs(svp->s_port); /* * Set the message to some error in case we fail. */ if(ai->message[0]) free(ai->message[0]); ai->message[0] = xmalloc(4096); ai->msn = 1; /* * First, build the request. */ if ((pkt = rad_buildauth(ai, 1)) == NULL) return CHAP_FAILURE; /* for PAP we optionally log the password here, for CHAP we can't */ /* * add the challenge and response fields */ switch (cstate->chal_type) { case CHAP_DIGEST_MD5: /* CHAP-Challenge and CHAP-Password */ cpassword[0] = cstate->chal_id; memcpy(&cpassword[1], remmd, MD5_SIGNATURE_SIZE); rc_avpair_add(&pkt, PW_CHAP_CHALLENGE, cstate->challenge, cstate->chal_len); rc_avpair_add(&pkt, PW_CHAP_PASSWORD, cpassword, MD5_SIGNATURE_SIZE + 1); break; #ifdef CHAPMS case CHAP_MICROSOFT: { /* MS-CHAP-Challenge and MS-CHAP-Response */ MS_ChapResponse *rmd = (MS_ChapResponse *) remmd; u_char *p = cpassword; *p++ = cstate->chal_id; /* The idiots use a different field order in RADIUS than PPP */ memcpy(p, rmd->UseNT, sizeof(rmd->UseNT)); p += sizeof(rmd->UseNT); memcpy(p, rmd->LANManResp, sizeof(rmd->LANManResp)); p += sizeof(rmd->LANManResp); memcpy(p, rmd->NTResp, sizeof(rmd->NTResp)); rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE, cstate->challenge, cstate->chal_len, VENDOR_MICROSOFT); rc_avpair_add(&send, PW_MS_CHAP_RESPONSE, cpassword, MS_CHAP_RESPONSE_LEN + 1, VENDOR_MICROSOFT); } break; case CHAP_MICROSOFT_V2: { /* MS-CHAP-Challenge and MS-CHAP2-Response */ MS_Chap2Response *rmd = (MS_Chap2Response *) remmd; u_char *p = cpassword; *p++ = cstate->chal_id; /* The idiots use a different field order in RADIUS than PPP */ memcpy(p, rmd->Flags, sizeof(rmd->Flags)); p += sizeof(rmd->Flags); memcpy(p, rmd->PeerChallenge, sizeof(rmd->PeerChallenge)); p += sizeof(rmd->PeerChallenge); memcpy(p, rmd->Reserved, sizeof(rmd->Reserved)); p += sizeof(rmd->Reserved); memcpy(p, rmd->NTResp, sizeof(rmd->NTResp)); rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE, cstate->challenge, cstate->chal_len, VENDOR_MICROSOFT); rc_avpair_add(&send, PW_MS_CHAP2_RESPONSE, cpassword, MS_CHAP2_RESPONSE_LEN + 1, VENDOR_MICROSOFT); } break; #endif } result = rc_auth(GetPortNo(), pkt, &received, ai->message[0]); if(!ai->message[0][0]) { free(ai->message[0]); ai->message[0] = NULL; } /* free value pairs */ rc_avpair_free(pkt); if(result != OK_RC) ret = CHAP_FAILURE; free_arrray(ai->message, MAX_RADIUS_MESSAGES); ai->msn = 0; free_arrray(ai->filterid, MAX_FILTERS); ai->fln = 0; if(!ai->done_chap_once && ret == CHAP_SUCCESS) { unpack_radius_auth_reply(received, ai); ai->start = time(NULL); } else { nsyslog(LOG_INFO, "authentication failed (%s/CHAP) %s", ai->login, ai->message[0] ? ai->message[0] : ""); } /* free value pairs */ rc_avpair_free(received); return ret; } #endif void unpack_radius_auth_reply(const VALUE_PAIR * const received, struct auth *ai) { bool islogin = false; bool isframed = false; const VALUE_PAIR *ptr; int oldproto = ai->proto; ai->proto = 0; /* * Put the reply into our auth struct. */ for(ptr = received; ptr; ptr = ptr->next) { /* if (ptr->type == 0) break; */ switch(ptr->attribute) { case PW_SERVICE_TYPE: /* Framed or login. */ switch(ptr->lvalue) { case PW_ADMINISTRATIVE: ai->proto = P_SHELL; break; case PW_LOGIN: islogin = true; break; case PW_FRAMED: isframed = true; break; default: break; } break; case PW_LOGIN_SERVICE: islogin = true; switch(ptr->lvalue) { case PW_TELNET: ai->proto = P_TELNET; break; case PW_RLOGIN: ai->proto = P_RLOGIN; break; case PW_SSH: ai->proto = P_SSH1; break; case PW_TCP_CLEAR: ai->proto = P_TCPCLEAR; break; case PW_PORTMASTER: default: islogin = false; /* Unknown to us. */ break; } break; case PW_LOGIN_IP_HOST: ai->host = ntohl(ptr->lvalue); break; #ifdef HAVE_IPV6 case PW_LOGIN_IPV6_HOST: ai->host = ntohl(ptr->lvalue); break; #endif case PW_LOGIN_PORT: ai->loginport = ptr->lvalue; break; case PW_PORT_LIMIT: ai->port_limit = ptr->lvalue; break; case PW_FRAMED_IP_ADDRESS: isframed = true; if((unsigned)ntohl(ptr->lvalue) != 0xFFFFFFFE) ai->address = ntohl(ptr->lvalue); break; case PW_FRAMED_IP_NETMASK: ai->netmask = ntohl(ptr->lvalue); break; case PW_FRAMED_MTU: ai->mtu = ptr->lvalue; break; case PW_IDLE_TIMEOUT: ai->idletime = ptr->lvalue; break; case PW_SESSION_TIMEOUT: ai->sessiontime = ptr->lvalue; break; case PW_FRAMED_COMPRESSION: if(ptr->lvalue != PW_VAN_JACOBSON_TCP_IP) break; if (ai->proto == 0 || ai->proto == P_SLIP) ai->proto = P_CSLIP; break; case PW_FRAMED_PROTOCOL: isframed = true; if(ptr->lvalue == PW_PPP) ai->proto = P_PPP; else if (ai->proto == 0) ai->proto = P_SLIP; break; case PW_FILTER_ID: if(ai->fln > MAX_FILTERS) break; ai->filterid[ai->fln] = xstrdup(ptr->strvalue); ai->fln++; break; case PW_FRAMED_ROUTE: if(ai->frn >= MAX_FRAMED_ROUTES) break; ai->framed_route[ai->frn] = xstrdup(ptr->strvalue); ai->frn++; break; case PW_REPLY_MESSAGE: if(ai->msn >= MAX_RADIUS_MESSAGES) break; ai->message[ai->msn] = xstrdup(ptr->strvalue); ai->msn++; break; #ifdef PORTSLAVE_CALLBACK case PW_CALLBACK_NUMBER: ai->cb_allowed = (1 << CB_CONF_ADMIN); ai->cb_number = xmalloc(len + 1); memcpy(ai->cb_number,a_val,len); ai->cb_number[len] = 0; break; case PW_VENDOR_SPECIFIC: len = a_len; if(len > 6) { unsigned long lvalue; unsigned long vid; char *attr; memcpy(&lvalue, a_val, 4); vid = ntohl(lvalue); if(vid == 9) { /* Cisco */ if(((int)a_val[4] == 1) && ((int)a_val[5] >= 24) ) { unsigned int vlen=(int)a_val[5]; if(strncmp(&a_val[6],"lcp:callback-dialstring",24) == 0) { if(vlen==24) { /* empty string, user defined */ ai->cb_allowed = (1 << CB_CONF_USER); } else { /* admin defined number */ ai->cb_allowed = (1 << CB_CONF_ADMIN); ai->cb_number = xmalloc(vlen-24+1); memcpy(ai->cb_number,&a_val[30],vlen-24); ai->cb_number[vlen-24]=0; } } } } } break; #endif } } if(isframed && ai->address == 0 && lineconf.rem_host) ai->address = lineconf.rem_host; if(islogin && ai->address == 0 && lineconf.host) ai->address = lineconf.host; if(ai->proto == 0) ai->proto = oldproto; } /* * Send accounting info to a RADIUS server. */ static int real_rad_acct(const struct auth *ai, bool islogin) { VALUE_PAIR *pkt; int result; /* * Update utmp/wtmp (ctlportslave) */ update_utmp(lineconf.stripnames ? "%L" : "%l", lineconf.utmpfrom, ai, lineconf.syswtmp); /* * Update Framed-Routes */ update_framed_route(ai, islogin); /* * Run filter backend */ update_filter_id(ai, islogin); /* * First, build the request. */ if((pkt = rad_buildacct(ai, islogin)) == NULL) return -1; result = rc_acct(GetPortNo(), pkt); if(result != OK_RC) { /* RADIUS server could be down so make this a warning */ syslog(LOG_WARNING, "Accounting STOP failed for %s", ai->login); } rc_avpair_free(pkt); return 0; } int rad_acct(const struct auth *ai, bool islogin) { int rc; if(!ai->do_acct) return 0; /* * While messing around with accounting, we have to * block, but not ignore, SIGHUP and friends. */ block(SIGHUP); block(SIGTERM); rc = real_rad_acct(ai, islogin); unblock(SIGTERM); unblock(SIGHUP); return rc; } /* * Invoke 'route' command to update "Framed-Route". */ static int update_framed_route(const struct auth *ai, bool islogin) { char cmd[1024], *buf = NULL; char *net, *gw, *metric; const char *net_or_host; int x, rc; if(ai->frn == 0) return 0; if(islogin) { nsyslog(LOG_INFO, "Adding routes: %d.", ai->frn); x = 0; } else { nsyslog(LOG_INFO, "Deleting routes: %d.", ai->frn); x = ai->frn - 1; } while(x < (int)ai->frn && x >= 0) { if(buf) free(buf); buf = xstrdup(ai->framed_route[x]); net = strtok (buf, " "); if(strlen(net) > 3 && !strcmp("/32", &net[strlen(net) - 3])) { net_or_host = "-host"; net[strlen(net) - 3] = '\0'; } else { net_or_host = "-net"; } gw = strtok ((char *) 0, " "); if(!gw || !strcmp(gw, "0.0.0.0")) gw = xstrdup(dotted(ai->address)); else gw = xstrdup(gw); metric = strtok ((char *) 0, " "); if(metric) { snprintf(cmd, sizeof(cmd) - 1, "exec %s %s %s %s gw %s metric %s >/dev/null 2>&1", PATH_ROUTE, islogin ? "add" : "del", net_or_host, net, gw, metric); } else { snprintf(cmd, sizeof(cmd) - 1, "exec %s %s %s %s gw %s >/dev/null 2>&1", PATH_ROUTE, islogin ? "add" : "del", net_or_host, net, gw); } free(gw); rc = system(cmd); if(rc) nsyslog(LOG_ERR, "Command \"%s\" returned %d", cmd, rc); islogin ? x++ : x--; /* FIFO add, LIFO del */ } if(buf) free(buf); return 0; } static void alrm_hand() { } /* * Invoke the filter script defined by "Framed-Filter-Id". */ static int update_filter_id(const struct auth *ai, bool islogin) { int x; if(ai->fln == 0) return 0; if(islogin) { nsyslog(LOG_INFO, "Starting filters: %d.", ai->fln); x = 0; } else { nsyslog(LOG_INFO, "Stopping filters: %d.", ai->fln); x = ai->fln - 1; } /* Format: path/script */ while(x < (int)ai->fln && x >= 0) { if(strstr(ai->filterid[x], "..")) { nsyslog(LOG_ERR, "Filter name %s is invalid."); } else { pid_t rc = fork(); if(rc == -1) { nsyslog(LOG_ERR, "Can't fork for filter: %m"); return 1; } if(rc) /* parent */ { signal(SIGALRM, alrm_hand); alarm(2); wait(NULL); alarm(0); } else /* child */ { const char *args[10]; char *buf = xmalloc(strlen(lineconf.filterdir) + strlen(ai->filterid[x]) + 2); int fd = open("/dev/null", O_RDWR); if(fd == -1) { nsyslog(LOG_ERR, "can't open /dev/null: %m"); exit(1); } dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if(fd > 2) close(fd); sprintf(buf, "%s/%s", lineconf.filterdir, ai->filterid[x]); args[0] = buf; args[1] = islogin ? "start" : "stop"; args[2] = xstrdup(dotted(ai->address)); args[3] = xstrdup(dotted(ai->localip)); args[4] = xstrdup(dotted(ai->netmask)); args[5] = NULL; execv(args[0], (char **)args); nsyslog(LOG_ERR, "%s: %m", args[0]); exit(1); } } islogin ? x++ : x--; /* FIFO add, LIFO del */ } return 0; } portslave-2010.04.19.1/src/rwconf.h0000664000000000000000000000357410027271707013430 0ustar /* * rwconf.h Definitions for the configuration stuff in conf.c. * You cannot set any compile-time directives here. * * Version: @(#)rwconf.h 1.10 14-Oct-1996 miquels@cistron.nl * */ #ifndef __rwconf_h #define __rwconf_h struct time_ent { int days; int start_time; int end_time; }; /* * Configuration, per line. */ struct line_cfg { char *hostname; char *radclient_config_file; unsigned int loc_host; #ifdef HAVE_IPV6 struct in6_addr loc_host6; bool use_v6; #endif char *lockdir; char *rlogin; char *telnet; char *ssh; char *pppd; unsigned int syslog; int facility; char *filterdir; /* Networking options */ int authtype; #ifdef PORTSLAVE_TACACS struct sockaddr *tacauthhost1; struct sockaddr *tacauthhost2; #endif char *utmpfrom; int protocol; int host; unsigned int rem_host; unsigned int netmask; int mtu, mru; char *autoppp; char *pppopt; char *tty; /* Other options */ char *issue; char *prompt; char *term; #ifdef FIDO bool fidonet; /* Do we allow fidonet? */ char *fidologin; /* The login name for the sole fido user */ char *fidopasswd; /* Fido password */ #endif /* Modem options */ int flow; bool dcd; int speed; int socket_port; int parity; int stopbits; int datasize; int debug; int porttype; char *initchat; #ifdef PORTSLAVE_CLIENT_IP_RULES char *valid_ip; #endif char *fixedlogin; char *lockfile; /* Internal use only */ bool emumodem; bool logpassword; bool locallogins; bool stripnames; bool radnullpass; bool sysutmp; bool syswtmp; bool do_acct; #ifndef NO_CHAP bool allow_chap; #endif char *login_time_str; struct time_ent *login_time; bool login_time_limited; } lineconf; /* * Flow control definitions. */ #define FLOW_NONE 0 #define FLOW_HARD 1 #define FLOW_SOFT 2 /* * Functions. */ void initcfg(void); int readcfg(const char *config_file, const char *tty); int writecfg(void); #endif /* __rwconf_h */ portslave-2010.04.19.1/src/main.c0000664000000000000000000001523511352105751013043 0ustar /* * main.c Main part of the portslave. * * Version: @(#)main.c 1.35 08-Nov-1997 MvS. * */ #include #include #include #include #include #include #include #include #include #include "server.h" static void usage() { nsyslog(LOG_ERR, "Usage: portslave port|-\n"); fprintf(stderr, "Portslave RADIUS client v%s\tGPL2\n" "(c) 1997-1999 Miquel van Smoorenburg, " "Dave Cinege, Vesselin Atanasov, et al.\n" "(c) 2000-2002 Russell Coker et al.\n\n" "Usage: portslave port|-\n", PORTSLAVE_VERSION); exit(1); } /* * Main loop for 1 login channel. */ int main(int argc, char **argv) { /* ai: structure that holds basically all data on the session, user-name, password, port number, IP address, MTU/MRU, etc tty: the device that is standard input i: usual loop counter rc: return code from system calls */ struct auth ai; char *tty = NULL; int i, rc = 0; /* do_acct: if we should do accounting in the main portslave program. printed: Whether we have displayed some text, in which case we wait 2 seconds is_ppp: true if the protocol to use is PPP */ bool do_acct = false; bool printed = false; bool is_ppp = false; char *param = argv[1]; const char *config_file = CONFFILE; /* * Check the syntax. */ if(argc < 2) usage(); if(argv[1][0] == '+') { if(argv[1][1]) { config_file = &argv[1][1]; param = argv[2]; } else { config_file = argv[2]; param = argv[3]; } } if(param[0] != '-') { int port_num = atoi(param); if(port_num == 0 && param[0] != '0') usage(); SetPortNo(port_num); } else { SetPortNo(RAD_INIT_PPPD); tty = ttyname(0); if (tty == NULL) { fprintf(stderr, "portslave: standard input is not a tty\n"); exit(1); } } /* set the environment variable if using non-default file */ if(strcmp(config_file, CONFFILE)) setenv("PORTSLAVE_CONF", config_file, 1); /* * Read the config file. */ if(rad_init(config_file, GetPortNo(), &ai, tty) < 0) return 1; if(lineconf.tty == NULL) { nsyslog(LOG_ERR, "port %d has no tty defined", GetPortNo()); exit(1); } nsyslog(LOG_INFO, "portslave started on port %d (%s)", GetPortNo(), lineconf.tty); if(ai.proto == P_SOCKET_SERVER) goto socket_srv; /* * Now put a getty on the port. */ if(lineconf.emumodem) rc = emumodem(&ai, eLocModem); else rc = getty(&ai, eLocModem); if(rc < 0) exit(1); if(lineconf.protocol == P_PPP_ONLY) goto socket_srv; nsyslog(LOG_INFO, "Connected - waiting for login"); /* * Do login/password if needed. */ if(lineconf.authtype) { for(i = 0; i < 3; i++) { rc = 0; if(lineconf.fixedlogin) { strncpy(ai.login, lineconf.fixedlogin, sizeof(ai.login)); ai.login[sizeof(ai.login) - 1] = '\0'; } else { rc = do_login(&ai); } if (rc == 2) continue; if (rc < 0) exit(1); do_acct = false; /* * Do authentication if needed. */ if(lineconf.locallogins && ai.login[0] == '!') { memmove(ai.login, ai.login+1, strlen(ai.login)); ai.passwd[0] = '\0'; ai.proto = P_LOCAL; break; } if(!strcmp(ai.login, "AutoPPP")) { ai.proto = P_AUTOPPP; break; } if(ai.proto == P_PPP) is_ppp = true; else do_acct = true; #ifdef FIDO /* This is bad - we should support multiple login names for fido - what if you are a NC or RC and you want to use Portslave??? */ if(!strcmp(ai.login, lineconf.fidologin)) { ai.proto = P_RLOGIN; is_ppp = false; do_acct = true; } #endif if(lineconf.fixedlogin) break; if(!do_local_or_server_authentication(&ai, is_ppp)) break; } if(i == 3) { /* * 3 login failures - exit! */ printf("Authentication failure - exiting\r\n"); fflush(stdout); xusleep(250000); maketermsane(); exit(1); } setenv("LOGNAME", ai.login, 1); if(do_acct) rad_acct(&ai, 1); } /* * Okay, we are logged in here (or authentication comes later). */ if(ai.message[0]) { unsigned int x; for(x = 0; x < ai.msn; x++) printf("%s\r\n", ai.message[x]); printed = true; } socket_srv: switch(ai.proto) { case P_AUTOPPP: nsyslog(LOG_INFO, "PPP frames detected - switching to PPP mode"); break; case P_SLIP: nsyslog(LOG_INFO, "%s/SLIP session (%s)", ai.login, dotted(ai.address)); break; case P_CSLIP: nsyslog(LOG_INFO, "%s/CSLIP session (%s)", ai.login, dotted(ai.address)); break; case P_PPP: case P_PPP_ONLY: if(ai.login && strcmp(ai.login, "NONE")) nsyslog(LOG_INFO, "%s/PPP session (%s)", ai.login, dotted(ai.address)); else nsyslog(LOG_INFO, "PPP session (%s)", dotted(ai.address)); break; case P_SSH1: if(!ai.host) ai.host = lineconf.host; nsyslog(LOG_INFO, "%s/ssh session (%s)", ai.login, dotted(ai.host)); break; case P_SSH2: if(!ai.host) ai.host = lineconf.host; nsyslog(LOG_INFO, "%s/ssh2 session (%s)", ai.login, dotted(ai.host)); break; case P_TELNET: if(!ai.host) ai.host = lineconf.host; nsyslog(LOG_INFO, "%s/telnet to %s", ai.login, dotted(ai.host)); break; case P_RLOGIN: if(!ai.host) ai.host = lineconf.host; nsyslog(LOG_INFO, "%s/rlogin to %s", ai.login, dotted(ai.host)); break; case P_SOCKET_SERVER: nsyslog(LOG_INFO, "socket server %d", GetPortNo()); break; case P_SOCKET_CLIENT: nsyslog(LOG_INFO, "socket client %d", GetPortNo()); break; case P_LOCAL: nsyslog(LOG_INFO, "%s/locallogin", ai.login); break; default: nsyslog(LOG_INFO, "%s/type %c starting", ai.login, ai.proto); break; } /* * Print a portmaster compatible SLIP/PPP banner. */ if (strchr("PCS", ai.proto)) { printf("%s session from (%s) ", ai.proto == 'P' ? "PPP" : "SLIP", dotted(lineconf.loc_host)); printf("to %s beginning....\n", dotted(ai.address)); printed = true; } /* * Wait for output to drain. */ fflush(stdout); if(printed) xsleep(1); tcdrain(1); /* * Start the protocol. */ rc = spawnit(&ai); /* * If the protocol returned, tell the accounting server we're done. */ if(do_acct) rad_acct(&ai, 0); if (ai.proto != P_PPP) nsyslog(LOG_INFO, "Session done."); return (rc == 0 ? 0 : 1); } portslave-2010.04.19.1/src/md5.c0000664000000000000000000002452307411406237012610 0ustar /* 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); \ } void 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; } portslave-2010.04.19.1/src/libpsr.c0000664000000000000000000002605510027273776013427 0ustar /* * libpsr.c LibPortSlaveRadius. * Shared library to be linked with pppd * Takes care of the portslave side of things. * * Version @(#)libpsr.c 1.03 09-Jan-1998 miquels@cistron.nl * */ #include #include #include #include #include #ifndef NO_CHAP #include #ifdef CHAPMS #include #endif #endif #include #include #include #include "server.h" /* Version string for pppd so it knows that we were compiled with the right header files */ char pppd_version[] = VERSION; /* thisauth is the struct that has all details of the user account in use */ static struct auth thisauth; /* rad_using_pap is a boolean determining if user does PAP */ static int rad_using_pap; int pap_check(); #ifndef NO_CHAP int chap_check(); #endif int ul_pap_login(char *User, char *Passwd, char **unused , struct wordlist **addrs, struct wordlist **opts); #ifndef NO_CHAP int ul_chap_login(char *User, u_char *remmd, int remmd_len, chap_state *cstate); #endif void ul_ppp_ipup(void); void ul_ppp_ipdown(void); void rad_make_wordlist(u_int32_t, struct wordlist **); #ifdef PORTSLAVE_CLIENT_IP_RULES void rad_make_wordlist2 (char * const *, int, struct wordlist **); #endif #ifdef PORTSLAVE_CALLBACK void ul_cbcp_init(cbcp_state *); #endif int radius_allowed_address(u_int32_t addr); int plugin_init(void) { const char *env_data; const char *config = getenv("PORTSLAVE_CONF"); if(!config) config = CONFFILE; if(rad_init(config, RAD_INIT_PPPD, &thisauth, ttyname(0)) < 0) { nsyslog(LOG_ERR, "libpsr plugin init failed!"); exit(1); } env_data = getenv("PORTSLAVELOGNAME"); if(!env_data) { nsyslog(LOG_ERR, "Bad environment, exit"); exit(1); } if(strlen(env_data) == 4 && strncmp(env_data,"NONE",4) == 0){ /* we start session for PPP only without auth */ if(ipparam != NULL) { /* try get login name from ipparam */ snprintf(thisauth.login, sizeof (thisauth.login), "%s", ipparam); } else { snprintf(thisauth.login, sizeof (thisauth.login), "%s", env_data); } } else { snprintf(thisauth.login, sizeof (thisauth.login), "%s", env_data); } update_utmp(lineconf.stripnames ? "%L" : "%l", lineconf.utmpfrom, &thisauth, lineconf.syswtmp); nopenlog(NULL, LOG_CONS|LOG_NDELAY, 0); pap_check_hook = pap_check; pap_auth_hook = ul_pap_login; #ifndef NO_CHAP chap_check_hook = chap_check; chap_auth_hook = ul_chap_login; #endif ip_up_hook = ul_ppp_ipup; ip_down_hook = ul_ppp_ipdown; #ifdef PORTSLAVE_CALLBACK cbcp_init_hook = ul_cbcp_init; #endif #ifdef PORTSLAVE_CLIENT_IP_RULES thisauth.valid_ip_rules = (char **) NULL; thisauth.num_ip_rules = 0; #endif rad_using_pap = 0; env_data = getenv("PORTSLAVE_SESSION"); if(!env_data) { nsyslog(LOG_ERR, "Bad environment, exit"); exit(1); } thisauth.acct_session_id = xstrdup(env_data); env_data = getenv("PORTSLAVE_START_TIME"); if(!env_data) { nsyslog(LOG_ERR, "Bad environment, exit"); exit(1); } thisauth.start = atoi(env_data); env_data = getenv("PORTSLAVE_CLI_SRC"); if(env_data) { strncpy(thisauth.cli_src, env_data, sizeof(thisauth.cli_src)); thisauth.cli_src[sizeof(thisauth.cli_src) - 1] = '\0'; } env_data = getenv("PORTSLAVE_CLI_DST"); if(env_data) { strncpy(thisauth.cli_dst, env_data, sizeof(thisauth.cli_dst)); thisauth.cli_dst[sizeof(thisauth.cli_dst) - 1] = '\0'; } if((env_data = getenv("CONNECT_INFO")) != NULL) { strncpy(thisauth.conn_info, env_data, sizeof(thisauth.conn_info)); thisauth.conn_info[sizeof(thisauth.conn_info) - 1] = '\0'; } #ifdef PORTSLAVE_CALLBACK thisauth.cb_allowed = 0; thisauth.cb_number = NULL; #endif return 0; } int pap_check() { return 1; /* always allow PAP */ } int ul_pap_login(char *User, char *Passwd, char **unused , struct wordlist **addrs, struct wordlist **opts) { char tmp[255]; #ifdef ALLOW_NO_LOCAL_IP bool set_ip_f; #endif /* don't use allowed_address_hook for PAP */ allowed_address_hook = NULL; snprintf(thisauth.login, sizeof (thisauth.login), "%s", User); snprintf(thisauth.passwd, sizeof (thisauth.passwd), "%s", Passwd); if(do_local_or_server_authentication(&thisauth, 1)) return 0; if(thisauth.proto == P_PPP_ONLY) return 0; if(thisauth.netmask && thisauth.netmask != 0xFFFFFFFF) netmask = thisauth.netmask; if(thisauth.mtu) lcp_allowoptions[0].mru = thisauth.mtu; if(thisauth.mru) { lcp_wantoptions[0].mru = thisauth.mru; lcp_wantoptions[0].neg_mru = 1; } #ifdef ALLOW_NO_LOCAL_IP if(thisauth.localip != 0xFFFFFFFF) { set_ip_f = true; strcpy(tmp, dotted(thisauth.localip)); strcat(tmp, ":"); } else { set_ip_f = false; tmp[0] = ':'; } #else strcpy(tmp, dotted(thisauth.localip)); strcat(tmp, ":"); #endif /* If an IP address was set, use it as the valid address. */ if(thisauth.address != 0xFFFFFFFF) { #ifdef ALLOW_NO_LOCAL_IP set_ip_f = true; #endif strcat(tmp, dotted (thisauth.address)); rad_make_wordlist (thisauth.address, addrs); } else { #ifdef PORTSLAVE_CLIENT_IP_RULES /* Return the list of IP rules, if any were */ /* specified, in a word list. Otherwise, */ /* just return NULL which means the auth */ /* of the address will fail (pppd 2.4.0). */ if(thisauth.num_ip_rules > 0) rad_make_wordlist2(thisauth.valid_ip_rules, thisauth.num_ip_rules, addrs); else *addrs = NULL; #else *addrs = NULL; #endif } #ifdef ALLOW_NO_LOCAL_IP if(set_ip_f) { #endif if(setipaddr(tmp, NULL, 1) < 0) { nsyslog(LOG_ERR, "bad IP address %s", tmp); return 0; } #ifdef ALLOW_NO_LOCAL_IP } #endif *opts = NULL; if(thisauth.idletime > 0) idle_time_limit = thisauth.idletime; maxconnect = get_sessiontime(&thisauth); setenv("LOGNAME", User, 1); update_utmp(lineconf.stripnames ? "%L" : "%l", lineconf.utmpfrom, &thisauth, lineconf.syswtmp); rad_using_pap = 1; nsyslog(LOG_NOTICE, "user %s logged in", User); return 1; } #ifndef NO_CHAP int chap_check() { /* Only RADIUS works with CHAP */ switch(lineconf.authtype) { case AUTH_LOCAL: case AUTH_TACACS: case AUTH_TACACS_LOCAL: case AUTH_LOCAL_TACACS: return 0; } return 1; } #endif int radius_allowed_address(u_int32_t addr) { if(thisauth.address != 0xFFFFFFFF && thisauth.address != addr) return 0; /* fail */ return 1; /* success */ } #ifndef NO_CHAP int ul_chap_login(char *User, u_char *remmd, int unused, chap_state *cstate) { char tmp[255]; /* return error for types we can't handle */ if((cstate->chal_type != CHAP_DIGEST_MD5) #ifdef CHAPMS && (cstate->chal_type != CHAP_MICROSOFT) && (cstate->chal_type != CHAP_MICROSOFT_V2) #endif ) { nsyslog(LOG_NOTICE, "CHAP type %u unsupported", cstate->chal_type); return CHAP_FAILURE; } /* use allowed_address_hook for CHAP */ allowed_address_hook = radius_allowed_address; snprintf(thisauth.login, sizeof (thisauth.login), "%s", User); if(do_chap_authentication(&thisauth, remmd, cstate) == CHAP_FAILURE) return CHAP_FAILURE; /* Check if(done_chap_once > 1) because it's incremented inside do_chap_authentication() */ if(thisauth.done_chap_once > 1) return CHAP_SUCCESS; if(thisauth.proto == P_PPP_ONLY) return CHAP_FAILURE; if(thisauth.netmask && thisauth.netmask != 0xFFFFFFFF) netmask = thisauth.netmask; if(thisauth.mtu) lcp_allowoptions[0].mru = thisauth.mtu; if(thisauth.mru) { lcp_wantoptions[0].mru = thisauth.mru; lcp_wantoptions[0].neg_mru = 1; } #ifdef ALLOW_NO_LOCAL_IP if(thisauth.localip == 0xFFFFFFFF) { strcpy(tmp, ":"); } else #endif { strcpy(tmp, dotted(thisauth.localip)); strcat(tmp, ":"); } strcat(tmp, dotted (thisauth.address)); #ifdef ALLOW_NO_LOCAL_IP if(!strcmp(tmp, ":")) { #endif if(setipaddr(tmp, NULL, 1) < 0) { nsyslog(LOG_ERR, "bad IP address %s", tmp); return CHAP_FAILURE; } #ifdef ALLOW_NO_LOCAL_IP } #endif if(thisauth.idletime > 0) idle_time_limit = thisauth.idletime; maxconnect = get_sessiontime(&thisauth); setenv("LOGNAME", User, 1); update_utmp(lineconf.stripnames ? "%L" : "%l", lineconf.utmpfrom, &thisauth, lineconf.syswtmp); rad_using_pap = 1; nsyslog(LOG_NOTICE, "user %s logged in", User); return CHAP_SUCCESS; } #endif void ul_ppp_ipdown() { thisauth.traffic.sent_bytes = link_stats.bytes_out; thisauth.traffic.recv_bytes = link_stats.bytes_in; thisauth.traffic.sent_pkts = link_stats.pkts_out; thisauth.traffic.recv_pkts = link_stats.pkts_in; rad_acct(&thisauth, 0); nsyslog(LOG_NOTICE, "user %s logged out", thisauth.login); } void ul_ppp_ipup() { if(!rad_using_pap) { if(ipparam == NULL) ipparam = getenv("PORTSLAVELOGNAME"); snprintf(thisauth.login, sizeof (thisauth.login), "%s", ipparam); getenv_from_rad("PORTSLAVE_FILTER", thisauth.filterid, MAX_FILTERS, &thisauth.fln); getenv_from_rad("PORTSLAVE_FRAMED_ROUTE", thisauth.framed_route, MAX_FRAMED_ROUTES, &thisauth.frn); thisauth.proto = P_PPP; thisauth.address = ipcp_gotoptions[0].hisaddr; thisauth.localip = ipcp_gotoptions[0].ouraddr; } if(getenv("PORTSLAVE_DO_ACCT")) thisauth.do_acct = 1; rad_acct(&thisauth, 1); } /* addr is an integer representation of an IP address, make it a single entry in a linked list pointed to by addrs */ void rad_make_wordlist (u_int32_t addr, struct wordlist **addrs) { const char *ipaddr; struct wordlist *ap; ipaddr = dotted(addr); ap = (struct wordlist *) xmalloc(sizeof(struct wordlist) + strlen(ipaddr) + 1); ap->word = (char *) (ap + 1); ap->next = NULL; strcpy(ap->word, ipaddr); *addrs = ap; } #ifdef PORTSLAVE_CLIENT_IP_RULES /* * Create a word list for PPPD from an array of strings. */ void rad_make_wordlist2(char * const *strings, int num, struct wordlist **addrs) { struct wordlist *head; struct wordlist *ap; struct wordlist *prev; int len; int cur; if(num == 0 || strings == NULL) return; head = NULL; prev = NULL; cur = 0; /* Loop through all of the strings given. */ while(cur < num) { /* Allocate the structure; the "word" must live in */ /* the same allocated chunk of memory. */ len = sizeof ap[0] + strlen(strings[cur]) + 1; ap = (struct wordlist *) xmalloc(len); ap->word = (char *) (ap + 1); ap->next = NULL; strcpy(ap->word, strings[cur]); /* Link this entry into the list if it's not the */ /* head of the list. */ if(prev != NULL) prev->next = ap; /* Remember the head of the list if it was not */ /* already set. */ if(head == NULL) head = ap; prev = ap; cur++; } *addrs = head; } #endif #ifdef PORTSLAVE_CALLBACK void ul_cbcp_init(cbcp_state *us) { if(thisauth.cb_allowed != 0) { us->us_allowed = thisauth.cb_allowed; if(thisauth.cb_number != NULL) { us->us_number = xstrdup(thisauth.cb_number); free(thisauth.cb_number); /* we don't need them anymore */ } } return; } #endif portslave-2010.04.19.1/src/auth.h0000664000000000000000000000706110027271611013060 0ustar /* * auth.h Header file for the authentication stuff. * We only use radius, but anyway this is * a try to hide the authentication protocol * from the rest of the system. * * Version: @(#)auth.h 1.00 05-Jul-1996 miquels@cistron.nl * */ #ifndef __auth_h #define __auth_h /* * Types of connection. */ #define P_UNKNOWN 0 #define P_LOCAL 'L' #define P_RLOGIN 'R' #define P_SLIP 'S' #define P_CSLIP 'C' #define P_PPP 'P' #define P_PPP_ONLY 'O' #define P_AUTOPPP 'A' #define P_TELNET 'E' #define P_TCPCLEAR 'T' #define P_TCPLOGIN 'U' #define P_CONSOLE '!' #define P_SHELL 'X' #define P_SSH1 'H' #define P_SSH2 '2' #define P_SOCKET_SERVER 'W' #define P_SOCKET_CLIENT 'I' #define P_SOCKET_SSH 'Y' /* * Types of authentication */ #define AUTH_NONE 0 #define AUTH_RADIUS 1 #define AUTH_TACACS 2 #define AUTH_REMOTE 3 #define AUTH_LOCAL 4 #define AUTH_RADIUS_LOCAL 5 #define AUTH_TACACS_LOCAL 6 #define AUTH_LOCAL_RADIUS 7 #define AUTH_LOCAL_TACACS 8 #ifdef CYCLADES #define AUTH_RADIUS_DOWN_LOCAL 9 #define AUTH_TACACS_DOWN_LOCAL 10 #endif struct traffic_stat { int sent_bytes; int recv_bytes; int sent_pkts; int recv_pkts; }; /* * Authentication info. This struct * contains all info we get back from * the authentication protocol. */ #define MAX_FRAMED_ROUTES 16 #define MAX_RADIUS_MESSAGES 16 #define MAX_FILTERS 16 struct auth { /* Input */ char login[64]; char passwd[64]; time_t start; /* Output */ char *message[MAX_RADIUS_MESSAGES]; /* Up to 16 messages. Good? */ unsigned int msn; /* message num */ char *filterid[MAX_FILTERS]; /* Up to 16 filters. Good? */ unsigned int fln; /* filterid num */ char *framed_route[MAX_FRAMED_ROUTES]; /* Up to 16 routes. Good? */ unsigned int frn; /* framed_router num */ char conn_info[128]; char cli_src[32]; /* number of caller */ char cli_dst[32]; /* number being called */ int proto; int nasport; /* NAS-Port attribute value */ int loginport; /* Login-TCP-Port attribute value */ unsigned int port_limit; /* Limit of MPPP ports */ char *acct_session_id; /* session ID for accounting */ bool authenticated; bool do_acct; /* bool for whether we do accounting */ unsigned int host; /* Address in network byte order of ssh/telnet target */ unsigned int address; /* Remote IP address */ #ifdef HAVE_IPV6 #endif unsigned int localip; unsigned int netmask; int mtu; int mru; int idletime; int sessiontime; /* maxconnect for pppd, maximum length of this call in seconds */ int porttype; struct traffic_stat traffic; #ifdef PORTSLAVE_CALLBACK unsigned char cb_allowed; /* bool for whether callback is allowed */ char *cb_number; /* number to call back */ #endif #ifdef PORTSLAVE_CLIENT_IP_RULES char **valid_ip_rules; /* Validate client-specified IP addr */ int num_ip_rules; #endif char *called_station; /* number they apparently called to get us */ char *calling_station; /* apparent phone number of the user */ #ifndef NO_CHAP int done_chap_once; /* chap is done in two stages */ #endif }; int login_local(struct auth *pai); int do_local_or_server_authentication(struct auth *pai, bool ppp); #ifndef NO_CHAP #ifdef __CHAP_INCLUDE__ int do_chap_authentication(struct auth *pai, u_char *remmd, chap_state *cstate); int rad_client_chap(struct auth *ai, u_char *remmd, chap_state *cstate); #endif #endif int rad_client(struct auth *ai, bool ppp); int rad_acct(const struct auth *ai, bool islogin); #define RAD_INIT_PPPD -2 int rad_init(const char *config_file, int port, struct auth *ai, const char *tty); struct realm_def *ckrealm(const struct auth *ai); #endif /* __auth_h */ portslave-2010.04.19.1/src/md5.h0000664000000000000000000000447107411406237012615 0ustar /* 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; #include /* UINT2 defines a two byte word */ typedef u_int16_t UINT2; /* UINT4 defines a four byte word */ typedef u_int32_t UINT4; /* 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. */ /* * Add some defines so that we use the functions under another name. */ #define md5_calc radius_md5_calc #define MD5Init portslave_MD5Init #define MD5Update portslave_MD5Update #define MD5Final portslave_MD5Final /* 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 *)); portslave-2010.04.19.1/src/ctlp-subs.c0000664000000000000000000000621607411462147014040 0ustar /* * ctlp-subs.c Here's where most SIOC* calls for ctlportslave live. * * Version: @(#)ctlp-subs.c 1.10 13-Jan-1998 miquels@cistron.nl * */ #include #include #include #include #include #include #include #include #include #include #include #if defined(__GLIBC__) # include #else # include # include # include #endif #include "server.h" #define MAX_IFS 128 /* * Find the idle time of a certain device, returns -1 on error. */ int idle_stat(const char *dev) { char buf[128]; int fd; struct termios tty; struct ppp_idle ppp_idle; struct stat st; time_t now; int rc = 0; if (dev[0] != '/') { snprintf(buf, sizeof (buf), "/dev/%s", dev); dev = buf; } if ((fd = open(dev, O_RDONLY|O_NONBLOCK)) < 0) { return -1; } if (tcgetattr(fd, &tty) < 0) { perror(dev); close(fd); return -1; } switch(tty.c_line) { case N_TTY: if (fstat(fd, &st) < 0) break; now = time(NULL); rc = now - st.st_mtime; break; case N_PPP: if (ioctl(fd, PPPIOCGIDLE, &ppp_idle) == 0) { if (ppp_idle.recv_idle < ppp_idle.xmit_idle) rc = ppp_idle.recv_idle; else rc = ppp_idle.xmit_idle; } break; default: break; } close(fd); return rc; } /* * Find the device with a certain IP address. * Return packets in/out if we can retrieve such information. */ int traffic_stats(int sockfd, struct in_addr saddr, int *in, int *out) { int ifs_len; struct ifreq *ifr, *ifs; struct ifconf ifc; struct in_addr ina; int ret = -1; char buf[256]; char *p; FILE *f; *in = *out = 0; ifs_len = MAX_IFS * sizeof (struct ifreq); ifs = (struct ifreq *) xmalloc(ifs_len); ifc.ifc_len = ifs_len; ifc.ifc_req = ifs; if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { perror("ioctl(SIOCGIFCONF)"); free(ifs); return -1; } ifs_len = ifc.ifc_len; for (ifr = ifc.ifc_req; ifs_len > 0; ifr++) { ifs_len -= sizeof(struct ifreq); ifr->ifr_dstaddr.sa_family = AF_INET; if (ioctl(sockfd, SIOCGIFDSTADDR, ifr) < 0) continue; if (ifr->ifr_dstaddr.sa_family != AF_INET) continue; ina = ((struct sockaddr_in *) &ifr->ifr_dstaddr)->sin_addr; /*printf("CHECK: %s %s\n", ifr->ifr_name, inet_ntoa(ina));*/ if (ina.s_addr == saddr.s_addr) { ret = 0; break; } } if (ret) { free(ifs); return ret; } if ((f = fopen ("/proc/net/dev", "r"))) { while (fgets (buf, sizeof(buf), f)) { p = strtok (buf, ":"); while (*p == ' ') p++; /* Trim leading spaces */ if (strcmp(ifr->ifr_name, p) == 0) { int x; p = strtok ((char *) 0, " \t\r\n"); *in = strtoul(p, NULL, 10); for (x = 2; x < 10; x++) p = strtok ((char *) 0, " \t\r\n"); *out = strtoul(p, NULL, 10); break; } } fclose (f); } free(ifs); return 0; } #ifdef STANDALONE int main(int argc, char **argv) { struct in_addr ina; int r, in, out; int sockfd; sockfd = socket(AF_INET, SOCK_DGRAM, 0); inet_aton(argv[1], &ina); r = traffic_stats(sockfd, ina, &in, &out); printf("r = %d, in = %d, out = %d\n", r, in, out); return 0; } #endif