Attached is a patch that adds support for netkey challenge/response authentication to lftp.

For those not familiar, the netkey protocol performs authentication by asking the client to encrypt a challenge made by the server with a key that is a function of the user's password. The encrypted challenge is then sent over the wire to perform authentication. It's the same algorithm that a SecureNet device would use.

The plan9 and inferno OSes use netkey authentication with their ftp servers and this patch allows interoperability with those servers.

I hope it's acceptable.

Thanks,
Ryan Thomas
diff -up lftp/src/ftpclass.cc.netkey lftp/src/ftpclass.cc
--- lftp/src/ftpclass.cc.netkey 2009-02-02 12:09:16.427541556 -0500
+++ lftp/src/ftpclass.cc        2009-02-02 12:14:26.365545129 -0500
@@ -473,6 +473,11 @@ void Ftp::NoPassReqCheck(int act) // for
         return;
       }
    }
+   if(act==331 && allow_netkey && user && pass)
+   {
+      netkey_pass.set(make_netkey_reply());
+   }
+
    if(is3XX(act))
       return;
    if(act==530)          // no such user or overloaded server
@@ -940,6 +945,7 @@ void Ftp::InitFtp()
    state=INITIAL_STATE;
    flags=SYNC_MODE;
    allow_skey=true;
+   allow_netkey=true;
    force_skey=false;
    verify_data_address=true;
    use_stat=true;
@@ -1424,6 +1430,7 @@ int   Ftp::Do()
       }
 
       skey_pass.set(0);
+      netkey_pass.set(0);
 
       expect->Push(Expect::USER);
       conn->SendCmd2("USER",user_to_use);
@@ -1448,10 +1455,12 @@ int   Ftp::Do()
       const char *proxy_auth_type=Query("proxy-auth-type",proxy);
       if(!conn->ignore_pass)
       {
-        conn->may_show_password = (skey_pass!=0) || (user==0) || pass_open;
+       conn->may_show_password = (skey_pass!=0) || (netkey_pass!=0) || 
(user==0) || pass_open;
         const char *pass_to_use=(pass?pass:anon_pass);
         if(allow_skey && skey_pass)
            pass_to_use=skey_pass;
+        else if(allow_netkey && netkey_pass)
+           pass_to_use=netkey_pass;
         else if(proxy && !conn->proxy_is_http && proxy_user && proxy_pass
         && !strcmp(proxy_auth_type,"joined"))
            pass_to_use=xstring::cat(pass_to_use,"@",proxy_pass.get(),NULL);
@@ -4418,6 +4427,7 @@ void Ftp::Reconfig(const char *name)
 
    allow_skey = QueryBool("skey-allow");
    force_skey = QueryBool("skey-force");
+   allow_netkey = QueryBool("netkey-allow");
    verify_data_address = QueryBool("verify-address");
    verify_data_port = QueryBool("verify-port");
 
@@ -4609,6 +4619,42 @@ const char *Ftp::make_skey_reply()
    return calculate_skey_response(skey_sequence,buf,pass);
 }
 
