chiark / gitweb /
crypto debugging, and several bugfixes
authorian <ian>
Tue, 30 May 2000 23:51:00 +0000 (23:51 +0000)
committerian <ian>
Tue, 30 May 2000 23:51:00 +0000 (23:51 +0000)
ipif/forwarder.c
ipif/mech-blowfish.c
ipif/mech-pkcs5.c
ipif/udptunnel

index 015afbde7b082d23c1e5235195a051f740b9778f..0112d90b79243a0f4542610cf40c50fd984a5f06 100644 (file)
@@ -7,8 +7,8 @@
  *                      <encdec-keys-fd>
  *                      <mtu> <keepalive> <timeout>
  *                      <public-remote-addr> [<public-remote-port>]
- *                      <mech1> [<mech1-params> ...]
- *                      <mech2> [<mech2-params> ...]
+ *                      !<mech1> [<mech1-params> ...]
+ *                      !<mech2> [<mech2-params> ...]
  *                      ''
  *
  * Remote addr may '' to mean wait to receive a packet and reply to
@@ -17,7 +17,7 @@
  *
  * <optchars> is zero or more of
  *    w   means generate and write encdec keys, rather than reading them
- *    D   means do crypto debug (use with care!)
+ *    K   means do crypto debug (use with care!)
  *
  * Every must be numeric.  There is very little argument checking.
  *
@@ -49,6 +49,7 @@
 #define MAXMECHS 10
 
 static size_t buffer_size;
+static struct utsname uname_result;
 
 static const char *opt_chars;
 static int public_local_fd, private_in_fd, private_out_fd;
