[>a2262.html>] [<a2260.html<] [^a2.html^]
Per concedere un accesso a Internet attraverso una connessione telefonica, così come fa normalmente un fornitore di accesso a Internet, bisogna predisporre un sistema GNU/Linux munito di molte porte seriali e di altrettanti modem in attesa di chiamata. In questo capitolo non verranno presentati i problemi tecnici legati all'installazione di una scheda seriale multipla, dal momento che questi variano da modello a modello, mentre ci si vuole concentrare sulla configurazione di Getty e sull'attivazione del protocollo PPP.
Nel capitolo si fa riferimento a programmi e a concetti già presentati in precedenza, che vengono richiamati per favorire il lettore.
Dovendo gestire le porte seriali, è opportuno preoccuparsi della loro impostazione attraverso il programma setserial, già descritto nel capitolo 111. Per questo si realizza solitamente uno script da includere nella procedura di inizializzazione del sistema. Potrebbe trattarsi di /etc/rc.d/rc.serial
, o qualcosa di simile. Il suo contenuto potrebbe assomigliare all'esempio che segue.
#!/bin/sh echo "Configurazione delle porte seriali..." /bin/setserial /dev/ttyS0 port 0x3F8 irq 4 /bin/setserial /dev/ttyS1 port 0x2F8 irq 3
Se si utilizza una scheda seriale multipla, è molto probabile che si debba indicare lo stesso IRQ per tutte le porte, mentre queste si distinguono solo in base agli indirizzi di I/O. Nello stesso modo, potrebbe essere necessario specificare più elementi, come il tipo di UART, e forse delle opzioni spd_* (purché siano tollerate dal kernel).
Una volta configurate le porte, prima di procedere oltre, è necessario fare degli esperimenti collegando un modem e comunicando con questo attraverso un programma per la gestione del terminale, come Minicom. Con qualche comando AT si può verificare se il collegamento tra il modem e l'elaboratore è funzionante, oppure se la porta seriale richiede qualche accorgimento di configurazione ulteriore.
Il pacchetto Getty_ps, e precisamente il programma uugetty, non rappresenta la scelta ottima per risolvere il problema dell'accesso da un terminale seriale, attraverso la linea commutata e il modem. Tuttavia, la sua semplicità permette di comprendere meglio ciò che si fa.
uugetty richiede la presenza del file /etc/gettydefs
, che serve a definire le caratteristiche elementari dei diversi tipi di linea. Nel caso delle connessioni via modem da linea commutata, sono necessarie in particolare le direttive seguenti.
230400# B230400 CS8 CRTSCTS # B230400 SANE -ISTRIP HUPCL CRTSCTS #@S login: #115200
115200# B115200 CS8 CRTSCTS # B115200 SANE -ISTRIP HUPCL CRTSCTS #@S login: #57600
57600# B57600 CS8 CRTSCTS # B57600 SANE -ISTRIP HUPCL CRTSCTS #@S login: #38400
38400# B38400 CS8 CRTSCTS # B38400 SANE -ISTRIP HUPCL CRTSCTS #@S login: #19200
19200# B19200 CS8 CRTSCTS # B19200 SANE -ISTRIP HUPCL CRTSCTS #@S login: #9600
9600# B9600 CS8 CRTSCTS # B9600 SANE -ISTRIP HUPCL CRTSCTS #@S login: #2400
2400# B2400 CS8 CRTSCTS # B2400 SANE -ISTRIP HUPCL CRTSCTS #@S login: #230400
Una volta verificata la presenza di questo file, e dopo aver visto che il contenuto è corretto, si possono predisporre i file di configurazione di ogni linea, che generalmente vengono collocati nella directory /etc/default/
. L'esempio seguente fa riferimento alla prima porta seriale, /dev/ttyS0
, e si concretizza nel file /etc/default/uugetty.ttyS0
.
Se si è sicuri che i dispositivi obsoleti per le chiamate in uscita, contrassegnati dai file /etc/cua*
, non vengono utilizzati, si può realizzare un solo file di configurazione per tutte le linee seriali gestite, ammesso che si abbiano a disposizione gli stessi modem, o almeno che questi accettino le stesse sequenze di inizializzazione.
#======================================================================= # /etc/default/uugetty.ttyS0 # # Configurazione per un modem compatibile Hayes. #======================================================================= #----------------------------------------------------------------------- # Se si devono usare i dispositivi /dev/cua* per le comunicazioni # in uscita, occorre togliere il commento alle righe seguenti. # Se non fosse per questo, il file di configurazione potrebbe essere # standardizzato per ogni linea seriale. #----------------------------------------------------------------------- #ALTLOCK=cua0 #ALTLINE=cua0 #INITLINE=cua0 #----------------------------------------------------------------------- # Disconnette se resta inattivo per il numero di secondi specificato. #----------------------------------------------------------------------- TIMEOUT=60 #----------------------------------------------------------------------- # Sequenza di inizializzazione del modem che viene messo nella # modalità di risposta automatica al primo squillo. # Per le particolarità del modem, si presume che il suo profilo interno # di configurazione sia stato predisposto nel modo più opportuno. # Per questo si utilizza il comando ATZ per richiamarlo, ma volendo si # può anche decidere di utilizzare AT&F in modo da partire sempre # dall'impostazione standard del produttore. # La sequenza ha il formato: # <attesa> <invio> <attesa> <invio>... #----------------------------------------------------------------------- INIT="" \d+++\dAT\r OK\r\n ATH0\r OK\r\n ATZ\r OK\r\n ATM0E1Q0V1X3S0=1\r OK\r\n #----------------------------------------------------------------------- # Si specifica un ritardo di un secondo prima di inviare la richiesta # del login. #----------------------------------------------------------------------- DELAY=1
Infine, occorre inserire la chiamata di uugetty nel file /etc/inittab
, con una riga per ogni porta seriale, e per ogni modem gestito.
s0:2345:respawn:/sbin/uugetty -d /etc/default/uugetty.ttyS0 ttyS0 115200 vt100 s1:2345:respawn:/sbin/uugetty -d /etc/default/uugetty.ttyS1 ttyS1 115200 vt100 #...
È bene ricordare che il numero 115200 indicato tra gli argomenti, fa riferimento alla voce corrispondente nel file /etc/gettydefs
, e precisamente a quella seguente:
115200# B115200 CS8 CRTSCTS # B115200 SANE -ISTRIP HUPCL CRTSCTS #@S login: #57600
Se per qualche motivo si ritiene di voler iniziare da una velocità più bassa, basta cambiare questo argomento, per esempio con 57600, 38400,...
Quando si utilizza un programma come uugetty per controllare le porte seriali e i modem in attesa di una chiamata, l'utente che accede è sottoposto a una procedura di autenticazione tradizionale (Unix), con la quale si deve inserire un nominativo-utente e una password. In questa situazione, la connessione PPP, per mezzo del programma pppd, viene avviata dopo il riconoscimento dell'utente, nel modo che verrà mostrato più avanti in questo capitolo.
Il protocollo PPP, e pppd in particolare, prevede delle forme di autenticazione autonome che richiedono la conoscenza di altri problemi. Prima di affrontarli, è necessario comprendere bene il funzionamento del sistema tradizionale di autenticazione. Per il momento ci si limita a trattare il PPP come un protocollo senza alcun sistema di autenticazione.
Uno dei problemi che riguardano l'attivazione del PPP è quello della definizione dinamica degli indirizzi IPv4. Di solito si deve fare in modo che per ogni modem disponibile in ricezione venga assegnato lo stesso indirizzo IP remoto, cioè quello abbinato al nodo dell'utente che si connette attraverso il telefono. L'indirizzo IP locale può essere sempre lo stesso, e di solito si tratta anche di uno già utilizzato per un'altra interfaccia di rete, tanto non viene definito alcun instradamento sul lato locale della connessione PPP.
A titolo di esempio si può decidere di utilizzare gli indirizzi seguenti:
192.168.11.10 per il dispositivo /etc/ttyS0
;
192.168.11.11 per il dispositivo /etc/ttyS1
;
ecc.
Dalla parte locale si può decidere di usare sempre l'indirizzo 192.168.11.1. Si osservi la figura 200.1
192.168.11.10 192.168.11.1 .---------------. ----------------------------------------| ttyS0 | | | 192.168.11.1 | Host eth0 |------. 192.168.11.11 192.168.11.1 | | | ----------------------------------------| ttyS1 | | `---------------' | Linee seriali | | .--------------. | Router | `--------------' | V Internet Figura 200.1. Schema di esempio della distribuzione degli indirizzi IPv4. Per risparmiare numeri IP viene dato lo stesso numero assegnato all'interfaccia eth0 anche alla parte locale dei collegamenti PPP. |
La soluzione del problema dell'assegnazione degli indirizzi IP si risolve con i file di configurazione di pppd distinti in base al dispositivo seriale attraverso cui si intende convogliare il protocollo. Si comincia generalmente dalla configurazione generale del file /etc/ppp/options
, che è sempre bene ridurre al minino, in modo da non rischiare interferenze con tutti i modi diversi in cui si pensa di utilizzare pppd. L'esempio seguente è decisamente minimo.
lock ms-dns 192.168.1.1
Tuttavia, è opportuno anticipare quali opzioni potrebbero essere aggiunte nella riga di comando di pppd per le connessioni senza autenticazione da parte del PPP.
noauth nodetach modem crtscts proxyarp
Eventualmente si potrebbe decidere di aggiungere la direttiva netmask 255.255.255.255 che è la più appropriata nelle connessioni punto-punto. Tuttavia, in condizioni normali, questa viene determinata automaticamente.
Si osservi la direttiva ms-dns che permette agli utenti che accedono attraverso il sistema operativo MS-Windows di ottenere automaticamente l'indicazione dell'indirizzo IP del servente DNS.
pppd permette di definire una serie di altri file di configurazione che servono a contenere le direttive specifiche per ogni linea di terminale, composti con un nome che rispetti il modello /etc/ppp/options.linea
. Per tornare all'esempio presentato, le particolarità della connessione attraverso la prima porta seriale potrebbero essere inserite nel file /etc/ppp/options.ttyS0
. In pratica, si tratta di definire solo gli indirizzi IP.
192.168.11.1:192.168.11.10
L'esempio si riferisce alla prima porta seriale, e con questo si vuole indicare che l'indirizzo locale è 192.168.11.1, mentre quello all'altro capo della connessione è 192.168.11.10. Volendo sistemare la seconda porta seriale, occorrerebbe creare il file /etc/ppp/options.ttyS1
con il contenuto seguente:
192.168.11.1:192.168.11.11
Per fare in modo che dopo l'identificazione avvenuta tramite una procedura di accesso tradizionale (login) venga attivato il PPP, occorre abbinare agli utenti una shell speciale: uno script che avvia pppd. Questo script potrebbe essere più o meno complesso, per esempio allo scopo di verificare se l'utente ha diritto di accedere in base alle fasce orarie che gli sono state concesse, o secondo altri criteri. Alla fine, si deve avviare pppd chiudendo il processo che interpretava lo script (il comando exec).
#!/bin/sh # # /usr/bin/utente_ppp # /usr/bin/mesg n /bin/stty -tostop # Verifica che l'utente possa accedere. if /usr/sbin/acua_login then # L'utente viene accolto. echo Benvenuto $LOGNAME else # L'utente viene estromesso e gli si dà modo di verificarne il # motivo. /usr/sbin/acua viewRec echo Premere un tasto per continuare read logout fi # Attiva la connessione PPP. echo "Viene attivata la connessione PPP." exec /usr/sbin/pppd crtscts modem noauth refuse-chap refuse-pap \ debug proxyarp idle 600
L'esempio appena mostrato fa riferimento alla possibilità che l'utilizzo di risorse da parte degli utenti sia controllato da Acua (descritto nel capitolo 229). Se il programma acua_login restituisce un valore diverso da zero, viene eseguito il programma logout (cosa produce la conclusione della connessione), e l'utente non può accedere.
Supponendo di avere collocato questo script nella directory /usr/bin/
e di averlo chiamato utente_ppp, si deve abbinare tale file agli utenti, in qualità di shell. Così, nel file /etc/passwd
apparirà qualcosa come nell'esempio seguente:
tizio:x:1001:1001:Tizio Tizi:/home/tizio:/usr/bin/utente_ppp caio:x:1002:1002:Caio Cai:/home/caio:/usr/bin/utente_ppp semproni:x:1003:1003:Sempronio Semproni:/home/semproni:/usr/bin/utente_ppp
Naturalmente, per evitare conflitti con i controlli del sistema di autenticazione, è necessario aggiungere tale shell nell'elenco del file /etc/shells
.
/bin/bash /bin/sh /bin/csh /usr/bin/utente_ppp
È importante tenere presente che in questo modo, il programma pppd deve poter essere avviato dagli utenti comuni; di conseguenza, è necessario attivare il bit SUID e fare in modo che appartenga all'utente root. |
#
chmod u+s /usr/sbin/pppd
#
chown root /usr/sbin/pppd
Il bello della connessione PPP è che il programma pppd provvede da solo a definire le interfacce di rete ppp* e a inserire gli instradamenti corretti. Quindi, se la configurazione di pppd è fatta correttamente, non occorre pensare ad altro.
Il problema rimane semmai nella gestione dell'inoltro dei pacchetti verso le altre interfacce, specialmente verso quella che permette di raggiungere la rete esterna. In pratica, occorre che il kernel del sistema sia disponibile al funzionamento come router, e che il file virtuale /proc/sys/net/ipv4/ip_forward
contenga il valore 1.
#
echo 1 > /proc/sys/net/ipv4/ip_forward
Secondo quanto mostrato fino a questo punto, gli utenti che accedono al servizio PPP attraverso la linea commutata non hanno alcun modo di utilizzare i comandi del sistema operativo. Questa è una cosa positiva: sarebbe difficile dormire sonni tranquilli trovandosi a gestire un centinaio di utenti che se vogliono possono allenarsi a fare i pirati nel proprio elaboratore. Tuttavia, ci sono alcune cose che sarebbe bene tali utenti potessero fare; per esempio: cambiare la password e controllare l'utilizzo delle risorse che gli competono.
Lo script seguente ricalca quello già visto nella sezione precedente, con la differenza che è scritto in Perl, e prima di attivare il PPP viene presentato un menù di opzioni, dove basta un ritorno a carrello aggiuntivo perché il servizio si avvii, ammesso che l'accesso provenga da una linea seriale.
#!/usr/bin/perl #====================================================================== # utente_ppp # # Verifica che l'utente possa accedere, e prima di attivare il PPP # mostra un menù di funzioni varie. # Se il terminale di accesso è di tipo seriale, attiva il PPP #======================================================================= #----------------------------------------------------------------------- # Definisce le variabili che verranno utilizzate. #----------------------------------------------------------------------- $terminale=""; $scelta=""; #----------------------------------------------------------------------- # Impedisce la scrittura sul terminale dell'utente. #----------------------------------------------------------------------- system( "/usr/bin/mesg n" ); system( "/bin/stty -tostop" ); #----------------------------------------------------------------------- # Verifica che l'utente possa accedere (zero corrisponde a falso in # Perl, quindi il risultato va invertito). #----------------------------------------------------------------------- if ( ! system( "/usr/sbin/acua_login" ) ) { #------------------------------------------------------------------- # L'utente viene accolto. #------------------------------------------------------------------- print STDOUT "Benvenuto $ENV{LOGNAME}\n"; } else { #------------------------------------------------------------------- # L'utente viene estromesso e gli si dà modo di verificarne il # motivo. #------------------------------------------------------------------- system( "/usr/bin/acua viewRec $ENV{LOGNAME}" ); #------------------------------------------------------------------- # Gli vengono concessi 15 secondi per leggere lo stato # delle risorse della sua utenza, quindi la connessione viene # interrotta. #------------------------------------------------------------------- print STDOUT "Fra 15 secondi la connessione verrà conclusa.\n"; sleep( 15 ); exit; } #----------------------------------------------------------------------- # Se ha superato i controlli precedenti, l'utente ha diritto di # accedere. Gli si presenta il menù. #----------------------------------------------------------------------- print STDOUT "Premere la lettera corrispondente, seguita da \n"; print STDOUT "Invio, per scegliere l'opzione desiderata, \n"; print STDOUT "oppure premere semplicemente Invio per attivare \n"; print STDOUT "il PPP\n\n"; print STDOUT "P) cambia la parola di accesso (password);\n\n"; print STDOUT "R) visualizza l'utilizzo di risorse;\n\n"; $scelta = getc; if ( $scelta =~ m|p|i ) { system( "/usr/bin/passwd" ); } elsif ( $scelta =~ m|r|i ) { system( "/usr/bin/acua viewRec $ENV{LOGNAME}" ); } #----------------------------------------------------------------------- # Verifica il terminale. #----------------------------------------------------------------------- $terminale=`/usr/bin/tty`; if ( $terminale =~ m|^/dev/ttyS\d+$| ) { #------------------------------------------------------------------- # Attiva la connessione PPP secondo la configurazione. #------------------------------------------------------------------- print STDOUT "Viene attivata la connessione PPP.\n"; exec( "/usr/sbin/pppd crtscts modem noauth refuse-chap refuse-pap debug proxyarp idle 600" ); exit; } else { #------------------------------------------------------------------- # Inutile attivare il PPP da un terminale differente. #------------------------------------------------------------------- print STDOUT "Fra 15 secondi la connessione verrà conclusa.\n"; sleep( 15 ); exit; } #----------------------------------------------------------------------- # Nel caso si riuscisse a raggiungere questo punto, esce. #----------------------------------------------------------------------- exit; #======================================================================
Nello stesso modo in cui viene avviato passwd, o acua, si potrebbe avviare una shell vera e propria, ma questo è meglio evitarlo se non si conoscono perfettamente le conseguenze.
Se si vuole fare in modo che sia il PPP a prendersi cura dell'identificazione di chi accede, bisogna fare un piccolo sforzo per comprendere che non c'è più il sostegno della procedura normale di autenticazione. Cioè non c'è più il sistema Getty + login + shell.
Di solito si utilizza pppd con l'opzione login per fare in modo che riconosca gli utenti registrati nel sistema, senza dover creare appositamente il file /etc/ppp/pap-secrets
(anche se comunque è necessario che questo contenga almeno una voce particolare con cui si accettano tutti i clienti con qualunque segreto).
Il demone pppd deve anche essere in grado di annotare gli accessi nel sistema dei file /var/run/utmp
e /var/log/wtmp
.
Anche se si utilizza un sistema di autenticazione attraverso il PPP, è necessario un altro programma che controlli il modem. Questo è generalmente mgetty (Mgetty+Sendfax), che in più riesce a gestire simultaneamente anche il sistema tradizionale di autenticazione: se si accorge che il cliente che accede si presenta subito con il protocollo PPP, avvia pppd, altrimenti presenta la richiesta di autenticazione tramite una procedura di accesso tradizionale.
Utilizzando GNU/Linux, o comunque un sistema Unix, è improbabile che si voglia gestire un'autenticazione diversa da PAP, dal momento che pppd è in grado di sfruttare le informazioni sugli utenti registrati nel sistema (il file /etc/passwd
) solo con tale protocollo. Comunque, il file /etc/ppp/pap-secrets
deve contenere una voce generica, come nell'esempio seguente:
# Secrets for authentication using PAP # client server secret IP addresses * * "" *
Per quanto riguarda il contenuto del file /etc/ppp/options
, vale quanto già suggerito in precedenza: indicare solo l'indispensabile. Infatti, se si usa Mgetty+Sendfax per consentire sia un'autenticazione tradizionale che quella del PPP, è necessario evitare l'uso di opzioni che possono essere incompatibili con una o con l'altra modalità.
lock ms-dns 192.168.1.1
Per quanto riguarda le altre opzioni necessarie per questo tipo di connessione, occorre tenere presente che l'autenticazione del nodo remoto diventa obbligatoria (auth), inoltre si deve usare il sistema PAP (require-pap) con l'opzione login.
crtscts modem auth require-pap login proxyarp
Per quanto riguarda il problema dell'assegnazione degli indirizzi IP dinamici, vale la stessa configurazione dei file /etc/ppp/options.ttyS*
già descritti per l'uso con il PPP senza autenticazione.
Mgetty+Sendfax è già stato introdotto in più parti di questo documento. Se il cliente si presenta senza tentare una connessione PPP, mgetty richiede un'autenticazione manuale nel modo solito, e alla fine avvia la shell dell'utente come è già stato visto nel caso di uugetty.
Come nel caso di uugetty il problema maggiore è quello di definire una sequenza di comandi per inizializzare correttamente il modem, possibilmente trovando quella che si adatta alla maggior parte dei modelli disponibili. Tuttavia, a questo proposito, l'eseguibile mgetty permette di utilizzare anche la riga di comando, facilitando ancora di più la cosa all'amministratore.
Per abilitare l'avvio automatico del PPP occorre intervenire nel file /etc/mgetty+sendfax/login.config
con un record simile a quello seguente (che viene spezzato per motivi tipografici, ma nella realtà deve utilizzare una sola riga).
# Il record seguente deve utilizzare una sola riga. /AutoPPP/ - a_ppp /usr/sbin/pppd crtscts modem auth refuse-chap require-pap login debug proxyarp idle 600
mgetty può registrare l'avvio di pppd nei file /var/run/utmp
e /var/log/wtmp
. Dal momento che, quando si avvia per rispondere a una chiamata, i privilegi del processo sono quelli dell'utente root, e considerato che mgetty non può sapere chi sia l'utente, se l'autenticazione la fa il PPP si può aggiungere quel nome, a_ppp, nel terzo campo di questo record. Questo verrà usato per segnalare la presenza di un accesso avvenuto in questo modo attraverso programmi come w, who o finger. Se pppd è in grado di fare questa registrazione per conto suo, utilizzando il nominativo acquisito con il protocollo di autenticazione PAP, allora si può sostituire a_ppp con un trattino, -, in modo da evitare che mgetty provveda in questo modo.
Quando si concede di accedere attraverso il PPP, con l'autenticazione PAP che si basa sugli utenti del sistema, i clienti possono presentarsi con l'identità di qualunque utente che abbia una password valida. A volte, questa non è la situazione che si desidera; spesso si usano dei trucchetti basati semplicemente sul tipo di shell che viene assegnata a un utente, per limitarne o impedirne l'accesso.
A fianco di questo problema, si aggiunge la possibile necessità di controllare l'utilizzo delle risorse da parte di questi clienti, cioè degli utenti che sfruttano la connessione PPP. L'unica possibilità offerta da pppd è quella di predisporre lo script /etc/ppp/ip-up
, che tuttavia ha lo svantaggio di essere avviato semplicemente, senza che pppd attenda la sua conclusione per continuare a mantenere la connessione. Qui viene presentato uno script in Perl in grado di verificare che l'utente (il cliente) disponga della shell prevista (precisamente quella che gli permetterebbe una connessione PPP dopo un'autenticazione tradizionale), e quindi di mettere il processo sotto il controllo di Acua. Se per qualche motivo l'utente deve essere estromesso, viene inviato un segnale di interruzione al processo corrispondente a pppd.
#! /usr/bin/perl #======================================================================= # /etc/ppp/ip-up # # Questo script viene avviato dopo che il collegamento IP è stato # instaurato. Purtroppo, pppd non attende la sua conclusione. #======================================================================= #----------------------------------------------------------------------- # Variabili utilizzate. #----------------------------------------------------------------------- $DATA=""; $PPPD_PID=""; $riga = ""; #----------------------------------------------------------------------- # Verrà scandito il file delle password per verificare la shell. #----------------------------------------------------------------------- $FILEIN = "/etc/passwd"; #----------------------------------------------------------------------- # I messaggi vengono emessi nella dodicesima console virtuale. #----------------------------------------------------------------------- $FILEOUT = "/dev/tty12"; #======================================================================= # Inizio del programma. #----------------------------------------------------------------------- #----------------------------------------------------------------------- # La variabile di ambiente PEERNAME contiene il nome utilizzato # per l'autenticazione. Se questa è vuota, significa che è stato # avviato pppd con l'opzione noauth, come nel caso dell'autenticazione # tradizionale. In questa situazione, questo script non serve, e tutto # finisce qui. #----------------------------------------------------------------------- if ( "$ENV{PEERNAME}" eq "" ) { exit; } #----------------------------------------------------------------------- # Prepara un file di messaggi. #----------------------------------------------------------------------- open ( MESSAGGI, ">> $FILEOUT" ); #----------------------------------------------------------------------- # Preleva la data e l'orario attuale. #----------------------------------------------------------------------- $DATA=`/bin/date`; chomp( $DATA ); #----------------------------------------------------------------------- # Preleva il numero del PID di pppd; si tratta del contenuto # del file /var/run/ppp?.pid. # La variabile IFNAME contiene il nome dell'interfaccia di rete # corrispondente (ppp*). #----------------------------------------------------------------------- $PPPD_PID=`cat /var/run/$ENV{IFNAME}.pid`; chomp( $PPPD_PID ); #----------------------------------------------------------------------- # Annota la connessione. #----------------------------------------------------------------------- print MESSAGGI "$DATA $ENV{PEERNAME} $PPPD_PID\n"; #----------------------------------------------------------------------- # Apre il file delle password. #----------------------------------------------------------------------- open ( PASSWD, "< $FILEIN" ); #----------------------------------------------------------------------- # Scandisce tutto il file delle password #----------------------------------------------------------------------- while ( $riga = <PASSWD> ) { #------------------------------------------------------------------- # Estrae i vari elementi del record di /etc/passwd #------------------------------------------------------------------- if ( $riga =~ m|^ *(.*):(.*):(.*):(.*):(.*):(.*):(.*) *$| ) { $utente = $1; $password = $2; $uid = $3; $gid = $4; $finger = $5; $home = $6; $shell = $7; #--------------------------------------------------------------- # Controlla se si tratta dell'utente. #--------------------------------------------------------------- if ( "$utente" eq "$ENV{PEERNAME}" ) { #----------------------------------------------------------- # Si tratta dell'utente giusto, adesso si controlla # se la shell è quella consentita. #----------------------------------------------------------- if ( "$shell" eq "/usr/bin/utente_ppp" ) { #------------------------------------------------------- # Il prossimo problema è Acua. # Verifica che l'utente possa accedere (zero # corrisponde a falso in Perl, quindi il risultato va # invertito. # La variabile DEVICE contiene il percorso assoluto # del dispositivo utilizzato per la connessione. # Questo è il modo indicato dalla documentazione di # Acua per individuare l'attività dell'utente, quando # si deve usare pppd per l'autenticazione. #------------------------------------------------------- if ( ! system( "/usr/sbin/acua_login < $ENV{DEVICE}" ) ) { #--------------------------------------------------- # Se pppd non annota correttamente l'utente, # cioè il cliente, nel file /var/log/wtmp, # Acua non consente l'accesso! #--------------------------------------------------- #--------------------------------------------------- # L'utente viene accolto. #--------------------------------------------------- print MESSAGGI "$ENV{PEERNAME} accettato da ACUA\n"; close ( PASSWD ); close ( MESSAGGI ); exit; } else { #--------------------------------------------------- # L'utente viene estromesso. #--------------------------------------------------- kill 15, "$PPPD_PID"; print MESSAGGI "$ENV{PEERNAME} ESTROMESSO: ACUA\n"; close ( PASSWD ); close ( MESSAGGI ); exit; } } else { #------------------------------------------------------- # La shell non è valida. L'utente viene estromesso. #------------------------------------------------------- kill 15, "$PPPD_PID"; print MESSAGGI "$ENV{PEERNAME} ESTROMESSO: SHELL\n"; close ( PASSWD ); close ( MESSAGGI ); exit; } } } } #----------------------------------------------------------------------- # Se siamo qui, vuol dire che l'utente non c'è nel file passwd! #----------------------------------------------------------------------- kill 15, "$PPPD_PID"; print MESSAGGI "$ENV{PEERNAME} L'UTENTE NON C'E` NEL FILE /etc/passwd\n"; close ( PASSWD ); close ( MESSAGGI ); #======================================================================= # Fine #=======================================================================Appunti di informatica libera 2000.07.31 --- Copyright © 2000 Daniele Giacomini -- daniele @ swlibero.org
1) Da quanto si legge nella documentazione di pppd, questo è predisposto per annotare esclusivamente le connessioni autenticate attraverso il protocollo PAP con l'opzione login, e ciò solo nel file /var/log/wtmp
. A quanto pare, alcune versioni che utilizzano le librerie PAM non fanno nemmeno questo. Purtroppo si tratta di un grosso problema, che si spera sia risolto al più presto.