+extern "C"
+   const char *calculate_netkey_response (const char *, const char *);
+
+const char *Ftp::make_netkey_reply()
+{
+   static const char * const netkey_head[] = {
+      "encrypt challenge, ",
+      0
+   };
+
+   const char *cp;
+   for(int i=0; ; i++)
+   {
+      if(netkey_head[i]==0)
+        return 0;
+      cp=strstr(all_lines,netkey_head[i]);
+      if(cp)
+      {
+        cp+=strlen(netkey_head[i]);
+        break;
+      }
+   }
+
+
+   if(cp) {
+          char buf[32];
+          int challenge_len = strcspn( cp, ", ");
+
+          strncpy( buf, cp, challenge_len );
+          buf[challenge_len]=0;
+          LogNote(9,"found netkey challenge %s", buf);
+          return calculate_netkey_response(pass.get(), buf);
+   }
+   return 0;
+}
+
 int Ftp::Buffered()
 {
    if(!conn || !conn->data_iobuf)
diff -up lftp/src/ftpclass.h.netkey lftp/src/ftpclass.h
--- lftp/src/ftpclass.h.netkey  2009-02-02 12:09:16.615544021 -0500
+++ lftp/src/ftpclass.h 2009-02-02 12:10:08.305895851 -0500
@@ -366,6 +366,10 @@ private:
    bool force_skey;
    const char *make_skey_reply();
 
+   xstring netkey_pass;
+   bool allow_netkey;
+   const char *make_netkey_reply();
+
    bool disconnect_on_close;
 
 public:
diff -up lftp/src/Makefile.am.netkey lftp/src/Makefile.am
--- lftp/src/Makefile.am.netkey 2009-02-02 12:09:13.946832944 -0500
+++ lftp/src/Makefile.am        2009-02-02 12:16:34.983982149 -0500
@@ -29,7 +29,7 @@ endif
 lib_LTLIBRARIES = liblftp-tasks.la liblftp-jobs.la
 
 proto_ftp_la_SOURCES  = ftpclass.cc ftpclass.h FtpListInfo.cc FtpListInfo.h\
- FtpDirList.cc FtpDirList.h ftp-opie.c FileCopyFtp.cc FileCopyFtp.h
+ FtpDirList.cc FtpDirList.h ftp-opie.c netkey.c FileCopyFtp.cc FileCopyFtp.h
 proto_http_la_SOURCES = Http.cc Http.h HttpDir.cc HttpDir.h HttpDirXML.cc
 proto_file_la_SOURCES = LocalAccess.cc LocalAccess.h
 proto_fish_la_SOURCES = Fish.cc Fish.h
diff -up lftp/src/netkey.c.netkey lftp/src/netkey.c
--- lftp/src/netkey.c.netkey    2009-02-02 12:10:11.765739504 -0500
+++ lftp/src/netkey.c   2009-02-02 12:10:11.765739504 -0500
@@ -0,0 +1,482 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+extern long read(int, void*, long);
+typedef unsigned char uchar;
+#define NAMELEN 28
+
+enum
+{
+  DESKEYLEN=      7,              /* length of a des key for encrypt/decrypt */
+  CHALLEN=     8,              /* length of a challenge */
+  NETCHLEN=    16,             /* max network challenge length */
+};
+
+
+/************ crypt.c *************/
+/*
+ *     Data Encryption Standard
+ *     D.P.Mitchell  83/06/08.
+ *
+ *     block_cipher(key, block, decrypting)
+ */
+static int     ip_low(char [8]);
+static int     ip_high(char [8]);
+static void    fp(int, int, char[8]);
+static void    key_setup(char[DESKEYLEN], char[128]);
+static void    block_cipher(char[128], char[8], int);
+
+/*
+ * destructively encrypt the buffer, which
+ * must be at least 8 characters long.
+ */
+int
+encrypt9(void *key, void *vbuf, int n)
+{
+       char ekey[128], *buf;
+       int i, r;
+
+       if(n < 8)
+               return 0;
+       key_setup(key, ekey);
+       buf = vbuf;
+       n--;
+       r = n % 7;
+       n /= 7;
+       for(i = 0; i < n; i++){
+               block_cipher(ekey, buf, 0);
+               buf += 7;
+       }
+       if(r)
+               block_cipher(ekey, buf - 7 + r, 0);
+       return 1;
+}
+
+/*
+ * destructively decrypt the buffer, which
+ * must be at least 8 characters long.
+ */
+int
+decrypt(void *key, void *vbuf, int n)
+{
+       char ekey[128], *buf;
+       int i, r;
+
+       if(n < 8)
+               return 0;
+       key_setup(key, ekey);
+       buf = vbuf;
+       n--;
+       r = n % 7;
+       n /= 7;
+       buf += n * 7;
+       if(r)
+               block_cipher(ekey, buf - 7 + r, 1);
+       for(i = 0; i < n; i++){
+               buf -= 7;
+               block_cipher(ekey, buf, 1);
+       }
+       return 1;
+}
+
+/*
+ *     Tables for Combined S and P Boxes
+ */
+
+static int  s0p[] = {
+0x00410100,0x00010000,0x40400000,0x40410100,0x00400000,0x40010100,0x40010000,0x40400000,
+0x40010100,0x00410100,0x00410000,0x40000100,0x40400100,0x00400000,0x00000000,0x40010000,
+0x00010000,0x40000000,0x00400100,0x00010100,0x40410100,0x00410000,0x40000100,0x00400100,
+0x40000000,0x00000100,0x00010100,0x40410000,0x00000100,0x40400100,0x40410000,0x00000000,
+0x00000000,0x40410100,0x00400100,0x40010000,0x00410100,0x00010000,0x40000100,0x00400100,
+0x40410000,0x00000100,0x00010100,0x40400000,0x40010100,0x40000000,0x40400000,0x00410000,
+0x40410100,0x00010100,0x00410000,0x40400100,0x00400000,0x40000100,0x40010000,0x00000000,
+0x00010000,0x00400000,0x40400100,0x00410100,0x40000000,0x40410000,0x00000100,0x40010100,
+};
+
+static int  s1p[] = {
+0x08021002,0x00000000,0x00021000,0x08020000,0x08000002,0x00001002,0x08001000,0x00021000,
+0x00001000,0x08020002,0x00000002,0x08001000,0x00020002,0x08021000,0x08020000,0x00000002,
+0x00020000,0x08001002,0x08020002,0x00001000,0x00021002,0x08000000,0x00000000,0x00020002,
+0x08001002,0x00021002,0x08021000,0x08000002,0x08000000,0x00020000,0x00001002,0x08021002,
+0x00020002,0x08021000,0x08001000,0x00021002,0x08021002,0x00020002,0x08000002,0x00000000,
+0x08000000,0x00001002,0x00020000,0x08020002,0x00001000,0x08000000,0x00021002,0x08001002,
+0x08021000,0x00001000,0x00000000,0x08000002,0x00000002,0x08021002,0x00021000,0x08020000,
+0x08020002,0x00020000,0x00001002,0x08001000,0x08001002,0x00000002,0x08020000,0x00021000,
+};
+
+static int  s2p[] = {
+0x20800000,0x00808020,0x00000020,0x20800020,0x20008000,0x00800000,0x20800020,0x00008020,
+0x00800020,0x00008000,0x00808000,0x20000000,0x20808020,0x20000020,0x20000000,0x20808000,
+0x00000000,0x20008000,0x00808020,0x00000020,0x20000020,0x20808020,0x00008000,0x20800000,
+0x20808000,0x00800020,0x20008020,0x00808000,0x00008020,0x00000000,0x00800000,0x20008020,
+0x00808020,0x00000020,0x20000000,0x00008000,0x20000020,0x20008000,0x00808000,0x20800020,
+0x00000000,0x00808020,0x00008020,0x20808000,0x20008000,0x00800000,0x20808020,0x20000000,
+0x20008020,0x20800000,0x00800000,0x20808020,0x00008000,0x00800020,0x20800020,0x00008020,
+0x00800020,0x00000000,0x20808000,0x20000020,0x20800000,0x20008020,0x00000020,0x00808000,
+};
+
+static int  s3p[] = {
+0x00080201,0x02000200,0x00000001,0x02080201,0x00000000,0x02080000,0x02000201,0x00080001,
+0x02080200,0x02000001,0x02000000,0x00000201,0x02000001,0x00080201,0x00080000,0x02000000,
+0x02080001,0x00080200,0x00000200,0x00000001,0x00080200,0x02000201,0x02080000,0x00000200,
+0x00000201,0x00000000,0x00080001,0x02080200,0x02000200,0x02080001,0x02080201,0x00080000,
+0x02080001,0x00000201,0x00080000,0x02000001,0x00080200,0x02000200,0x00000001,0x02080000,
+0x02000201,0x00000000,0x00000200,0x00080001,0x00000000,0x02080001,0x02080200,0x00000200,
+0x02000000,0x02080201,0x00080201,0x00080000,0x02080201,0x00000001,0x02000200,0x00080201,
+0x00080001,0x00080200,0x02080000,0x02000201,0x00000201,0x02000000,0x02000001,0x02080200,
+};
+
+static int  s4p[] = {
+0x01000000,0x00002000,0x00000080,0x01002084,0x01002004,0x01000080,0x00002084,0x01002000,
+0x00002000,0x00000004,0x01000004,0x00002080,0x01000084,0x01002004,0x01002080,0x00000000,
+0x00002080,0x01000000,0x00002004,0x00000084,0x01000080,0x00002084,0x00000000,0x01000004,
+0x00000004,0x01000084,0x01002084,0x00002004,0x01002000,0x00000080,0x00000084,0x01002080,
+0x01002080,0x01000084,0x00002004,0x01002000,0x00002000,0x00000004,0x01000004,0x01000080,
+0x01000000,0x00002080,0x01002084,0x00000000,0x00002084,0x01000000,0x00000080,0x00002004,
+0x01000084,0x00000080,0x00000000,0x01002084,0x01002004,0x01002080,0x00000084,0x00002000,
+0x00002080,0x01002004,0x01000080,0x00000084,0x00000004,0x00002084,0x01002000,0x01000004,
+};
+
+static int  s5p[] = {
+0x10000008,0x00040008,0x00000000,0x10040400,0x00040008,0x00000400,0x10000408,0x00040000,
+0x00000408,0x10040408,0x00040400,0x10000000,0x10000400,0x10000008,0x10040000,0x00040408,
+0x00040000,0x10000408,0x10040008,0x00000000,0x00000400,0x00000008,0x10040400,0x10040008,
+0x10040408,0x10040000,0x10000000,0x00000408,0x00000008,0x00040400,0x00040408,0x10000400,
+0x00000408,0x10000000,0x10000400,0x00040408,0x10040400,0x00040008,0x00000000,0x10000400,
+0x10000000,0x00000400,0x10040008,0x00040000,0x00040008,0x10040408,0x00040400,0x00000008,
+0x10040408,0x00040400,0x00040000,0x10000408,0x10000008,0x10040000,0x00040408,0x00000000,
+0x00000400,0x10000008,0x10000408,0x10040400,0x10040000,0x00000408,0x00000008,0x10040008,
+};
+
+static int  s6p[] = {
+0x00000800,0x00000040,0x00200040,0x80200000,0x80200840,0x80000800,0x00000840,0x00000000,
+0x00200000,0x80200040,0x80000040,0x00200800,0x80000000,0x00200840,0x00200800,0x80000040,
+0x80200040,0x00000800,0x80000800,0x80200840,0x00000000,0x00200040,0x80200000,0x00000840,
+0x80200800,0x80000840,0x00200840,0x80000000,0x80000840,0x80200800,0x00000040,0x00200000,
+0x80000840,0x00200800,0x80200800,0x80000040,0x00000800,0x00000040,0x00200000,0x80200800,
+0x80200040,0x80000840,0x00000840,0x00000000,0x00000040,0x80200000,0x80000000,0x00200040,
+0x00000000,0x80200040,0x00200040,0x00000840,0x80000040,0x00000800,0x80200840,0x00200000,
+0x00200840,0x80000000,0x80000800,0x80200840,0x80200000,0x00200840,0x00200800,0x80000800,
+};
+
+static int  s7p[] = {
+0x04100010,0x04104000,0x00004010,0x00000000,0x04004000,0x00100010,0x04100000,0x04104010,
+0x00000010,0x04000000,0x00104000,0x00004010,0x00104010,0x04004010,0x04000010,0x04100000,
+0x00004000,0x00104010,0x00100010,0x04004000,0x04104010,0x04000010,0x00000000,0x00104000,
+0x04000000,0x00100000,0x04004010,0x04100010,0x00100000,0x00004000,0x04104000,0x00000010,
+0x00100000,0x00004000,0x04000010,0x04104010,0x00004010,0x04000000,0x00000000,0x00104000,
+0x04100010,0x04004010,0x04004000,0x00100010,0x04104000,0x00000010,0x00100010,0x04004000,
+0x04104010,0x00100000,0x04100000,0x04000010,0x00104000,0x00004010,0x04004010,0x04100000,
+0x00000010,0x04104000,0x00104010,0x00000000,0x04000000,0x04100010,0x00004000,0x00104010,
+};
+
+/*
+ *     DES electronic codebook encryption of one block
+ */
+static void
+block_cipher(char expanded_key[128], char text[8], int decrypting)
+{
+       char *key;
+       int crypto, temp, right, left;
+       int i, key_offset;
+
+       key = expanded_key;
+       left = ip_low(text);
+       right = ip_high(text);
+       if (decrypting) {
+               key_offset = 16;
+               key = key + 128 - 8;
+       } else
+               key_offset = 0;
+       for (i = 0; i < 16; i++) {
+               temp = (right << 1) | ((right >> 31) & 1);
+               crypto  = s0p[(temp         & 0x3f) ^ *key++];
+               crypto |= s1p[((temp >>  4) & 0x3f) ^ *key++];
+               crypto |= s2p[((temp >>  8) & 0x3f) ^ *key++];
+               crypto |= s3p[((temp >> 12) & 0x3f) ^ *key++];
+               crypto |= s4p[((temp >> 16) & 0x3f) ^ *key++];
+               crypto |= s5p[((temp >> 20) & 0x3f) ^ *key++];
+               crypto |= s6p[((temp >> 24) & 0x3f) ^ *key++];
+               temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
+               crypto |= s7p[temp ^ *key++];
+               temp = left;
+               left = right;
+               right = temp ^ crypto;
+               key -= key_offset;
+       }
+       /*
+        *      standard final permutation (IPI)
+        *      left and right are reversed here
+        */
+       fp(right, left, text);
+}
+
+/*
+ *     Initial Permutation
+ */
+static int iptab[] = {
+       0x00000000, 0x00008000, 0x00000000, 0x00008000,
+       0x00000080, 0x00008080, 0x00000080, 0x00008080
+};
+
+static int
+ip_low(char block[8])
+{
+       int i;
+       int l;
+
+       l = 0;
+       for(i = 0; i < 8; i++){
+               l |= iptab[(block[i] >> 4) & 7] >> i;
+               l |= iptab[block[i] & 7] << (16 - i);
+       }
+       return l;
+}
+
+static int
+ip_high(char block[8])
+{
+       int i;
+       int l;
+
+       l = 0;
+       for(i = 0; i < 8; i++){
+               l |= iptab[(block[i] >> 5) & 7] >> i;
+               l |= iptab[(block[i] >> 1) & 7] << (16 - i);
+       }
+       return l;
+}
+
+/*
+ *     Final Permutation
+ */
+static unsigned int    fptab[] = {
+0x00000000,0x80000000,0x00800000,0x80800000,0x00008000,0x80008000,0x00808000,0x80808000,
+0x00000080,0x80000080,0x00800080,0x80800080,0x00008080,0x80008080,0x00808080,0x80808080,
+};
+
+static void
+fp(int left, int right, char text[8])
+{
+       unsigned int ta[2], t, v[2];
+       int i, j, sh;
+
+       ta[0] = right;
+       ta[1] = left;
+       v[0] = v[1] = 0;
+       for(i = 0; i < 2; i++){
+               t = ta[i];
+               sh = i;
+               for(j = 0; j < 4; j++){
+                       v[1] |= fptab[t & 0xf] >> sh;
+                       t >>= 4;
+                       v[0] |= fptab[t & 0xf] >> sh;
+                       t >>= 4;
+                       sh += 2;
+               }
+       }
+       for(i = 0; i < 2; i++)
+               for(j = 0; j < 4; j++){
+                       *text++ = (char)(v[i]&0xff);
+                       v[i] >>= 8;
+               }
+}
+
+/*
+ *     Key set-up
+ */
+static uchar keyexpand[][15][2] = {
+       {   3,  2,   9,  8,  18,  8,  27, 32,  33,  2,  42, 16,  48,  8,  65, 
16, 
+          74,  2,  80,  2,  89,  4,  99, 16, 104,  4, 122, 32,   0,  0, },
+       {   1,  4,   8,  1,  18,  4,  25, 32,  34, 32,  41,  8,  50,  8,  59, 
32, 
+          64, 16,  75,  4,  90,  1,  97, 16, 106,  2, 112,  2, 123,  1, },
+       {   2,  1,  19,  8,  35,  1,  40,  1,  50,  4,  57, 32,  75,  2,  80, 
32, 
+          89,  1,  96, 16, 107,  4, 120,  8,   0,  0,   0,  0,   0,  0, },
+       {   4, 32,  20,  2,  31,  4,  37, 32,  47,  1,  54,  1,  63,  2,  68,  
1, 
+          78,  4,  84,  8, 101, 16, 108,  4, 119, 16, 126,  8,   0,  0, },
+       {   5,  4,  15,  4,  21, 32,  31,  1,  38,  1,  47,  2,  53,  2,  68,  
8, 
+          85, 16,  92,  4, 103, 16, 108, 32, 118, 32, 124,  2,   0,  0, },
+       {  15,  2,  21,  2,  39,  8,  46, 16,  55, 32,  61,  1,  71, 16,  76, 
32, 
+          86, 32,  93,  4, 102,  2, 108, 16, 117,  8, 126,  1,   0,  0, },
+       {  14, 16,  23, 32,  29,  1,  38,  8,  52,  2,  63,  4,  70,  2,  76, 
16, 
+          85,  8, 100,  1, 110,  4, 116,  8, 127,  8,   0,  0,   0,  0, },
+       {   1,  8,   8, 32,  17,  1,  24, 16,  35,  4,  50,  1,  57, 16,  67,  
8, 
+          83,  1,  88,  1,  98,  4, 105, 32, 114, 32, 123,  2,   0,  0, },
+       {   0,  1,  11, 16,  16,  4,  35,  2,  40, 32,  49,  1,  56, 16,  65,  
2, 
+          74, 16,  80,  8,  99,  8, 115,  1, 121,  4,   0,  0,   0,  0, },
+       {   9, 16,  18,  2,  24,  2,  33,  4,  43, 16,  48,  4,  66, 32,  73,  
8, 
+          82,  8,  91, 32,  97,  2, 106, 16, 112,  8, 122,  1,   0,  0, },
+       {  14, 32,  21,  4,  30,  2,  36, 16,  45,  8,  60,  1,  69,  2,  87,  
8, 
+          94, 16, 103, 32, 109,  1, 118,  8, 124, 32,   0,  0,   0,  0, },
+       {   7,  4,  14,  2,  20, 16,  29,  8,  44,  1,  54,  4,  60,  8,  71,  
8, 
+          78, 16,  87, 32,  93,  1, 102,  8, 116,  2, 125,  4,   0,  0, },
+       {   7,  2,  12,  1,  22,  4,  28,  8,  45, 16,  52,  4,  63, 16,  70,  
8, 
+          84,  2,  95,  4, 101, 32, 111,  1, 118,  1,   0,  0,   0,  0, },
+       {   6, 16,  13, 16,  20,  4,  31, 16,  36, 32,  46, 32,  53,  4,  62,  
2, 
+          69, 32,  79,  1,  86,  1,  95,  2, 101,  2, 119,  8,   0,  0, },
+       {   0, 32,  10,  8,  19, 32,  25,  2,  34, 16,  40,  8,  59,  8,  66,  
2, 
+          72,  2,  81,  4,  91, 16,  96,  4, 115,  2, 121,  8,   0,  0, },
+       {   3, 16,  10,  4,  17, 32,  26, 32,  33,  8,  42,  8,  51, 32,  57,  
2, 
+          67,  4,  82,  1,  89, 16,  98,  2, 104,  2, 113,  4, 120,  1, },
+       {   1, 16,  11,  8,  27,  1,  32,  1,  42,  4,  49, 32,  58, 32,  67,  
2, 
+          72, 32,  81,  1,  88, 16,  99,  4, 114,  1,   0,  0,   0,  0, },
+       {   6, 32,  12,  2,  23,  4,  29, 32,  39,  1,  46,  1,  55,  2,  61,  
2, 
+          70,  4,  76,  8,  93, 16, 100,  4, 111, 16, 116, 32,   0,  0, },
+       {   6,  2,  13, 32,  23,  1,  30,  1,  39,  2,  45,  2,  63,  8,  77, 
16, 
+          84,  4,  95, 16, 100, 32, 110, 32, 117,  4, 127,  4,   0,  0, },
+       {   4,  1,  13,  2,  31,  8,  38, 16,  47, 32,  53,  1,  62,  8,  68, 
32, 
+          78, 32,  85,  4,  94,  2, 100, 16, 109,  8, 127,  2,   0,  0, },
+       {   5, 16,  15, 32,  21,  1,  30,  8,  44,  2,  55,  4,  61, 32,  68, 
16, 
+          77,  8,  92,  1, 102,  4, 108,  8, 126, 16,   0,  0,   0,  0, },
+       {   2,  8,   9,  1,  16, 16,  27,  4,  42,  1,  49, 16,  58,  2,  75,  
1, 
+          80,  1,  90,  4,  97, 32, 106, 32, 113,  8, 120, 32,   0,  0, },
+       {   2,  4,   8,  4,  27,  2,  32, 32,  41,  1,  48, 16,  59,  4,  66, 
16, 
+          72,  8,  91,  8, 107,  1, 112,  1, 123, 16,   0,  0,   0,  0, },
+       {   3,  8,  10,  2,  16,  2,  25,  4,  35, 16,  40,  4,  59,  2,  65,  
8, 
+          74,  8,  83, 32,  89,  2,  98, 16, 104,  8, 121, 16,   0,  0, },
+       {   4,  2,  13,  4,  22,  2,  28, 16,  37,  8,  52,  1,  62,  4,  79,  
8, 
+          86, 16,  95, 32, 101,  1, 110,  8, 126, 32,   0,  0,   0,  0, },
+       {   5, 32,  12, 16,  21,  8,  36,  1,  46,  4,  52,  8,  70, 16,  79, 
32, 
+          85,  1,  94,  8, 108,  2, 119,  4, 126,  2,   0,  0,   0,  0, },
+       {   5,  2,  14,  4,  20,  8,  37, 16,  44,  4,  55, 16,  60, 32,  76,  
2, 
+          87,  4,  93, 32, 103,  1, 110,  1, 119,  2, 124,  1,   0,  0, },
+       {   7, 32,  12,  4,  23, 16,  28, 32,  38, 32,  45,  4,  54,  2,  60, 
16, 
+          71,  1,  78,  1,  87,  2,  93,  2, 111,  8, 118, 16, 125, 16, },
+       {   1,  1,  11, 32,  17,  2,  26, 16,  32,  8,  51,  8,  64,  2,  73,  
4, 
+          83, 16,  88,  4, 107,  2, 112, 32, 122,  8,   0,  0,   0,  0, },
+       {   0,  4,   9, 32,  18, 32,  25,  8,  34,  8,  43, 32,  49,  2,  58, 
16, 
+          74,  1,  81, 16,  90,  2,  96,  2, 105,  4, 115, 16, 122,  4, },
+       {   2,  2,  19,  1,  24,  1,  34,  4,  41, 32,  50, 32,  57,  8,  64, 
32, 
+          73,  1,  80, 16,  91,  4, 106,  1, 113, 16, 123,  8,   0,  0, },
+       {   3,  4,  10, 16,  16,  8,  35,  8,  51,  1,  56,  1,  67, 16,  72,  
4, 
+          91,  2,  96, 32, 105,  1, 112, 16, 121,  2,   0,  0,   0,  0, },
+       {   4, 16,  15,  1,  22,  1,  31,  2,  37,  2,  55,  8,  62, 16,  69, 
16, 
+          76,  4,  87, 16,  92, 32, 102, 32, 109,  4, 118,  2, 125, 32, },
+       {   6,  4,  23,  8,  30, 16,  39, 32,  45,  1,  54,  8,  70, 32,  77,  
4, 
+          86,  2,  92, 16, 101,  8, 116,  1, 125,  2,   0,  0,   0,  0, },
+       {   4,  4,  13,  1,  22,  8,  36,  2,  47,  4,  53, 32,  63,  1,  69,  
8, 
+          84,  1,  94,  4, 100,  8, 117, 16, 127, 32,   0,  0,   0,  0, },
+       {   3, 32,   8, 16,  19,  4,  34,  1,  41, 16,  50,  2,  56,  2,  67,  
1, 
+          72,  1,  82,  4,  89, 32,  98, 32, 105,  8, 114,  8, 121,  1, },
+       {   1, 32,  19,  2,  24, 32,  33,  1,  40, 16,  51,  4,  64,  8,  83,  
8, 
+          99,  1, 104,  1, 114,  4, 120,  4,   0,  0,   0,  0,   0,  0, },
+       {   8,  2,  17,  4,  27, 16,  32,  4,  51,  2,  56, 32,  66,  8,  75, 
32, 
+          81,  2,  90, 16,  96,  8, 115,  8, 122,  2,   0,  0,   0,  0, },
+       {   2, 16,  18,  1,  25, 16,  34,  2,  40,  2,  49,  4,  59, 16,  66,  
4, 
+          73, 32,  82, 32,  89,  8,  98,  8, 107, 32, 113,  2, 123,  4, },
+       {   7,  1,  13,  8,  28,  1,  38,  4,  44,  8,  61, 16,  71, 32,  77,  
1, 
+          86,  8, 100,  2, 111,  4, 117, 32, 124, 16,   0,  0,   0,  0, },
+       {  12,  8,  29, 16,  36,  4,  47, 16,  52, 32,  62, 32,  68,  2,  79,  
4, 
+          85, 32,  95,  1, 102,  1, 111,  2, 117,  2, 126,  4,   0,  0, },
+       {   5,  1,  15, 16,  20, 32,  30, 32,  37,  4,  46,  2,  52, 16,  61,  
8, 
+          70,  1,  79,  2,  85,  2, 103,  8, 110, 16, 119, 32, 124,  4, },
+       {   0, 16,   9,  2,  18, 16,  24,  8,  43,  8,  59,  1,  65,  4,  75, 
16, 
+          80,  4,  99,  2, 104, 32, 113,  1, 123, 32,   0,  0,   0,  0, },
+       {  10, 32,  17,  8,  26,  8,  35, 32,  41,  2,  50, 16,  56,  8,  66,  
1, 
+          73, 16,  82,  2,  88,  2,  97,  4, 107, 16, 112,  4, 121, 32, },
+       {   0,  2,  11,  1,  16,  1,  26,  4,  33, 32,  42, 32,  49,  8,  58,  
8, 
+          65,  1,  72, 16,  83,  4,  98,  1, 105, 16, 114,  2,   0,  0, },
+       {   8,  8,  27,  8,  43,  1,  48,  1,  58,  4,  64,  4,  83,  2,  88, 
32, 
+          97,  1, 104, 16, 115,  4, 122, 16,   0,  0,   0,  0,   0,  0, },
+       {   5,  8,  14,  1,  23,  2,  29,  2,  47,  8,  54, 16,  63, 32,  68,  
4, 
+          79, 16,  84, 32,  94, 32, 101,  4, 110,  2, 116, 16, 127,  1, },
+       {   4,  8,  15,  8,  22, 16,  31, 32,  37,  1,  46,  8,  60,  2,  69,  
4, 
+          78,  2,  84, 16,  93,  8, 108,  1, 118,  4,   0,  0,   0,  0, },
+       {   7, 16,  14,  8,  28,  2,  39,  4,  45, 32,  55,  1,  62,  1,  76,  
1, 
+          86,  4,  92,  8, 109, 16, 116,  4, 125,  1,   0,  0,   0,  0, },
+       {   1,  2,  11,  4,  26,  1,  33, 16,  42,  2,  48,  2,  57,  4,  64,  
1, 
+          74,  4,  81, 32,  90, 32,  97,  8, 106,  8, 115, 32, 120, 16, },
+       {   2, 32,  11,  2,  16, 32,  25,  1,  32, 16,  43,  4,  58,  1,  75,  
8, 
+          91,  1,  96,  1, 106,  4, 113, 32,   0,  0,   0,  0,   0,  0, },
+       {   3,  1,   9,  4,  19, 16,  24,  4,  43,  2,  48, 32,  57,  1,  67, 
32, 
+          73,  2,  82, 16,  88,  8, 107,  8, 120,  2,   0,  0,   0,  0, },
+       {   0,  8,  10,  1,  17, 16,  26,  2,  32,  2,  41,  4,  51, 16,  56,  
4, 
+          65, 32,  74, 32,  81,  8,  90,  8,  99, 32, 105,  2, 114, 16, },
+       {   6,  1,  20,  1,  30,  4,  36,  8,  53, 16,  60,  4,  69,  1,  78,  
8, 
+          92,  2, 103,  4, 109, 32, 119,  1, 125,  8,   0,  0,   0,  0, },
+       {   7,  8,  21, 16,  28,  4,  39, 16,  44, 32,  54, 32,  61,  4,  71,  
4, 
+          77, 32,  87,  1,  94,  1, 103,  2, 109,  2, 124,  8,   0,  0, },
+       {   6,  8,  12, 32,  22, 32,  29,  4,  38,  2,  44, 16,  53,  8,  71,  
2, 
+          77,  2,  95,  8, 102, 16, 111, 32, 117,  1, 127, 16,   0,  0, }
+};
+
+static void
+key_setup(char key[DESKEYLEN], char *ek)
+{
+       int i, j, k, mask;
+       uchar (*x)[2];
+
+       memset(ek, 0, 128);
+       x = keyexpand[0];
+       for(i = 0; i < 7; i++){
+               k = key[i];
+               for(mask = 0x80; mask; mask >>= 1){
+                       if(k & mask)
+                               for(j = 0; j < 15; j++)
+                                       ek[x[j][0]] |= x[j][1];
+                       x += 15;
+               }
+       }
+}
+
+
+/************ netkey main.c *************/
+int
+passtokey(char *key, const char *p)
+{
+       uchar buf[NAMELEN], *t;
+       int i, n;
+
+       n = strlen(p);
+       if(n >= NAMELEN)
+               n = NAMELEN-1;
+       memset(buf, ' ', 8);
+       t = buf;
+       strncpy((char*)t, p, n);
+       t[n] = '\0';
+       memset(key, 0, DESKEYLEN);
+       for(;;){
+               for(i = 0; i < DESKEYLEN; i++)
+                       key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1)));
+               if(n <= 8)
+                       return 1;
+               n -= 8;
+               t += 8;
+               if(n < 8){
+                       t -= 8 - n;
+                       n = 8;
+               }
+               encrypt9(key, t, 8);
+       }
+       return 1;       /* not reached */
+}
+
+int
+netcrypt(void *key, void *chal)
+{
+        uchar buf[8], *p;
+
+        strncpy((char*)buf, chal, 7);
+        buf[7] = '\0';
+        for(p = buf; *p && *p != '\n'; p++)
+                ;
+        *p = '\0';
+        encrypt9(key, buf, 8);
+        sprintf(chal, "%.2x%.2x%.2x%.2x", buf[0], buf[1], buf[2], buf[3]);
+        return 1;
+}
+
+char * calculate_netkey_response( const char* pass, 
+                                 const char* challenge )
+{
+  char key[DESKEYLEN];
+  static char response[32];
+  
+  passtokey( key, pass );
+  strcpy( response, challenge );
+  netcrypt( key, response );
+
+  return response;
+}
diff -up lftp/src/resource.cc.netkey lftp/src/resource.cc
--- lftp/src/resource.cc.netkey 2009-02-02 12:09:16.806209378 -0500
+++ lftp/src/resource.cc        2009-02-02 12:10:11.766896000 -0500
@@ -200,6 +200,7 @@ static ResType lftp_vars[] = {
    {"ftp:timezone",             "GMT",   0,0},
    {"ftp:skey-allow",           "yes",   ResMgr::BoolValidate,0},
    {"ftp:skey-force",           "no",    ResMgr::BoolValidate,0},
+   {"ftp:netkey-allow",                 "yes",   ResMgr::BoolValidate,0},
 #if USE_SSL
    {"ftp:ssl-allow",            "yes",   ResMgr::BoolValidate,0},
    {"ftp:ssl-force",            "no",    ResMgr::BoolValidate,0},

Reply via email to