From: Frank Cusack Date: Thu, 10 Oct 2002 05:47:34 +0000 (+0000) Subject: Add 'remotenumber' and 'allow-number' options, for CNID purposes. X-Git-Tag: ppp-2.4.7~374 X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=93b9f7ad08d5f0ee16880ec2b21b1c13a00d4779 Add 'remotenumber' and 'allow-number' options, for CNID purposes. In practice, the admin can configure allow-number settings, and getty or other programs can call ppp with the remotenumber option. remotenumber is also available to plugins; for example the radius plugin will pass this on as the Calling-Station-Id attribute and the radius server can make an authentication decision based on that. --- diff --git a/pppd/auth.c b/pppd/auth.c index 5af2ee0..d2b0c9f 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -32,7 +32,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: auth.c,v 1.84 2002/09/24 11:35:22 fcusack Exp $" +#define RCSID "$Id: auth.c,v 1.85 2002/10/10 05:47:34 fcusack Exp $" #include #include @@ -106,6 +106,12 @@ static struct permitted_ip *addresses[NUM_PPP]; without authenticating itself. */ static struct wordlist *noauth_addrs; +/* Remote telephone number, if available */ +char remote_number[MAXNAMELEN]; + +/* Wordlist giving remote telephone numbers which may connect. */ +static struct wordlist *permitted_numbers; + /* Extra options to apply, from the secrets file entry for the peer. */ static struct wordlist *extra_options; @@ -214,6 +220,7 @@ static int some_ip_ok __P((struct wordlist *)); static int setupapfile __P((char **)); static int privgroup __P((char **)); static int set_noauth_addr __P((char **)); +static int set_permitted_number __P((char **)); static void check_access __P((FILE *, char *)); static int wordlist_count __P((struct wordlist *)); @@ -329,6 +336,14 @@ option_t auth_options[] = { "Set IP address(es) which can be used without authentication", OPT_PRIV | OPT_A2LIST }, + { "remotenumber", o_string, remote_number, + "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC, + NULL, MAXNAMELEN }, + + { "allow-number", o_special, (void *)set_permitted_number, + "Set telephone number(s) which are allowed to connect", + OPT_PRIV | OPT_A2LIST }, + { NULL } }; @@ -433,6 +448,28 @@ set_noauth_addr(argv) } +/* + * set_permitted_number - set remote telephone number(s) that may connect. + */ +static int +set_permitted_number(argv) + char **argv; +{ + char *number = *argv; + int l = strlen(number) + 1; + struct wordlist *wp; + + wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); + if (wp == NULL) + novm("allow-number argument"); + wp->word = (char *) (wp + 1); + wp->next = permitted_numbers; + BCOPY(number, wp->word, l); + permitted_numbers = wp; + return 1; +} + + /* * An Open on LCP has requested a change from Dead to Establish phase. * Do what's necessary to bring the physical layer up. @@ -1892,6 +1929,35 @@ some_ip_ok(addrs) return 0; } +/* + * auth_number - check whether the remote number is allowed to connect. + * Returns 1 if authorized, 0 otherwise. + */ +int +auth_number() +{ + struct wordlist *wp = permitted_numbers; + int l; + + /* Allow all if no authorization list. */ + if (!wp) + return 1; + + /* Allow if we have a match in the authorization list. */ + while (wp) { + /* trailing '*' wildcard */ + l = strlen(wp->word); + if ((wp->word)[l - 1] == '*') + l--; + if (!strncasecmp(wp->word, remote_number, l)) + return 1; + } + wp = wp->next; + } + + return 0; +} + /* * check_access - complain if a secret file has too-liberal permissions. */ diff --git a/pppd/main.c b/pppd/main.c index c6ba438..4fb985b 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: main.c,v 1.113 2002/05/21 17:26:49 dfs Exp $" +#define RCSID "$Id: main.c,v 1.114 2002/10/10 05:47:34 fcusack Exp $" #include #include @@ -84,7 +84,6 @@ char hostname[MAXNAMELEN]; /* Our hostname */ static char pidfilename[MAXPATHLEN]; /* name of pid file */ static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ -char remote_number[MAXNAMELEN]; /* Remote telephone number, if available */ uid_t uid; /* Our real user-id */ struct notifier *pidchange = NULL; struct notifier *phasechange = NULL; @@ -361,10 +360,19 @@ main(argc, argv) init_pr_log(NULL, LOG_INFO); print_options(pr_log, NULL); end_pr_log(); - if (dryrun) - die(0); } + /* + * Early check for remote number authorization. + */ + if (!auth_number()) { + error("remote number %s is not authorized", remote_number); + exit(EXIT_CNID_AUTH_FAILED); + } + + if (dryrun) + die(0); + /* * Initialize system-dependent stuff. */ diff --git a/pppd/pppd.8 b/pppd/pppd.8 index 339dde7..91ea477 100644 --- a/pppd/pppd.8 +++ b/pppd/pppd.8 @@ -1,5 +1,5 @@ .\" manual page [] for pppd 2.4 -.\" $Id: pppd.8,v 1.65 2002/09/20 06:53:19 fcusack Exp $ +.\" $Id: pppd.8,v 1.66 2002/10/10 05:47:34 fcusack Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph @@ -200,6 +200,10 @@ authenticating themselves. The parameter is parsed as for each element of the list of allowed IP addresses in the secrets files (see the AUTHENTICATION section below). .TP +.B allow-number \fInumber +Allow peers to connect from the given telephone number. A trailing +`*' character will match all numbers beginning with the leading part. +.TP .B bsdcomp \fInr,nt Request that the peer compress packets that it sends, using the BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and @@ -865,6 +869,10 @@ displayed in readable form using the pppdump(8) program. Set the assumed name of the remote system for authentication purposes to \fIname\fR. .TP +.B remotenumber \fInumber +Set the assumed telephone number of the remote system for authentication +purposes to \fInumber\fR. +.TP .B refuse-chap With this option, pppd will not agree to authenticate itself to the peer using CHAP. diff --git a/pppd/pppd.h b/pppd/pppd.h index 493f86e..90f7446 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -16,7 +16,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: pppd.h,v 1.74 2002/09/24 11:35:22 fcusack Exp $ + * $Id: pppd.h,v 1.75 2002/10/10 05:47:34 fcusack Exp $ */ /* @@ -516,6 +516,7 @@ int get_secret __P((int, char *, char *, char *, int *, int)); /* get "secret" for chap */ int auth_ip_addr __P((int, u_int32_t)); /* check if IP address is authorized */ +int auth_number __P((void)); /* check if remote number is authorized */ int bad_ip_adrs __P((u_int32_t)); /* check if IP address is unreasonable */ @@ -755,6 +756,7 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len)); #ifdef MAXOCTETS #define EXIT_TRAFFIC_LIMIT 20 #endif +#define EXIT_CNID_AUTH_FAILED 21 /* * Debug macros. Slightly useful for finding bugs in pppd, not particularly