]> git.ozlabs.org Git - ppp.git/commitdiff
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.
  */
 
  * 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>
 
 #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;
 
    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;
 
 /* 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  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 *));
 
 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 },
 
       "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 }
 };
 
     { 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.
 /*
  * 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;
 }
 
     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.
  */
 /*
  * 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.
  */
 
  * 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>
 
 #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) */
 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;
 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();
        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.
      */
     /*
      * Initialize system-dependent stuff.
      */
index 339dde77d569a6859bf6e8b5b107004912235f29..91ea477be53821ae787725acf8e3ed587c7ecf40 100644 (file)
@@ -1,5 +1,5 @@
 .\" manual page [] for pppd 2.4
 .\" 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
 .\" 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
 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
 .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
 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.
 .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.
  *
  * 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 */
                                /* 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 */
 
 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
 #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
 
 /*
  * Debug macros.  Slightly useful for finding bugs in pppd, not particularly