Subject: Opie and SunOS 4.1.x C2 security support patch for wu-ftpd-2.4.2 beta 13

From: [email-masked] (KOJIMA Hajime)
Date: Fri, 21 Mar 1997 15:11:06 +0900

Opie and SunOS 4.1.x C2 security (/etc/security/passwd.adjunct)
---------------------------------------------------------------
support patch for academ version of wu-ftpd-2.4.2 beta 13
---------------------------------------------------------

* -DOPIE for opie support, based on S/Key support of wu-ftpd-2.4.2 
  beta 12.
  If you want to use -DOPIE with opie 2.22 or berofe, define both
  -DOPIE and -DBEFORE_OPIE_2_3.  I STRONGLY RECOMMEND to use with
  opie 2.31 or later, because 2.3 or berofe has SERIOUS lock bug.

  If you enable -DOPIE, normal UNIX password is disabled.

* -DSUN_C2_SECURITY for SunOS 4.1.x C2 security 
  (/etc/security/passwd.adjunct) supoort.

* tested: SunOS 4.1.3_U1 with JLE (Japanese Language Environment) 1.1.3,
  opie 2.31-test8 + own patch

Have fun!

----
KOJIMA Hajime - Ryukoku Univ., Seta, Ohtu, Shiga, Japan
[Office] [email-masked]
         Phone: +81-775-43-7414  Fax: +81-775-43-0706
[Home]   [email-masked]
         [email-masked]

--- /home/kjm/wu-ftpd-2.4.2-beta-13/src/ftpd.c	Mon Mar  3 18:39:56 1997
+++ ftpd.c	Mon Mar 17 12:14:04 1997
@@ -340,6 +340,11 @@
 #include <skey.h>
 int	pwok = 0;
 #endif
+#ifdef OPIE
+#include "opie.h"
+struct opie opie_blk;
+char chbuff[OPIE_CHALLENGE_MAX];
+#endif
 
 #ifdef KERBEROS
 void init_krb();
@@ -946,7 +951,33 @@
     else
        save.pw_passwd = sgetsave("");
 #else
+# ifdef SUN_C2_SECURITY
+#  define PASSWD_ADJUNCT        "/etc/security/passwd.adjunct"
+    if (strlen(p->pw_passwd) > 2 && strncmp(p->pw_passwd, "##", 2) == 0) {
+	char linebuf[BUFSIZ];
+	FILE *fp;
+
+	if ((fp = fopen(PASSWD_ADJUNCT, "r")) == NULL) {
+	    syslog(LOG_DEBUG, "fopen(PASSWD_ADJUNCT)");
+	    exit(1);
+	}
+
+	while (fgets(linebuf, BUFSIZ, fp) != NULL) {
+	    char *hit, *next;
+	    
+	    if ((hit = strtok(linebuf, ":")) != NULL) {
+		if (strcmp(hit, p->pw_name) == 0 && (next = strtok(NULL, ":")) != NULL) {
+		    save.pw_passwd = sgetsave(next);
+		    break;
+		}
+	    }
+	}
+	fclose(fp);
+    } else
+	save.pw_passwd = sgetsave(p->pw_passwd);
+# else
     save.pw_passwd = sgetsave(p->pw_passwd);
+# endif
 #endif
 #ifdef SHADOW_PASSWORD
         if (p) {
@@ -1255,7 +1286,12 @@
     pwok = skeyaccess(name, NULL, remotehost, remoteaddr);
     reply(331, "%s", skey_challenge(name, pw, pwok));
 #else
+# ifdef OPIE
+    opiechallenge (&opie_blk, name, chbuff);
+    reply (331, "[%s] required for %s.", chbuff, name);
+# else
     reply(331, "Password required for %s.", name);
+# endif
 #endif
     askpasswd = 1;
     /* Delay before reading passwd after first failed attempt to slow down
@@ -1395,6 +1431,17 @@
         if (*passwd == '-')
             passwd++;
         *guestpw = '\0';
+#ifdef OPIE
+	xpasswd = "wrongo:spazmoid";		/* disable normal password */
+# ifdef BEFORE_OPIE_2_3
+	if (opie_blk.keyfile) {
+# endif
+	    if (opieverify (&opie_blk, passwd) == 0)
+		strcpy (xpasswd, pw->pw_passwd);	/* do it the sleazy way */
+# ifdef BEFORE_OPIE_2_3
+	}
+# endif
+#else /* OPIE */
         if (pw == NULL)
             salt = "xx"; /* XXX */
         else
@@ -1413,6 +1460,7 @@
 #endif
 #endif
 #endif
+#endif /* OPIE */
 #ifdef ULTRIX_AUTH
         if ((numfails = ultrix_check_pass(passwd, xpasswd)) < 0) {
 #else