diff -urN ppp-2.4.2.orig/etc.ppp/callback-client ppp-2.4.2/etc.ppp/callback-client --- ppp-2.4.2.orig/etc.ppp/callback-client 1970-01-01 03:00:00.000000000 +0300 +++ ppp-2.4.2/etc.ppp/callback-client 2004-10-14 19:54:27.000000000 +0300 @@ -0,0 +1,6 @@ +#!/bin/sh +# Script callback-client +# Script parameters: delay time in seconds + +sleep $1 +/usr/sbin/chat -v "" ATZ OK "" RING ATA CONNECT diff -urN ppp-2.4.2.orig/etc.ppp/callback-server ppp-2.4.2/etc.ppp/callback-server --- ppp-2.4.2.orig/etc.ppp/callback-server 1970-01-01 03:00:00.000000000 +0300 +++ ppp-2.4.2/etc.ppp/callback-server 2004-10-14 19:55:10.000000000 +0300 @@ -0,0 +1,6 @@ +#!/bin/sh +# Script callback-server +# Script parameters: delay time in seconds, callback number + +sleep $1 +/usr/sbin/chat -v "" ATZ OK ATDT$2 CONNECT diff -urN ppp-2.4.2.orig/etc.ppp/callback-users ppp-2.4.2/etc.ppp/callback-users --- ppp-2.4.2.orig/etc.ppp/callback-users 1970-01-01 03:00:00.000000000 +0300 +++ ppp-2.4.2/etc.ppp/callback-users 2004-10-14 16:45:07.000000000 +0300 @@ -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 -urN ppp-2.4.2.orig/linux/Makefile.top ppp-2.4.2/linux/Makefile.top --- ppp-2.4.2.orig/linux/Makefile.top 2002-09-07 13:37:49.000000000 +0300 +++ ppp-2.4.2/linux/Makefile.top 2004-10-14 20:00:49.000000000 +0300 @@ -3,7 +3,7 @@ BINDIR = $(DESTDIR)/usr/sbin INCDIR = $(DESTDIR)/usr/include -MANDIR = $(DESTDIR)/usr/man +MANDIR = $(DESTDIR)/usr/share/man ETCDIR = $(DESTDIR)/etc/ppp # uid 0 = root @@ -26,7 +26,8 @@ cd pppdump; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ - $(ETCDIR)/chap-secrets + $(ETCDIR)/chap-secrets $(ETCDIR)/callback-users \ + $(ETCDIR)/callback-client $(ETCDIR)/callback-server install-devel: cd pppd; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) INCDIR=$(INCDIR) $(MFLAGS) install-devel @@ -37,6 +38,12 @@ $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@ $(ETCDIR)/chap-secrets: $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@ +$(ETCDIR)/callback-users: + $(INSTALL) -c -m 664 etc.ppp/callback-users $@ +$(ETCDIR)/callback-client: + $(INSTALL) -c -m 700 etc.ppp/callback-client $@ +$(ETCDIR)/callback-server: + $(INSTALL) -c -m 700 etc.ppp/callback-server $@ $(BINDIR): $(INSTALL) -d -m 755 $@ diff -urN ppp-2.4.2.orig/pppd/auth.c ppp-2.4.2/pppd/auth.c --- ppp-2.4.2.orig/pppd/auth.c 2003-06-12 02:56:26.000000000 +0300 +++ ppp-2.4.2/pppd/auth.c 2004-10-14 19:28:45.000000000 +0300 @@ -248,7 +248,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 **)); @@ -671,7 +670,7 @@ /* * Proceed to the network phase. */ -static void +void network_phase(unit) int unit; { @@ -697,7 +696,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 -urN ppp-2.4.2.orig/pppd/cbcp.c ppp-2.4.2/pppd/cbcp.c --- ppp-2.4.2.orig/pppd/cbcp.c 2003-01-31 13:11:17.000000000 +0200 +++ ppp-2.4.2/pppd/cbcp.c 2004-10-14 19:42:09.000000000 +0300 @@ -1,8 +1,12 @@ /* * cbcp - Call Back Configuration Protocol. * - * Copyright (c) 1995 Pedro Roque Marques. All rights reserved. + * Copyright (c) 1995 Pedro Roque Marques. + * Copyright (c) 2001 Bolke de Bruin + * Copyright (c) 2004 Valery Kartel * + * All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -39,28 +43,22 @@ #include #include #include +#include +#include #include "pppd.h" #include "cbcp.h" #include "fsm.h" #include "lcp.h" +#include "ipcp.h" +#include "pathnames.h" static const char rcsid[] = RCSID; /* - * Options. - */ -static int setcbcp __P((char **)); - -static option_t cbcp_option_list[] = { - { "callback", o_special, (void *)setcbcp, - "Ask for callback", OPT_PRIO | OPT_A2STRVAL, &cbcp[0].us_number }, - { NULL } -}; - -/* * Protocol entry points. */ + static void cbcp_init __P((int unit)); static void cbcp_open __P((int unit)); static void cbcp_lowerup __P((int unit)); @@ -84,8 +82,6 @@ 0, "CBCP", NULL, - cbcp_option_list, - NULL, NULL, NULL }; @@ -93,27 +89,23 @@ cbcp_state cbcp[NUM_PPP]; /* internal prototypes */ - +static void cbcp_sendreq __P((void *arg)); static void cbcp_recvreq __P((cbcp_state *us, u_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, u_char *pckt, int len)); + static void cbcp_send __P((cbcp_state *us, int 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 @@ -125,7 +117,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 */ @@ -135,18 +126,17 @@ { 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)); } 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 */ @@ -161,11 +151,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; } @@ -175,7 +167,7 @@ #if 0 if (len > pktlen) { - error("CBCP packet: invalid length"); + syslog(LOG_ERR, "CBCP packet: invalid length"); return; } #endif @@ -184,17 +176,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); @@ -274,13 +285,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, ">"); @@ -306,41 +318,40 @@ u_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: @@ -349,59 +360,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 ) ) { + 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 = 2; + len = 3; PUTCHAR(len , bufp); + PUTCHAR(0, bufp); cbcp_send(us, CBCP_RESP, buf, len); - start_networks(us->us_unit); return; } + syslog(LOG_WARNING, "cbcp_sendresp: no usable options available!"); } +/* Send the packet */ static void cbcp_send(us, code, buf, len) cbcp_state *us; @@ -428,43 +444,432 @@ output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } +/* Received Ack */ static void cbcp_recvack(us, pckt, len) cbcp_state *us; u_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 ); +} - cbcp_up(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"); + } +} + +/* 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 ); + } } -/* ok peer will do callback */ +/* 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")); +} + +/* 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 -urN ppp-2.4.2.orig/pppd/cbcp.h ppp-2.4.2/pppd/cbcp.h --- ppp-2.4.2.orig/pppd/cbcp.h 1998-11-07 08:55:38.000000000 +0200 +++ ppp-2.4.2/pppd/cbcp.h 2004-10-14 18:39:08.000000000 +0300 @@ -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; @@ -18,9 +20,19 @@ #define CBCP_REQ 1 #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 -urN ppp-2.4.2.orig/pppd/ipcp.c ppp-2.4.2/pppd/ipcp.c --- ppp-2.4.2.orig/pppd/ipcp.c 2004-01-13 05:59:06.000000000 +0200 +++ ppp-2.4.2/pppd/ipcp.c 2004-10-14 18:42:31.000000000 +0300 @@ -61,6 +61,10 @@ #include "ipcp.h" #include "pathnames.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif + static const char rcsid[] = RCSID; /* global vars */ @@ -1316,6 +1320,10 @@ u_char maxslotindex, cflag; int d; +#ifdef CBCP_SUPPORT + cbcp_stop(); +#endif + /* * Reset all his options. */ diff -urN ppp-2.4.2.orig/pppd/ipv6cp.c ppp-2.4.2/pppd/ipv6cp.c --- ppp-2.4.2.orig/pppd/ipv6cp.c 2004-01-13 05:59:37.000000000 +0200 +++ ppp-2.4.2/pppd/ipv6cp.c 2004-10-14 18:43:57.000000000 +0300 @@ -167,6 +167,10 @@ #include "magic.h" #include "pathnames.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif + static const char rcsid[] = RCSID; /* global vars */ @@ -900,6 +904,10 @@ 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 -urN ppp-2.4.2.orig/pppd/ipxcp.c ppp-2.4.2/pppd/ipxcp.c --- ppp-2.4.2.orig/pppd/ipxcp.c 2003-11-18 12:42:56.000000000 +0200 +++ ppp-2.4.2/pppd/ipxcp.c 2004-10-14 18:44:59.000000000 +0300 @@ -62,6 +62,10 @@ #include "pathnames.h" #include "magic.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif + static const char rcsid[] = RCSID; /* global vars */ @@ -998,6 +1002,10 @@ 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 -urN ppp-2.4.2.orig/pppd/lcp.c ppp-2.4.2/pppd/lcp.c --- ppp-2.4.2.orig/pppd/lcp.c 2003-11-18 12:42:56.000000000 +0200 +++ ppp-2.4.2/pppd/lcp.c 2004-10-14 18:48:32.000000000 +0300 @@ -365,9 +365,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; } @@ -1767,6 +1765,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 -urN ppp-2.4.2.orig/pppd/main.c ppp-2.4.2/pppd/main.c --- ppp-2.4.2.orig/pppd/main.c 2004-10-14 20:03:18.000000000 +0300 +++ ppp-2.4.2/pppd/main.c 2004-10-14 18:58:08.000000000 +0300 @@ -159,6 +159,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 */ @@ -283,6 +287,10 @@ struct protent *protp; char numbuf[16]; +#ifdef CBCP_SUPPORT + char *connector; +#endif + link_stats_valid = 0; new_phase(PHASE_INITIALIZE); @@ -544,6 +552,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) { @@ -572,6 +584,71 @@ 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 diff -urN ppp-2.4.2.orig/pppd/Makefile.linux ppp-2.4.2/pppd/Makefile.linux --- ppp-2.4.2.orig/pppd/Makefile.linux 2004-10-14 20:03:18.000000000 +0300 +++ ppp-2.4.2/pppd/Makefile.linux 2004-10-14 20:07:06.162743880 +0300 @@ -5,7 +5,7 @@ # Default installation locations BINDIR = $(DESTDIR)/usr/sbin -MANDIR = $(DESTDIR)/usr/man +MANDIR = $(DESTDIR)/usr/share/man INCDIR = $(DESTDIR)/usr/include TARGETS = pppd diff -urN ppp-2.4.2.orig/pppd/options.c ppp-2.4.2/pppd/options.c --- ppp-2.4.2.orig/pppd/options.c 2004-10-14 20:03:18.000000000 +0300 +++ ppp-2.4.2/pppd/options.c 2004-10-14 19:41:31.000000000 +0300 @@ -66,6 +66,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 { @@ -165,6 +171,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. */ @@ -304,6 +314,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 + #ifdef MAXOCTETS { "maxoctets", o_int, &maxoctets, "Set connection traffic limit", @@ -1594,3 +1609,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 -urN ppp-2.4.2.orig/pppd/pathnames.h ppp-2.4.2/pppd/pathnames.h --- ppp-2.4.2.orig/pppd/pathnames.h 2002-11-09 13:24:42.000000000 +0200 +++ ppp-2.4.2/pppd/pathnames.h 2004-10-14 19:02:52.000000000 +0300 @@ -44,6 +44,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 -urN ppp-2.4.2.orig/pppd/plugins/radius/Makefile ppp-2.4.2/pppd/plugins/radius/Makefile --- ppp-2.4.2.orig/pppd/plugins/radius/Makefile 2004-10-14 20:03:18.000000000 +0300 +++ ppp-2.4.2/pppd/plugins/radius/Makefile 2004-10-14 16:53:59.000000000 +0300 @@ -3,7 +3,7 @@ # Copyright 2002 Roaring Penguin Software Inc. # -MANDIR=/usr/man +MANDIR=/usr/share/man PLUGIN=radius.so radattr.so radrealms.so CFLAGS=$(COPTS) -I../.. -I../../../include -Iradiusclient/include diff -urN ppp-2.4.2.orig/pppd/plugins/radius/Makefile.linux ppp-2.4.2/pppd/plugins/radius/Makefile.linux --- ppp-2.4.2.orig/pppd/plugins/radius/Makefile.linux 2004-10-14 20:03:18.000000000 +0300 +++ ppp-2.4.2/pppd/plugins/radius/Makefile.linux 2004-10-14 16:53:59.000000000 +0300 @@ -3,7 +3,7 @@ # Copyright 2002 Roaring Penguin Software Inc. # -MANDIR=/usr/man +MANDIR=/usr/share/man PLUGIN=radius.so radattr.so radrealms.so CFLAGS=$(COPTS) -I../.. -I../../../include -Iradiusclient/include diff -urN ppp-2.4.2.orig/pppd/plugins/radius/radiusclient/config.h.in ppp-2.4.2/pppd/plugins/radius/radiusclient/config.h.in --- ppp-2.4.2.orig/pppd/plugins/radius/radiusclient/config.h.in 2002-07-25 19:29:16.000000000 +0300 +++ ppp-2.4.2/pppd/plugins/radius/radiusclient/config.h.in 2004-10-14 19:26:00.000000000 +0300 @@ -1,6 +1,6 @@ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* - * $Id: config.h.in,v 1.3 2002/07/25 16:29:16 dfs Exp $ + * $Id: acconfig.h,v 1.1 2002/01/22 16:03:00 dfs Exp $ * * Copyright (C) 1996,1997 Lars Fenneberg * diff -urN ppp-2.4.2.orig/pppd/pppd.8 ppp-2.4.2/pppd/pppd.8 --- ppp-2.4.2.orig/pppd/pppd.8 2004-01-15 07:09:00.000000000 +0200 +++ ppp-2.4.2/pppd/pppd.8 2004-10-14 19:04:07.000000000 +0300 @@ -87,6 +87,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\fR. 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 Usually there is something which needs to be done to prepare the link before the PPP protocol can be started; for instance, with a dial-up diff -urN ppp-2.4.2.orig/pppd/pppd.h ppp-2.4.2/pppd/pppd.h --- ppp-2.4.2.orig/pppd/pppd.h 2004-10-14 20:03:18.000000000 +0300 +++ ppp-2.4.2/pppd/pppd.h 2004-10-14 19:20:53.000000000 +0300 @@ -71,6 +71,10 @@ #include "eui64.h" #endif +/* for cbcp_init_hook */ +#include "cbcp.h" + + /* * Limits. */ @@ -334,6 +338,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 */ @@ -488,6 +496,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)); @@ -513,6 +523,7 @@ /* read a complete buffer */ /* 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 */ @@ -688,6 +699,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 *)); extern int (*chap_check_hook) __P((void)); extern int (*chap_passwd_hook) __P((char *user, char *passwd)); diff -urN ppp-2.4.2.orig/pppd/tty.c ppp-2.4.2/pppd/tty.c --- ppp-2.4.2.orig/pppd/tty.c 2004-01-13 06:17:59.000000000 +0200 +++ ppp-2.4.2/pppd/tty.c 2004-10-14 19:18:09.000000000 +0300 @@ -101,6 +101,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)); @@ -131,6 +134,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 */ @@ -511,10 +516,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. @@ -542,72 +547,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"); - -#ifndef __linux__ - /* - * Linux 2.4 and above blocks normal writes to the tty - * when it is in PPP line discipline, so this isn't needed. - */ - /* - * 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; -#endif /* __linux__ */ - - /* - * 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, @@ -736,6 +676,112 @@ 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() { diff -urN ppp-2.4.2.orig/pppdump/Makefile ppp-2.4.2/pppdump/Makefile --- ppp-2.4.2.orig/pppdump/Makefile 1970-01-01 03:00:00.000000000 +0300 +++ ppp-2.4.2/pppdump/Makefile 2004-10-14 16:26:22.000000000 +0300 @@ -0,0 +1,17 @@ +CFLAGS= $(COPTS) -I../include/net +OBJS = pppdump.o bsd-comp.o deflate.o zlib.o + +INSTALL= install + +all: pppdump + +pppdump: $(OBJS) + $(CC) $(LDFLAGS) -o pppdump $(OBJS) + +clean: + rm -f pppdump $(OBJS) *~ + +install: + mkdir -p $(BINDIR) $(MANDIR)/man8 + $(INSTALL) -s -c pppdump $(BINDIR) + $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)/man8 diff -urN ppp-2.4.2.orig/pppstats/Makefile ppp-2.4.2/pppstats/Makefile --- ppp-2.4.2.orig/pppstats/Makefile 1970-01-01 03:00:00.000000000 +0300 +++ ppp-2.4.2/pppstats/Makefile 2004-10-14 16:26:22.000000000 +0300 @@ -0,0 +1,33 @@ +# +# pppstats makefile +# $Id: Makefile.linux,v 1.5 2002/10/27 12:56:26 fcusack Exp $ +# + +PPPSTATSRCS = pppstats.c +PPPSTATOBJS = pppstats.o + +#CC = gcc +COPTS = -O +COMPILE_FLAGS = -I../include +LIBS = + +INSTALL= install -o root -g daemon + +CFLAGS = $(COPTS) $(COMPILE_FLAGS) + +all: pppstats + +install: pppstats + -mkdir -p $(MANDIR)/man8 + $(INSTALL) -s -c pppstats $(BINDIR)/pppstats + $(INSTALL) -c -m 444 pppstats.8 $(MANDIR)/man8/pppstats.8 + +pppstats: $(PPPSTATSRCS) + $(CC) $(CFLAGS) $(LDFLAGS) -o pppstats pppstats.c $(LIBS) + +clean: + rm -f pppstats *~ #* core + +depend: + cpp -M $(CFLAGS) $(PPPSTATSRCS) >.depend +# makedepend $(CFLAGS) $(PPPSTATSRCS) diff -urN ppp-2.4.2.orig/README.cbcp ppp-2.4.2/README.cbcp --- ppp-2.4.2.orig/README.cbcp 2003-11-27 23:24:04.000000000 +0200 +++ ppp-2.4.2/README.cbcp 2004-10-14 16:42:55.000000000 +0300 @@ -1,6 +1,8 @@ Microsoft Call Back Configuration Protocol. by Pedro Roque Marques - (updated by Paul Mackerras) + (updated by Paul Mackerras) + (updated by Bolke de Bruin, bolke@xs4all.nl) + (updated by Valery Kartel, droid@terem.kiev.ua) The CBCP is a method by which the Microsoft Windows NT Server may implement additional security. It is possible to configure the server @@ -11,10 +13,6 @@ It is a requirement of servers to be 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,30 +20,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 uncomment the line -in Makefile.linux that sets CBCP=y and recompile pppd. - -I use such script to make a callback: - -pppd debug nodetach /dev/modem 115200 crtscts modem \ -callback 222222 name NAME remotename SERVER \ -connect 'chat -v "" atz OK atdt111111 CONNECT ""' -sleep 1 -pppd debug /dev/modem 115200 crtscts modem \ -name NAME remotename SERVER defaultroute \ -connect 'chat -v RING ATA CONNECT "\c"' - -First we invoke pppd with 'nodetach' option in order to not detach from -the controlling terminal and 'callback NUMBER' option, then wait for -1 second and invoke pppd again which waits for a callback (RING) and -then answers (ATA). Number 222222 is a callback number, i.e. server will -call us back at this number, while number 111111 is the number we are -calling to. - -You have to put in /etc/ppp/chap-secrets the following two lines: - -NAME SERVER PASSWORD -SERVER NAME PASSWORD - -You have to use your real login name, remote server name and password. - +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.