From muir@idiom.com  Mon Feb 12 02:35:20 1996
Received: from idiom.com (idiom.com [140.174.82.4])
          by freefall.freebsd.org (8.7.3/8.7.3) with SMTP id CAA13408
          for <FreeBSD-gnats-submit@freebsd.org>; Mon, 12 Feb 1996 02:35:19 -0800 (PST)
Received: (from muir@localhost) by idiom.com (8.6.12/8.6.12) id CAA10465; Mon, 12 Feb 1996 02:35:18 -0800
Message-Id: <199602121035.CAA10465@idiom.com>
Date: Mon, 12 Feb 1996 02:35:18 -0800
From: David Muir Sharnoff <muir@idiom.com>
Reply-To: muir@idiom.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: pppd doesn't handle PAP-only authentication well
X-Send-Pr-Version: 3.2

>Number:         1021
>Category:       bin
>Synopsis:       pppd doesn't handle PAP-only authentication well
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    phk
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 12 02:40:01 PST 1996
>Closed-Date:    Mon May 25 00:31:12 PDT 1998
>Last-Modified:  Mon May 25 00:31:29 PDT 1998
>Originator:     David Muir Sharnoff
>Release:        FreeBSD 2.1-STABLE i386
>Organization:
Idiom Consulting - ISP, http://www.idiom.com
>Environment:

	Requirements:

	1. Authenticate users based solely on /etc/passwd
	2. Don't allow accounts w/o passwords to connect
	3. Don't allow accounts w/o valid shells to connect
	4. Choose local & remote IP addresses and netmasks
		from the login

>Description:

	Trying to run an ISP on FreeBSD...

>How-To-Repeat:


>Fix:
	
	Make the following changes to pppd.  Sorry, not documented and
	not based on the newest version of pppd.

	Basic idea: after verifying a password, exec /etc/ppp/ip-login
	and treat its output as an options file.

	I'm not distributing my /etc/ppp/ip-login file, but it might
	be available to those who ask.

diff -r -c pppd/auth.c idiompppd/auth.c
*** pppd/auth.c	Sat Sep  2 07:52:54 1995
--- idiompppd/auth.c	Mon Feb 12 01:14:30 1996
***************
*** 360,365 ****
--- 360,369 ----
      char passwd[256], user[256];
      char secret[MAXWORDLEN];
      static int attempts = 0;
+     struct stat s_loginopts;
+     int code;
+     char cmd[1024];
+     extern int baud_rate;
  
      /*
       * Make copies of apasswd and auser, then null-terminate them.
***************
*** 399,404 ****
--- 403,430 ----
  	if (ret == UPAP_AUTHNAK) {
  	    syslog(LOG_WARNING, "upap login failure for %s", user);
  	}
+ 
+ 	code = stat(_PATH_IPOPT, &s_loginopts);
+ 
+ 	if (ret == UPAP_AUTHACK && code == 0) {
+ 
+ 	    sprintf(cmd, "%s %s %s %d '%s' %d", _PATH_IPOPT, ifname, devname, baud_rate, user, strlen(passwd) != 0);
+ 	    f = popen(cmd, "r");
+ 	    if (f == NULL) {
+ 		syslog(LOG_ERR, "popen %s: %m", cmd);
+ 		ret = UPAP_AUTHNAK;
+ 	    } else {
+ 		read_options_stream(f, cmd);
+ 		code = pclose(f);
+ 		if (code == -1) {
+ 		    syslog(LOG_ERR, "pclose %s: %m", cmd);
+ 		    ret = UPAP_AUTHNAK;
+ 		} else if (code != 0) {
+ 		    syslog(LOG_WARNING, "%s %s returned %d - access denied", _PATH_IPOPT, user, code);
+ 		    ret = UPAP_AUTHNAK;
+ 		} 
+ 	    }
+ 	}
      }
  
      if (ret == UPAP_AUTHNAK) {
***************
*** 459,488 ****
      if (pw->pw_expire && time(NULL) >= pw->pw_expire)
  	return (UPAP_AUTHNAK);
  
-     /*
-      * XXX If no passwd, let them login without one.
-      */
-     if (pw->pw_passwd == '\0') {
- 	return (UPAP_AUTHACK);
-     }
- 
      epasswd = crypt(passwd, pw->pw_passwd);
      if (strcmp(epasswd, pw->pw_passwd)) {
  	return (UPAP_AUTHNAK);
      }
  
      syslog(LOG_INFO, "user %s logged in", user);
