Add 'remotenumber' and 'allow-number' options, for CNID purposes.
authorFrank Cusack <fcusack@fcusack.com>
Thu, 10 Oct 2002 05:47:34 +0000 (05:47 +0000)
committerFrank Cusack <fcusack@fcusack.com>
Thu, 10 Oct 2002 05:47:34 +0000 (05:47 +0000)
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.

pppd/auth.c
pppd/main.c
pppd/pppd.8
pppd/pppd.h

index 5af2ee0f483f501a707711df1b490dd249e3c9d7..d2b0c9f04995f41e5761f0946ce429a04c51626b 100644 (file)
@@ -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 <stdio.h>
 #include <stddef.h>
@@ -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.
  */
index c6ba438a43576f021ce86721a0171a51b55d043b..4fb985b89a010440c86bb6bf367604afae3b6448 100644 (file)
@@ -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 <stdio.h>
 #include <ctype.h>
@@ -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.
      */
index 339dde77d569a6859bf6e8b5b107004912235f29..91ea477be53821ae787725acf8e3ed587c7ecf40 100644 (file)
@@ -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.
index 493f86ef3d73e4b21c9f037dde0c9dcb84d61e5a..90f74466bea38c3674d9428b14bf9adab34857e4 100644 (file)
@@ -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