@@ -70,27 +71,38 @@ static time_t nextsendka;
 
 static void cdebug(int mechno /*or -1*/, const char *msg) {
   if (!crypto_debug) return;
-  printf("%s: CRYPTO: %-20s encrypt setup\n",
+  printf("%s: CRYPTO: %-20s %s\n",
         programid,
-        mechno >= 0 ? mechs[i]->name : "",
+        mechno >= 0 ? mechs[mechno]->name : "",
         msg);
 }
 
-static void cdebughex(int mechno /*or -1*/, const char *msg,
-                     size_t skipbefore, const void *ptr, size_t sz, size_t skipafter) {
+static void cdebughex(int mechno /*or -1*/, const char *msg, const void *ptr,
+                     size_t sz, size_t skipbefore,
+                     int spc_offset, int dot_offset) {
   const unsigned char *p;
+  size_t i;
+  unsigned j= dot_offset;
   
   if (!crypto_debug) return;
-  printf("%s: CRYPTO: %-20s %s",
-        programid,
-        mechno >= 0 ? mechs[i]->name : "",
+  printf("%-8.8s: CRYPTO: %-20s %-10s",
+        uname_result.nodename,
+        mechno >= 0 ? mechs[mechno]->name : "",
         msg);
-  for (i=0; i<skipbefore) fputs(" ..",stdout);
-  for (i=0, p=ptr; i<sz; i++, p++) fprintf(" %02x",*p);
-  for (i=0; i<skipafter) fputs(" ..",stdout);
+
+  for (i=0; i<spc_offset; i++, j++) fputs(j&3 ? "  " : "   ",stdout);
+  for (i=0; i<skipbefore; i++, j++) fputs(j&3 ? ".." : " ..",stdout);
+  for (i=0, p=ptr; i<sz; i++, j++, p++) printf(j&3 ? "%02x" : " %02x",*p);
+
   fputc('\n',stdout);
 }
 
+static void cdebugbuf(int mechno /*or -1*/, const char *msg,
+                     const struct buffer *buf, int spc_offset, int dot_offset) {
+  cdebughex(mechno, msg, buf->start, buf->size, buf->start - buf->base,
+           spc_offset, dot_offset);
+}
+
 void get_random(void *ptr, size_t sz) {
   static FILE *randfile;
 
@@ -103,10 +115,10 @@ void get_random(void *ptr, size_t sz) {
   }
 
   r= fread(ptr,1,sz,randfile);
-  if (r == sz) return;
-  (ferror(randfile) ? sysfail : fail)("cannot read random number generator");
+  if (r != sz)
+    (ferror(randfile) ? sysfail : fail)("cannot read random number generator");
 
-  cdebughex(-1, "get_random", ptr, sz, 0,0);
+  cdebughex(-1, "get_random", ptr, sz, 0,0,0);
 }
 
 void random_key(void *ptr, size_t sz) {
@@ -128,12 +140,9 @@ static void setnonblock(int fd, int nonblock) {
   if (r==-1) sysfail("fcntl F_SETFL");
 }
 
-static const struct mechanism *getarg_mech(void) {
-  const char *name;
+static const struct mechanism *find_mech(const char *name) {
   const struct mechanism *mech, *const *mechlist;
 
-  name= getarg_string();
-
   for (mechlist= mechanismlists;
        *mechlist;
        mechlist++)
@@ -173,12 +182,14 @@ static void inbound(void) {
 
   assert(r <= buf_in.size);
   buf_in.size= r;
+  cdebugbuf(-1, "decode", &buf_in, 3,0);
   for (i=n_mechs-1; i>=0; i--) {
     emsg= mechs[i]->decode(md_in[i],&buf_in);
     if (emsg) {
       fprintf(stderr, "%s: bad packet: %s: %s\n", programid, mechs[i]->name, emsg);
       return;
     }
+    cdebugbuf(i, "decode", &buf_in, 3,0);
   }
 
   alarm(timeout);
@@ -232,7 +243,11 @@ static void sendpacket(const unsigned char *message, size_t size) {
 
   nextsendka= now() + keepalive;
 
-  for (i=0; i<n_mechs; i++) mechs[i]->encode(md_out[i],&buf_out);
+  cdebugbuf(-1, "encode", &buf_out, 4,0);
+  for (i=0; i<n_mechs; i++) {
+    mechs[i]->encode(md_out[i],&buf_out);
+    cdebugbuf(i, "encode", &buf_out, 4,0);
+  }
   assert(public_remote_specd);
   
   setnonblock(public_local_fd,1);
@@ -280,8 +295,9 @@ static void outbound(void) {
 
 int main(int argc, const char *const *const argv_in) {
   const char *arg;
+  const char *const *argv_save;
+  const char *const *argv_done;
   struct pollfd pollfds[2];
-  struct utsname uname_result;
   int i, polltimeout, r;
   time_t tnow;
 
@@ -291,8 +307,8 @@ int main(int argc, const char *const *const argv_in) {
   sprintf(programid, PROGRAM ": %.*s", SYS_NMLN, uname_result.nodename);
 
   opt_chars= getarg_string();
-  encdec_keys_write= !!strchr(opt_chars,"w");
-  crypto_debug= !!strchr(opt_chars,"D");
+  encdec_keys_write= !!strchr(opt_chars,'w');
+  crypto_debug= !!strchr(opt_chars,'K');
 
   public_local_fd= getarg_ulong();
   private_in_fd= getarg_ulong();
@@ -317,17 +333,26 @@ int main(int argc, const char *const *const argv_in) {
   }
 
   maxprefix= 0;
-  for (i=0; i<n_mechs; i++) {
-    mechs[i]= getarg_mech();
-  }
-  for (i=0; i<n_mechs; i++) {
-    cdebug(i,"encrypt setup");
+  i= 0;
+  while ((arg= *++argv)) {
+    arg_assert(*arg++ == '!');
+    arg_assert(i <= MAXMECHS);
+    mechs[i]= find_mech(arg);
+    cdebug(i,"encsetup");
+
+    argv_save= argv;
     mechs[i]->encsetup(&md_in[i], &maxprefix, &maxsuffix);
-  }
-  for (i=0; i<n_mechs; i++) {
-    cdebug(i,"decrypt setup");
+
+    argv_done= argv;
+    argv= argv_save;
+    cdebug(i,"decsetup");
     mechs[i]->decsetup(&md_out[i]);
+
+    assert(argv == argv_done);
+    
+    i++;
   }
+  n_mechs= i;
 
   if (maxprefix<1) maxprefix= 1;
   if (maxsuffix<1) maxsuffix= 1;
index 07ec8c13cd89f463ede1271c0b7258aa80d4ffed..7447cadb1d888a3ccd729f897c720ba9e5ca0018 100644 (file)
@@ -22,7 +22,7 @@ static void mds_blowfish(struct mechdata **md_r) {
   unsigned char iv[BLOWFISH_BLOCKBYTES];
   unsigned char key[BLOWFISH_MAXKEYBYTES];
 
-  md= xmalloc(sizeof(md));
+  XMALLOC(md);
 
   keysize= getarg_ulong();
   arg_assert(!(keysize & 7));
@@ -53,18 +53,20 @@ static void mes_bfmac(struct mechdata **md_r, int *maxprefix_io, int *maxsuffix_
 
 #define MSGSIZE_OUT                                                  \
   msgsize= buf->size;                                                \
-  arg_assert(!(msgsize & ~BLOWFISH_BLOCKBYTES));
+  arg_assert(!(msgsize & (BLOWFISH_BLOCKBYTES-1)));
 
 #define MSGSIZE_IN                                                   \
   msgsize= buf->size;                                                \
-  if (msgsize & ~BLOWFISH_BLOCKBYTES) return "not multiple of block size"
+  if (msgsize & (BLOWFISH_BLOCKBYTES-1)) return "not multiple of block size"
 
 #define FOREACH_BLOCK(func,inptr,outptr)                             \
  {                                                                    \
    unsigned char *ptr;                                               \
-   ptr= buf->start;                                                  \
-   while (ptr < buf->start + msgsize)                                \
+   for (ptr= buf->start;                                             \
+        ptr < buf->start + msgsize;                                  \
+       ptr += BLOWFISH_BLOCKBYTES) {                                 \
      func(&md->cbc,inptr,outptr);                                    \
+   }                                                                  \
  }
 
 static void menc_blowfish(struct mechdata *md, struct buffer *buf) {
index 85b586379e70e5f21c63ded960d19f312a4b8a3b..6ff35cd2287ddab8026c84c6bb6403c1af4358b0 100644 (file)
@@ -21,7 +21,7 @@ static unsigned long setup(struct mechdata **md_r) {
 
   blocksize= getarg_ulong();
   md->mask= blocksize - 1;
-  arg_assert(!md->mask & blocksize);
+  arg_assert(!(md->mask & blocksize));
   arg_assert(blocksize <= 255);
 
   *md_r= md;
index 08b75a35e2d49f175cf1961434782cc4a660e0ac..e52ee73bad0cdb846a1fda77df601a0012c76393 100755 (executable)
@@ -159,7 +159,7 @@ sub show_addr_port ($) {
     return show_addr($s).','.show_port($s);
 }
 sub arg_value ($$) {
-    my ($val,$opt);
+    my ($val,$opt) = @_;
     $_= '-';
     return $val if length $val;
     @ARGV or quit("$opt needs value");
@@ -187,14 +187,17 @@ while ($ARGV[0] =~ m/^-/) {
            $fcmd= arg_value($_,'-f');
        } elsif (s/^-e//) {
            $encrarg= arg_value($_,'-e');
-           push @encrargs, "-e$encrarg";
-           push @encryption, split m#/#, $encrarg;
+           push @remoteopts, "-e$encrarg";
+           @thisencryption= split m#/#, $encrarg;
+           $thisencryption[0] =~ s/^/\!/;
+           push @encryption, @thisencryption;
        } elsif (s/^-m/-/) {
            $masq= 1;
        } elsif (s/^-d/-/) {
            $dump= 1;
        } elsif (s/^-Dcrypto$/-/) {
            $xfwdopts.= 'K';
+           push @remoteopts, '-Dcrypto';
        } else {
            quit("unknown option \`$_'");
        }
@@ -259,7 +262,7 @@ if (@ARGV) {
     $rad= xform_remote(show_addr($rs),$ras);
     $rpd= xform_remote(show_port($rs),$rps);
     @rcmd= (@ARGV,
-           @encrargs,
+           @remoteopts,
            "$rad,$rpd",
            $masq ? 'Wait,Wait' : $lapd,
            "$rva,$lva,$mtu,$proto",
@@ -271,10 +274,10 @@ if (@ARGV) {
        pipe(RAPREAD,RCMDREADSUB) or fail("pipe");
        select(RCMDREADSUB); $|=1; select(STDOUT);
     }
-    pipe(DUMPKEYS,RCMDWRITESUB) or fail("pipe");
+    pipe(RCMDWRITESUB,DUMPKEYS) or fail("pipe");
     defined($c_rcmd= fork) or fail("fork for remote");
     if (!$c_rcmd) {
-       open STDIN, ">&RCMDWRITESUB" or fail("reopen stdin for remote command");
+       open STDIN, "<&RCMDWRITESUB" or fail("reopen stdin for remote command");
        open STDOUT, ">&RCMDREADSUB" or fail("reopen stdout for remote command")
            if $rapcmd;
        close RAPREAD if $rapcmd;
@@ -360,7 +363,7 @@ debug("forwarding command @fcmd.");
 
 defined($c_fwd= fork) or fail("fork for udptunnel-forwarder");
 if (!$c_fwd) {
-    foreach $fd (qw(L DW UR)) {
+    foreach $fd (qw(L DW UR DUMPKEYS)) {
        fcntl($fd, F_SETFD, 0) or fail("set no-close-on-exec $fd");
     }
     exec @fcmd; fail("cannot execute $fcmd[0]");
@@ -381,11 +384,12 @@ $estatus= 0;
 while (keys %procs) {
     ($c= wait) >0 or
        fail("wait failed (expecting ". join('; ',keys %procs). ")");
-    warning("unexpected child reaped: pid $c, code $?"), next
+    $status= $?;
+    warning("unexpected child reaped: pid $c, code $status"), next
        unless exists $procs{$c};
     $str= $procs{$c};
     delete $procs{$c};
-    $? ? warning("subprocess $str failed with code $?")
+    $status ? warning("subprocess $str failed with code $status")
        : debug("subprocess $str finished");
     if ($c==$c_lcmd || $c==$c_fwd || $c==$c_rcmd) {
        kill 15, grep (exists $procs{$_}, $c_fwd, $c_rcmd);