- 
-     /*
-      * Write a wtmp entry for this user.
-      */
-     tty = strrchr(devname, '/');
-     if (tty == NULL)
- 	tty = devname;
-     else
- 	tty++;
-     logwtmp(tty, user, "");		/* Add wtmp login entry */
-     logged_in = TRUE;
  
      return (UPAP_AUTHACK);
  }
--- 485,496 ----
diff -r -c pppd/options.c idiompppd/options.c
*** pppd/options.c	Fri Oct  6 08:10:14 1995
--- idiompppd/options.c	Mon Feb 12 00:06:24 1996
***************
*** 319,328 ****
  	    progname);
  }
  
- /*
-  * options_from_file - Read a string of options from a file,
-  * and interpret them.
-  */
  int
  options_from_file(filename, must_exist, check_prot)
      char *filename;
--- 319,324 ----
***************
*** 330,340 ****
      int check_prot;
  {
      FILE *f;
!     int i, newline, ret;
!     struct cmd *cmdp;
!     char *argv[MAXARGS];
!     char args[MAXARGS][MAXWORDLEN];
!     char cmd[MAXWORDLEN];
  
      if ((f = fopen(filename, "r")) == NULL) {
  	if (!must_exist && errno == ENOENT)
--- 326,332 ----
      int check_prot;
  {
      FILE *f;
!     int	ret;
  
      if ((f = fopen(filename, "r")) == NULL) {
  	if (!must_exist && errno == ENOENT)
***************
*** 348,353 ****
--- 340,366 ----
  	return 0;
      }
  
+     ret = read_options_stream(f, filename);
+     fclose(f);
+     return (ret);
+ }
+ 
+ 
+ /*
+  * options_from_file - Read a string of options from a file,
+  * and interpret them.
+  */
+ int
+ read_options_stream(f, filename)
+     FILE *f;
+     char *filename;
+ {
+     int i, newline, ret;
+     struct cmd *cmdp;
+     char *argv[MAXARGS];
+     char args[MAXARGS][MAXWORDLEN];
+     char cmd[MAXWORDLEN];
+ 
      while (getword(f, cmd, &newline, filename)) {
  	/*
  	 * First see if it's a command.
***************
*** 362,374 ****
  		    fprintf(stderr,
  			    "In file %s: too few parameters for command %s\n",
  			    filename, cmd);
- 		    fclose(f);
  		    return 0;
  		}
  		argv[i] = args[i];
  	    }
  	    if (!(*cmdp->cmd_func)(argv)) {
- 		fclose(f);
  		return 0;
  	    }
  
--- 375,385 ----
***************
*** 381,387 ****
  		&& (ret = setipaddr(cmd)) == 0) {
  		fprintf(stderr, "In file %s: unrecognized command %s\n",
  			filename, cmd);
- 		fclose(f);
  		return 0;
  	    }
  	    if (ret < 0)	/* error */
--- 392,397 ----
diff -r -c pppd/pathnames.h idiompppd/pathnames.h
*** pppd/pathnames.h	Sat Sep 24 19:32:10 1994
--- idiompppd/pathnames.h	Sun Feb 11 23:59:45 1996
***************
*** 16,19 ****
--- 16,20 ----
  #define _PATH_IPUP	"/etc/ppp/ip-up"
  #define _PATH_IPDOWN	"/etc/ppp/ip-down"
  #define _PATH_TTYOPT	"/etc/ppp/options."
+ #define _PATH_IPOPT	"/etc/ppp/ip-login"
  #define _PATH_USEROPT	".ppprc"
>Release-Note:
>Audit-Trail:

Originator reports:
The pppd development team seems to be working on doing something to
address the concerns that I have.  Their fixes have not made it into
FreeBSD as far as I know.

Responsible-Changed-From-To: freebsd-bugs->phk 
Responsible-Changed-By: scrappy 
Responsible-Changed-When: Wed Apr 17 16:24:52 PDT 1996 
Responsible-Changed-Why:  
phk seems to have done recent work on this...see note in Audit-Trail: 
State-Changed-From-To: open->closed 
State-Changed-By: phk 
State-Changed-When: Mon May 25 00:31:12 PDT 1998 
State-Changed-Why:  


As part of our PR auditing campaign, this PR has been closed due to it's 
age and lack of activity on the PR. 

There is a good chance that the problem reported have been solved 
as part of other activities. 

If this is not the case, please reopen this PR with fresh information 
on the manifestation of the bug. 

Sorry about the late reaction to this PR. 
>Unformatted:
