* 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.88 2002/10/27 12:56:26 fcusack Exp $"
#include <stdio.h>
#include <stddef.h>
#include <sys/socket.h>
#include <utmp.h>
#include <fcntl.h>
-#if defined(_PATH_LASTLOG) && defined(_linux_)
+#if defined(_PATH_LASTLOG) && defined(__linux__)
#include <lastlog.h>
#endif
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;
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 *));
"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 }
};
}
+/*
+ * 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.
{
lcp_options *go = &lcp_gotoptions[unit];
+ /* Log calling number. */
+ if (*remote_number)
+ notice("peer from calling number %q authorized", remote_number);
+
/*
* If the peer had to authenticate, run the auth-up script now.
*/
ret = UPAP_AUTHACK;
if (uselogin || login_secret) {
/* login option or secret is @login */
- ret = plogin(user, passwd, msg);
- if (ret == UPAP_AUTHNAK)
- warn("PAP login failure for %s", user);
- else
+ if ((ret = plogin(user, passwd, msg)) == UPAP_AUTHACK)
used_login = 1;
}
if (secret[0] != 0 && !login_secret) {
/* password given in pap-secrets - must match */
if ((cryptpap || strcmp(passwd, secret) != 0)
- && strcmp(crypt(passwd, secret), secret) != 0) {
+ && strcmp(crypt(passwd, secret), secret) != 0)
ret = UPAP_AUTHNAK;
- warn("PAP authentication failure for %s", user);
- }
}
}
fclose(f);
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.
*/