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},