The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Патч для работы CBCP Callback в pppd-2.4.1 (cbcp ppp callback patch)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: cbcp, ppp, callback, patch,  (найти похожие документы)
From: opennet Date: Mon, 3 Oct 2002 14:31:37 +0000 (UTC) Subject: Патч для работы CBCP Callback в pppd-2.4.1 1. Патчим. 2. Копируем в /etc/ppp файл etc.ppp/callback-client 3. В /etc/ppp/pap-secrets пишем: логин * пароль * 4. Соединяемся: /usr/sbin/pppd lock modem crtscts /dev/modem 115200 \ noipdefault defaultroute noauth \ -detach callback <ТЕЛЕФОН ДЛЯ ПЕРЕЗВОНА> name <ЛОГИН> pap-timeout 10 \ connect "chat -T <ТЕЛЕФОН ПРОВАЙДЕРА> -f /etc/ppp/cb_chat_call" /etc/ppp/cb_chat_call: TIMEOUT 90 ABORT BUSY ABORT 'NO ANSWER' ABORT 'NO DIALTONE' ABORT ERROR ABORT 'NO CARRIER' "" AT&F1M1 OK atdt\T CONNECT \c diff -urN ppp-2.4.1.org/README.cbcp ppp-2.4.1/README.cbcp --- ppp-2.4.1.org/README.cbcp Thu May 22 08:48:50 1997 +++ ppp-2.4.1/README.cbcp Fri Jun 22 22:49: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 <sys/types.h> 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 <sys/types.h> 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 <number>). 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 -urN ppp-2.4.1.org/chat/Makefile.linux ppp-2.4.1/chat/Makefile.linux --- ppp-2.4.1.org/chat/Makefile.linux Fri Jun 22 22:49:09 2001 +++ ppp-2.4.1/chat/Makefile.linux Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/chat/chat.c ppp-2.4.1/chat/chat.c --- ppp-2.4.1.org/chat/chat.c Thu Dec 23 03:39:54 1999 +++ ppp-2.4.1/chat/chat.c Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/etc.ppp/callback-client ppp-2.4.1/etc.ppp/callback-client --- ppp-2.4.1.org/etc.ppp/callback-client Thu Jan 1 03:00:00 1970 +++ ppp-2.4.1/etc.ppp/callback-client Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/etc.ppp/callback-server ppp-2.4.1/etc.ppp/callback-server --- ppp-2.4.1.org/etc.ppp/callback-server Thu Jan 1 03:00:00 1970 +++ ppp-2.4.1/etc.ppp/callback-server Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/etc.ppp/callback-users ppp-2.4.1/etc.ppp/callback-users --- ppp-2.4.1.org/etc.ppp/callback-users Thu Jan 1 03:00:00 1970 +++ ppp-2.4.1/etc.ppp/callback-users Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/linux/Makefile.top ppp-2.4.1/linux/Makefile.top --- ppp-2.4.1.org/linux/Makefile.top Mon Apr 17 13:39:26 2000 +++ ppp-2.4.1/linux/Makefile.top Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/pppd/auth.c ppp-2.4.1/pppd/auth.c --- ppp-2.4.1.org/pppd/auth.c Fri Jun 22 22:49:09 2001 +++ ppp-2.4.1/pppd/auth.c Fri Jun 22 22:49:37 2001 @@ -172,7 +172,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 **)); @@ -499,8 +498,7 @@ /* * Proceed to the network phase. */ -static void -network_phase(unit) +void network_phase(unit) int unit; { lcp_options *go = &lcp_gotoptions[unit]; @@ -520,7 +518,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.1.org/pppd/cbcp.c ppp-2.4.1/pppd/cbcp.c --- ppp-2.4.1.org/pppd/cbcp.c Thu Mar 8 07:11:10 2001 +++ ppp-2.4.1/pppd/cbcp.c Fri Jun 22 22:52:24 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 <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/time.h> +#include <syslog.h> +#include <sys/stat.h> #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,22 @@ /* 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)); + + +cbcp_state *stop_iface = NULL; -/* 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); -} /* init state */ static void @@ -110,7 +99,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 +108,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 +135,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 +151,7 @@ #if 0 if (len > pktlen) { - error("CBCP packet: invalid length"); + syslog(LOG_ERR, "CBCP packet: invalid length"); return; } #endif @@ -169,17 +160,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 +269,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 +302,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 +344,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 +428,427 @@ 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"); + - cbcp_up(us); } -/* ok peer will do callback */ +/* 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 ); + + 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"); + } +} + +/* 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")); +} + +/* 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.1.org/pppd/cbcp.h ppp-2.4.1/pppd/cbcp.h --- ppp-2.4.1.org/pppd/cbcp.h Sat Nov 7 08:55:38 1998 +++ ppp-2.4.1/pppd/cbcp.h Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/pppd/ipcp.c ppp-2.4.1/pppd/ipcp.c --- ppp-2.4.1.org/pppd/ipcp.c Thu Mar 8 07:11:12 2001 +++ ppp-2.4.1/pppd/ipcp.c Fri Jun 22 22:49: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 */ @@ -1216,6 +1220,9 @@ u_char maxslotindex, cflag; int d; +#ifdef CBCP_SUPPORT + cbcp_stop(); +#endif /* * Reset all his options. */ diff -urN ppp-2.4.1.org/pppd/ipv6cp.c ppp-2.4.1/pppd/ipv6cp.c --- ppp-2.4.1.org/pppd/ipv6cp.c Fri Mar 23 13:23:54 2001 +++ ppp-2.4.1/pppd/ipv6cp.c Fri Jun 22 22:49: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 */ @@ -852,6 +856,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 -urN ppp-2.4.1.org/pppd/ipxcp.c ppp-2.4.1/pppd/ipxcp.c --- ppp-2.4.1.org/pppd/ipxcp.c Thu Mar 8 07:11:13 2001 +++ ppp-2.4.1/pppd/ipxcp.c Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/pppd/lcp.c ppp-2.4.1/pppd/lcp.c --- ppp-2.4.1.org/pppd/lcp.c Thu Mar 8 07:11:14 2001 +++ ppp-2.4.1/pppd/lcp.c Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/pppd/main.c ppp-2.4.1/pppd/main.c --- ppp-2.4.1.org/pppd/main.c Fri Jun 22 22:49:09 2001 +++ ppp-2.4.1/pppd/main.c Fri Jun 22 22:53:32 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 */ @@ -233,6 +237,10 @@ struct protent *protp; char numbuf[16]; +#ifdef CBCP_SUPPORT + char *connector; +#endif + new_phase(PHASE_INITIALIZE); /* @@ -478,6 +486,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) { @@ -514,7 +526,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 -urN ppp-2.4.1.org/pppd/options.c ppp-2.4.1/pppd/options.c --- ppp-2.4.1.org/pppd/options.c Tue Mar 13 07:56:19 2001 +++ ppp-2.4.1/pppd/options.c Fri Jun 22 22:49: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 { @@ -128,6 +132,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. */ @@ -262,6 +270,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 } }; @@ -1511,3 +1524,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.1.org/pppd/pathnames.h ppp-2.4.1/pppd/pathnames.h --- ppp-2.4.1.org/pppd/pathnames.h Thu Mar 8 07:15:37 2001 +++ ppp-2.4.1/pppd/pathnames.h Fri Jun 22 22:49:37 2001 @@ -42,6 +42,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.1.org/pppd/pppd.8 ppp-2.4.1/pppd/pppd.8 --- ppp-2.4.1.org/pppd/pppd.8 Tue Mar 13 07:54:37 2001 +++ ppp-2.4.1/pppd/pppd.8 Fri Jun 22 22:49: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 -urN ppp-2.4.1.org/pppd/pppd.h ppp-2.4.1/pppd/pppd.h --- ppp-2.4.1.org/pppd/pppd.h Tue Mar 13 07:54:37 2001 +++ ppp-2.4.1/pppd/pppd.h Fri Jun 22 22:58:15 2001 @@ -278,6 +278,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 */ @@ -422,6 +426,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)); @@ -443,6 +449,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 */ diff -urN ppp-2.4.1.org/pppd/tty.c ppp-2.4.1/pppd/tty.c --- ppp-2.4.1.org/pppd/tty.c Tue Mar 13 07:54:43 2001 +++ ppp-2.4.1/pppd/tty.c Fri Jun 22 23:03:34 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() { diff -urN ppp-2.4.1.org/pppd/cbcp.c ppp-2.4.1/pppd/cbcp.c --- ppp-2.4.1.org/pppd/cbcp.c Fri Oct 26 23:58:12 2001 +++ ppp-2.4.1/pppd/cbcp.c Sat Oct 27 01:08:09 2001 @@ -88,6 +88,7 @@ cbcp_state *stop_iface = NULL; +void (*cbcp_init_hook) __P((cbcp_state *)) = NULL; /* init state */ static void @@ -553,6 +554,9 @@ else us->us_allowed = ( 1 << CB_CONF_USER ); + if (cbcp_init_hook) + cbcp_init_hook( us ); + cbcp_sendreq( us ); } diff -urN ppp-2.4.1.org/pppd/pppd.h ppp-2.4.1/pppd/pppd.h --- ppp-2.4.1.org/pppd/pppd.h Sat Oct 27 00:14:45 2001 +++ ppp-2.4.1/pppd/pppd.h Sat Oct 27 00:42:34 2001 @@ -48,6 +48,9 @@ #include "eui64.h" #endif +/* for cbcp_init_hook */ +#include "cbcp.h" + /* * Limits. */ @@ -621,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.

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру