[prev in list] [next in list] [prev in thread] [next in thread] 

List:       proftpd-committers
Subject:    [ProFTPD-committers] proftpd/contrib/mod_sftp umac.c, NONE, 1.1 umac.h, NONE, 1.1 Makefile.in, 1.8,
From:       TJ Saunders <castaglia () users ! sourceforge ! net>
Date:       2013-03-28 18:48:33
Message-ID: E1ULHsJ-00011L-V3 () sfs-ml-2 ! v29 ! ch3 ! sourceforge ! com
[Download RAW message or body]

Update of /cvsroot/proftp/proftpd/contrib/mod_sftp
In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv26499/contrib/mod_sftp

Modified Files:
	Makefile.in crypto.c fxp.c mac.c mac.h mod_sftp.c 
Added Files:
	umac.c umac.h 
Log Message:

Bug#3920 - Support umac-64@openssh.com digest for mod_sftp.


Index: crypto.c
===================================================================
RCS file: /cvsroot/proftp/proftpd/contrib/mod_sftp/crypto.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- crypto.c	15 Mar 2013 02:35:52 -0000	1.28
+++ crypto.c	28 Mar 2013 18:48:31 -0000	1.29
@@ -26,6 +26,7 @@
 
 #include "mod_sftp.h"
 #include "crypto.h"
+#include "umac.h"
 
 /* In OpenSSL 0.9.7, all des_ functions were renamed to DES_ to avoid 
  * clashes with older versions of libdes. 
@@ -83,7 +84,6 @@
   /* The handling of NULL openssl_name and get_type fields is done in
    * sftp_crypto_get_cipher(), as special cases.
    */
-
 #if OPENSSL_VERSION_NUMBER > 0x000907000L
   { "aes256-ctr",	NULL,		0,	NULL,	TRUE, TRUE },
   { "aes192-ctr",	NULL,		0,	NULL,	TRUE, TRUE },
@@ -144,6 +144,9 @@
 };
 
 static struct sftp_digest digests[] = {
+  /* The handling of NULL openssl_name and get_type fields is done in
+   * sftp_crypto_get_digest(), as special cases.
+   */
 #ifdef HAVE_SHA256_OPENSSL
   { "hmac-sha2-256",	"sha256",		EVP_sha256,	0, TRUE, TRUE },
 #endif /* SHA256 support in OpenSSL */
@@ -155,6 +158,7 @@
   { "hmac-md5",		"md5",		EVP_md5,	0,	TRUE, FALSE },
   { "hmac-md5-96",	"md5",		EVP_md5,	12,	TRUE, FALSE },
   { "hmac-ripemd160",	"rmd160",	EVP_ripemd160,	0,	TRUE, FALSE },
+  { "umac-64@openssh.com", NULL,	NULL,		8,	TRUE, FALSE },
   { "none",		"null",		EVP_md_null,	0,	FALSE, TRUE },
   { NULL, NULL, NULL, 0, FALSE, FALSE }
 };
@@ -643,6 +647,60 @@
 }
 #endif /* OpenSSL older than 0.9.7 */
 
+static int update_umac(EVP_MD_CTX *ctx, const void *data, size_t len) {
+  int res;
+
+  if (ctx->md_data == NULL) {
+    struct umac_ctx *umac;
+
+    umac = umac_new((unsigned char *) data);
+    if (umac == NULL) {
+      return 0;
+    }
+
+    ctx->md_data = umac;
+    return 1;
+  }
+
+  res = umac_update(ctx->md_data, (unsigned char *) data, (long) len);
+  return res;
+}
+
+static int final_umac(EVP_MD_CTX *ctx, unsigned char *md) {
+  unsigned char nonce[8];
+  int res;
+
+  res = umac_final(ctx->md_data, md, nonce);
+  return res;
+}
+
+static int delete_umac(EVP_MD_CTX *ctx) {
+  struct umac_ctx *umac;
+
+  umac = ctx->md_data;
+  umac_delete(umac);
+  ctx->md_data = NULL;
+
+  return 1;
+}
+
+static const EVP_MD *get_umac_digest(void) {
+  static EVP_MD umac_digest;
+
+  memset(&umac_digest, 0, sizeof(EVP_MD));
+
+  umac_digest.type = NID_undef;
+  umac_digest.pkey_type = NID_undef;
+  umac_digest.md_size = 8;
+  umac_digest.flags = 0UL;
+  umac_digest.update = update_umac;
+  umac_digest.final = final_umac;
+  umac_digest.cleanup = delete_umac;
+  umac_digest.block_size = 32;
+
+  return &umac_digest;
+}
+
 const EVP_CIPHER *sftp_crypto_get_cipher(const char *name, size_t *key_len,
     size_t *discard_len) {
   register unsigned int i;
@@ -702,7 +760,15 @@
 
   for (i = 0; digests[i].name; i++) {
     if (strcmp(digests[i].name, name) == 0) {
-      const EVP_MD *digest = digests[i].get_type();
+      const EVP_MD *digest = NULL;
+
+      if (strncmp(name, "umac-64@openssh.com", 12) == 0) {
+        digest = get_umac_digest();
+
+      } else {
+        digest = digests[i].get_type();
+      }
+
       if (mac_len) {
         *mac_len = digests[i].mac_len;
       }
@@ -874,14 +940,22 @@
 #endif /* OPENSSL_FIPS */
 
           if (strncmp(c->argv[i], "none", 5) != 0) {
-            if (EVP_get_digestbyname(digests[j].openssl_name) != NULL) {
+            if (digests[j].openssl_name != NULL &&
+                EVP_get_digestbyname(digests[j].openssl_name) != NULL) {
               res = pstrcat(p, res, *res ? "," : "",
                 pstrdup(p, digests[j].name), NULL);
 
             } else {
-              pr_trace_msg(trace_channel, 3,
-                "unable to use '%s' digest: Unsupported by OpenSSL",
-                digests[j].name);
+              /* The umac-64 digest is a special case. */
+              if (strncmp(digests[j].name, "umac-64@openssh.com", 12) == 0) {
+                res = pstrcat(p, res, *res ? "," : "",
+                  pstrdup(p, digests[j].name), NULL);
+
+              } else {
+                pr_trace_msg(trace_channel, 3,
+                  "unable to use '%s' digest: Unsupported by OpenSSL",
+                  digests[j].name);
+              }
             }
 
           } else {
@@ -912,14 +986,22 @@
 #endif /* OPENSSL_FIPS */
 
         if (strncmp(digests[i].name, "none", 5) != 0) {
-          if (EVP_get_digestbyname(digests[i].openssl_name) != NULL) {
+          if (digests[i].openssl_name != NULL &&
+              EVP_get_digestbyname(digests[i].openssl_name) != NULL) {
             res = pstrcat(p, res, *res ? "," : "",
               pstrdup(p, digests[i].name), NULL);
 
           } else {
-            pr_trace_msg(trace_channel, 3,
-              "unable to use '%s' digest: Unsupported by OpenSSL",
-              digests[i].name);
+            /* The umac-64 digest is a special case. */
+            if (strncmp(digests[i].name, "umac-64@openssh.com", 12) == 0) {
+              res = pstrcat(p, res, *res ? "," : "",
+                pstrdup(p, digests[i].name), NULL);
+
+            } else {
+              pr_trace_msg(trace_channel, 3,
+                "unable to use '%s' digest: Unsupported by OpenSSL",
+                digests[i].name);
+            }
           }
 
         } else {

Index: mac.c
===================================================================
RCS file: /cvsroot/proftp/proftpd/contrib/mod_sftp/mac.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mac.c	29 Jan 2013 07:40:45 -0000	1.13
+++ mac.c	28 Mar 2013 18:48:31 -0000	1.14
@@ -33,9 +33,12 @@
 #include "session.h"
 #include "disconnect.h"
 #include "interop.h"
+#include "umac.h"
 
 struct sftp_mac {
   const char *algo;
+  int algo_type;
+
   const EVP_MD *digest;
 
   unsigned char *key;
@@ -49,6 +52,12 @@
   uint32_t mac_len;
 };
 
+#define SFTP_MAC_ALGO_TYPE_HMAC		1
+#define SFTP_MAC_ALGO_TYPE_UMAC64	2
+
+#define SFTP_MAC_FL_READ_MAC	1
+#define SFTP_MAC_FL_WRITE_MAC	2
+
 /* We need to keep the old MACs around, so that we can handle N arbitrary
  * packets to/from the client using the old keys, as during rekeying.
  * Thus we have two read MAC contexts, two write MAC contexts.
@@ -56,16 +65,18 @@
  */
 
 static struct sftp_mac read_macs[] = {
-  { NULL, NULL, NULL, 0 },
-  { NULL, NULL, NULL, 0 }
+  { NULL, 0, NULL, NULL, 0 },
+  { NULL, 0, NULL, NULL, 0 }
 };
-static HMAC_CTX read_ctxs[2];
+static HMAC_CTX hmac_read_ctxs[2];
+static struct umac_ctx *umac_read_ctxs[2];
 
 static struct sftp_mac write_macs[] = {
-  { NULL, NULL, NULL, 0 },
-  { NULL, NULL, NULL, 0 }
+  { NULL, 0, NULL, NULL, 0 },
+  { NULL, 0, NULL, NULL, 0 }
 };
-static HMAC_CTX write_ctxs[2];
+static HMAC_CTX hmac_write_ctxs[2];
+static struct umac_ctx *umac_write_ctxs[2];
 
 static size_t mac_blockszs[2] = { 0, 0 };
 
@@ -93,10 +104,12 @@
   if (read_macs[read_mac_idx].key) {
     clear_mac(&(read_macs[read_mac_idx]));
 #if OPENSSL_VERSION_NUMBER > 0x000907000L
-    HMAC_CTX_cleanup(&(read_ctxs[read_mac_idx]));
+    HMAC_CTX_cleanup(&(hmac_read_ctxs[read_mac_idx]));
 #else
-    HMAC_cleanup(&(read_ctxs[read_mac_idx]));
+    HMAC_cleanup(&(hmac_read_ctxs[read_mac_idx]));
 #endif
+    umac_reset(umac_read_ctxs[read_mac_idx]);
+
     mac_blockszs[read_mac_idx] = 0; 
 
     /* Now we can switch the index. */
@@ -114,10 +127,11 @@
   if (write_macs[write_mac_idx].key) {
     clear_mac(&(write_macs[write_mac_idx]));
 #if OPENSSL_VERSION_NUMBER > 0x000907000L
-    HMAC_CTX_cleanup(&(write_ctxs[write_mac_idx]));
+    HMAC_CTX_cleanup(&(hmac_write_ctxs[write_mac_idx]));
 #else
-    HMAC_cleanup(&(write_ctxs[write_mac_idx]));
+    HMAC_cleanup(&(hmac_write_ctxs[write_mac_idx]));
 #endif
+    umac_reset(umac_write_ctxs[write_mac_idx]);
 
     /* Now we can switch the index. */
     if (write_mac_idx == 1) {
@@ -142,6 +156,209 @@
   mac->algo = NULL;
 }
 
+static int init_mac(pool *p, struct sftp_mac *mac, HMAC_CTX *hmac_ctx,
+    struct umac_ctx *umac_ctx) {
+#if OPENSSL_VERSION_NUMBER > 0x000907000L
+  HMAC_CTX_init(hmac_ctx);
+#else
+  /* Reset the HMAC context. */
+  HMAC_Init(hmac_ctx, NULL, 0, NULL);
+#endif
+  umac_reset(umac_ctx);
+
+  if (mac->algo_type == SFTP_MAC_ALGO_TYPE_HMAC) {
+#if OPENSSL_VERSION_NUMBER > 0x000907000L
+# if OPENSSL_VERSION_NUMBER >= 0x10000001L
+    if (HMAC_Init_ex(hmac_ctx, mac->key, mac->key_len, mac->digest,
+        NULL) != 1) {
+      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "error initializing HMAC: %s", sftp_crypto_get_errors());
+      errno = EPERM;
+      return -1;
+    }
+
+# else
+    HMAC_Init_ex(hmac_ctx, mac->key, mac->key_len, mac->digest, NULL);
+# endif /* OpenSSL-1.0.0 and later */
+
+#else
+    HMAC_Init(hmac_ctx, mac->key, mac->key_len, mac->digest);
+#endif
+
+  } else if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC64) {
+    umac_init(umac_ctx, mac->key);
+  }
+
+  return 0;
+}
+
+static int get_mac(struct ssh2_packet *pkt, struct sftp_mac *mac,
+    HMAC_CTX *hmac_ctx, struct umac_ctx *umac_ctx, int flags) {
+  unsigned char *mac_data;
+  unsigned char *buf, *ptr;
+  uint32_t buflen, bufsz = 0, mac_len = 0;
+
+  if (mac->algo_type == SFTP_MAC_ALGO_TYPE_HMAC) {
+    bufsz = (sizeof(uint32_t) * 2) + pkt->packet_len;
+    mac_data = pcalloc(pkt->pool, EVP_MAX_MD_SIZE);
+
+    buflen = bufsz;
+    ptr = buf = sftp_msg_getbuf(pkt->pool, bufsz);
+
+    sftp_msg_write_int(&buf, &buflen, pkt->seqno);
+    sftp_msg_write_int(&buf, &buflen, pkt->packet_len);
+    sftp_msg_write_byte(&buf, &buflen, pkt->padding_len);
+    sftp_msg_write_data(&buf, &buflen, pkt->payload, pkt->payload_len, FALSE);
+    sftp_msg_write_data(&buf, &buflen, pkt->padding, pkt->padding_len, FALSE);
+
+#if OPENSSL_VERSION_NUMBER > 0x000907000L
+# if OPENSSL_VERSION_NUMBER >= 0x10000001L
+    if (HMAC_Init_ex(hmac_ctx, NULL, 0, NULL, NULL) != 1) {
+      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "error resetting HMAC context: %s", sftp_crypto_get_errors());
+      errno = EPERM;
+      return -1;
+    }
+# else
+    HMAC_Init_ex(hmac_ctx, NULL, 0, NULL, NULL);
+# endif /* OpenSSL-1.0.0 and later */
+
+#else
+    HMAC_Init(hmac_ctx, NULL, 0, NULL);
+#endif /* OpenSSL-0.9.7 and later */
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000001L
+    if (HMAC_Update(hmac_ctx, ptr, (bufsz - buflen)) != 1) {
+      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "error adding %lu bytes of data to  HMAC context: %s",
+        (unsigned long) (bufsz - buflen), sftp_crypto_get_errors());
+      errno = EPERM;
+      return -1;
+    }
+
+    if (HMAC_Final(hmac_ctx, mac_data, &mac_len) != 1) {
+      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "error finalizing HMAC context: %s", sftp_crypto_get_errors());
+      errno = EPERM;
+      return -1;
+    }
+#else
+    HMAC_Update(hmac_ctx, ptr, (bufsz - buflen));
+    HMAC_Final(hmac_ctx, mac_data, &mac_len);
+#endif /* OpenSSL-1.0.0 and later */
+
+  } else if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC64) {
+    unsigned char nonce[8], *nonce_ptr;
+    uint32_t nonce_len = 0;
+
+    bufsz = sizeof(uint32_t) + pkt->packet_len;
+    mac_data = pcalloc(pkt->pool, EVP_MAX_MD_SIZE);
+
+    buflen = bufsz;
+    ptr = buf = sftp_msg_getbuf(pkt->pool, bufsz);
+
+    sftp_msg_write_int(&buf, &buflen, pkt->packet_len);
+    sftp_msg_write_byte(&buf, &buflen, pkt->padding_len);
+    sftp_msg_write_data(&buf, &buflen, pkt->payload, pkt->payload_len, FALSE);
+    sftp_msg_write_data(&buf, &buflen, pkt->padding, pkt->padding_len, FALSE);
+
+    nonce_ptr = nonce;
+    nonce_len = sizeof(nonce);
+    sftp_msg_write_long(&nonce_ptr, &nonce_len, pkt->seqno);
+
+    umac_reset(umac_ctx);
+    umac_update(umac_ctx, ptr, (bufsz - buflen));
+    umac_final(umac_ctx, mac_data, nonce);
+    mac_len = 8;
+  }
+
+  if (mac_len == 0) {
+    pkt->mac = NULL;
+    pkt->mac_len = 0;
+
+    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+      "error computing MAC using %s: %s", mac->algo,
+      sftp_crypto_get_errors());
+
+    errno = EIO;
+    return -1;
+  }
+
+  if (mac->mac_len != 0) {
+    mac_len = mac->mac_len;
+  }
+
+  if (flags & SFTP_MAC_FL_READ_MAC) {
+    if (memcmp(mac_data, pkt->mac, mac_len) != 0) {
+      unsigned int i = 0;
+
+      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "MAC from client differs from expected MAC using %s", mac->algo);
+
+#ifdef SFTP_DEBUG_PACKET
+      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "client MAC (len %lu):", (unsigned long) pkt->mac_len);
+      for (i = 0; i < mac_len;) {
+        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+          "  %02x%02x %02x%02x %02x%02x %02x%02x",
+          ((unsigned char *) pkt->mac)[i], ((unsigned char *) pkt->mac)[i+1],
+          ((unsigned char *) pkt->mac)[i+2], ((unsigned char *) pkt->mac)[i+3],
+          ((unsigned char *) pkt->mac)[i+4], ((unsigned char *) pkt->mac)[i+5],
+          ((unsigned char *) pkt->mac)[i+6], ((unsigned char *) pkt->mac)[i+7]);
+        i += 8;
+      }
+
+      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "server MAC (len %lu):", (unsigned long) mac_len);
+      for (i = 0; i < mac_len;) {
+        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+          "  %02x%02x %02x%02x %02x%02x %02x%02x",
+          ((unsigned char *) mac)[i], ((unsigned char *) mac)[i+1],
+          ((unsigned char *) mac)[i+2], ((unsigned char *) mac)[i+3],
+          ((unsigned char *) mac)[i+4], ((unsigned char *) mac)[i+5],
+          ((unsigned char *) mac)[i+6], ((unsigned char *) mac)[i+7]);
+        i += 8;
+      }
+#else
+      /* Avoid compiler warning. */
+      (void) i;
+#endif
+
+      errno = EINVAL;
+      return -1;
+    }
+
+  } else if (flags & SFTP_MAC_FL_WRITE_MAC) {
+    unsigned int i = 0;
+#ifdef SFTP_DEBUG_PACKET
+
+    if (pkt->mac_len > 0) {
+      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "server MAC (len %lu, seqno %lu):",
+        (unsigned long) pkt->mac_len, (unsigned long) pkt->seqno);
+      for (i = 0; i < mac_len;) {
+        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+          "  %02x%02x %02x%02x %02x%02x %02x%02x",
+          ((unsigned char *) pkt->mac)[i], ((unsigned char *) pkt->mac)[i+1],
+          ((unsigned char *) pkt->mac)[i+2], ((unsigned char *) pkt->mac)[i+3],
+          ((unsigned char *) pkt->mac)[i+4], ((unsigned char *) pkt->mac)[i+5],
+          ((unsigned char *) pkt->mac)[i+6], ((unsigned char *) pkt->mac)[i+7]);
+        i += 8;
+      }
+    }
+#else
+    /* Avoid compiler warning. */
+    (void) i;
+#endif
+  }
+
+  pkt->mac_len = mac_len;
+  pkt->mac = pcalloc(pkt->pool, pkt->mac_len);
+  memcpy(pkt->mac, mac_data, mac_len);
+
+  return 0;
+}
+
 static int set_mac_key(struct sftp_mac *mac, const EVP_MD *hash,
     const unsigned char *k, uint32_t klen, const char *h, uint32_t hlen,
     char *letter, const unsigned char *id, uint32_t id_len) {
@@ -149,10 +366,9 @@
   unsigned char *key = NULL;
   size_t key_sz;
   uint32_t key_len = 0;
- 
+
   key_sz = sftp_crypto_get_size(EVP_MD_block_size(mac->digest),
     EVP_MD_size(hash)); 
-
   if (key_sz == 0) {
     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
       "unable to determine key length for MAC '%s'", mac->algo);
@@ -242,6 +458,7 @@
   /* If we need more, keep hashing, as per RFC, until we have enough
    * material.
    */
+
   while (key_sz > key_len) {
     uint32_t len = key_len;
 
@@ -314,7 +531,13 @@
   mac->key = key;
   mac->keysz = key_sz;
 
-  mac->key_len = EVP_MD_size(mac->digest);
+  if (mac->algo_type == SFTP_MAC_ALGO_TYPE_HMAC) {
+    mac->key_len = EVP_MD_size(mac->digest);
+
+  } else if (mac->algo_type == SFTP_MAC_ALGO_TYPE_UMAC64) {
+    mac->key_len = EVP_MD_block_size(mac->digest);
+  }
+
   if (!sftp_interop_supports_feature(SFTP_SSH2_FEAT_MAC_LEN)) {
     mac->key_len = 16;
   }
@@ -350,10 +573,18 @@
   }
 
   read_macs[idx].digest = sftp_crypto_get_digest(algo, &mac_len);
-  if (read_macs[idx].digest == NULL)
+  if (read_macs[idx].digest == NULL) {
     return -1;
+  }
 
   read_macs[idx].algo = algo;
+  if (strncmp(read_macs[idx].algo, "umac-64@openssh.com", 12) == 0) {
+    read_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_UMAC64;
+
+  } else {
+    read_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_HMAC;
+  }
+
   read_macs[idx].mac_len = mac_len;
   return 0;
 }
@@ -366,12 +597,14 @@
   char letter;
   size_t blocksz;
   struct sftp_mac *mac;
-  HMAC_CTX *mac_ctx;
+  HMAC_CTX *hmac_ctx;
+  struct umac_ctx *umac_ctx;
 
   switch_read_mac();
 
   mac = &(read_macs[read_mac_idx]);
-  mac_ctx = &(read_ctxs[read_mac_idx]);
+  hmac_ctx = &(hmac_read_ctxs[read_mac_idx]);
+  umac_ctx = umac_read_ctxs[read_mac_idx];
 
   bufsz = buflen = 1024;
   ptr = buf = sftp_msg_getbuf(p, bufsz);
@@ -385,27 +618,10 @@
   letter = 'E';
   set_mac_key(mac, hash, ptr, (bufsz - buflen), h, hlen, &letter, id, id_len);
 
-#if OPENSSL_VERSION_NUMBER > 0x000907000L
-  HMAC_CTX_init(mac_ctx);
-
-# if OPENSSL_VERSION_NUMBER >= 0x10000001L
-  if (HMAC_Init_ex(mac_ctx, mac->key, mac->key_len, mac->digest, NULL) != 1) {
-    pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-      "error initializing HMAC: %s", sftp_crypto_get_errors());
-    errno = EPERM;
+  if (init_mac(p, mac, hmac_ctx, umac_ctx) < 0) {
     return -1;
   }
 
-# else
-  HMAC_Init_ex(mac_ctx, mac->key, mac->key_len, mac->digest, NULL);
-# endif /* OpenSSL-1.0.0 and later */
-
-#else
-  /* Reset the HMAC context. */
-  HMAC_Init(mac_ctx, NULL, 0, NULL);
-  HMAC_Init(mac_ctx, mac->key, mac->key_len, mac->digest);
-#endif
-
   if (mac->mac_len == 0) {
     blocksz = EVP_MD_size(mac->digest);
 
@@ -420,120 +636,26 @@
 
 int sftp_mac_read_data(struct ssh2_packet *pkt) {
   struct sftp_mac *mac;
-  HMAC_CTX *mac_ctx;
+  HMAC_CTX *hmac_ctx;
+  struct umac_ctx *umac_ctx;
+  int res;
 
   mac = &(read_macs[read_mac_idx]);
-  mac_ctx = &(read_ctxs[read_mac_idx]);
-
-  if (mac->key) {
-    unsigned char *buf, *ptr, *mac_data;
-    uint32_t buflen, bufsz = (sizeof(uint32_t) * 2) + pkt->packet_len,
-      mac_len = 0;
-
-    mac_data = pcalloc(pkt->pool, EVP_MAX_MD_SIZE);
-
-    buflen = bufsz;
-    ptr = buf = sftp_msg_getbuf(pkt->pool, bufsz);
-
-    sftp_msg_write_int(&buf, &buflen, pkt->seqno);
-    sftp_msg_write_int(&buf, &buflen, pkt->packet_len);
-    sftp_msg_write_byte(&buf, &buflen, pkt->padding_len);
-    sftp_msg_write_data(&buf, &buflen, pkt->payload, pkt->payload_len, FALSE);
-    sftp_msg_write_data(&buf, &buflen, pkt->padding, pkt->padding_len, FALSE);
-
-#if OPENSSL_VERSION_NUMBER > 0x000907000L
-# if OPENSSL_VERSION_NUMBER >= 0x10000001L
-    if (HMAC_Init_ex(mac_ctx, NULL, 0, NULL, NULL) != 1) {
-      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "error resetting HMAC context: %s", sftp_crypto_get_errors());
-      errno = EPERM;
-      return -1;
-    }
-# else
-    HMAC_Init_ex(mac_ctx, NULL, 0, NULL, NULL);
-# endif /* OpenSSL-1.0.0 and later */
-
-#else
-    HMAC_Init(mac_ctx, NULL, 0, NULL);
-#endif /* OpenSSL-0.9.7 and later */
-
-#if OPENSSL_VERSION_NUMBER >= 0x10000001L
-    if (HMAC_Update(mac_ctx, ptr, (bufsz - buflen)) != 1) {
-      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "error adding %lu bytes of data to  HMAC context: %s",
-        (unsigned long) (bufsz - buflen), sftp_crypto_get_errors());
-      errno = EPERM;
-      return -1;
-    }
-
-    if (HMAC_Final(mac_ctx, mac_data, &mac_len) != 1) {
-      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "error finalizing HMAC context: %s", sftp_crypto_get_errors());
-      errno = EPERM;
-      return -1;
-    }
-#else
-    HMAC_Update(mac_ctx, ptr, (bufsz - buflen));
-    HMAC_Final(mac_ctx, mac_data, &mac_len);
-#endif /* OpenSSL-1.0.0 and later */
-
-    if (mac_len == 0) {
-      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "error computing MAC using %s: %s", mac->algo,
-        sftp_crypto_get_errors());
-      SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL);
-    }
-
-    if (mac->mac_len != 0) {
-      mac_len = mac->mac_len;
-    }
-
-    if (mac_len != pkt->mac_len) {
-      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "expected %u MAC len from client, got %lu", mac_len,
-        (unsigned long) pkt->mac_len);
-      SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL);
-    }
-
-    if (memcmp(mac_data, pkt->mac, mac_len) != 0) {
-      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "MAC from client differs from expected MAC using %s", mac->algo);
-
-#ifdef SFTP_DEBUG_PACKET
-{
-      unsigned int i;
-      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "client MAC (len %lu):", (unsigned long) pkt->mac_len);
-      for (i = 0; i < mac_len;) {
-        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-          "  %02x%02x %02x%02x %02x%02x %02x%02x",
-          ((unsigned char *) pkt->mac)[i], ((unsigned char *) pkt->mac)[i+1],
-          ((unsigned char *) pkt->mac)[i+2], ((unsigned char *) pkt->mac)[i+3],
-          ((unsigned char *) pkt->mac)[i+4], ((unsigned char *) pkt->mac)[i+5],
-          ((unsigned char *) pkt->mac)[i+6], ((unsigned char *) pkt->mac)[i+7]);
-        i += 8;
-      }
-
-      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "server MAC (len %lu):", (unsigned long) mac_len);
-      for (i = 0; i < mac_len;) {
-        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-          "  %02x%02x %02x%02x %02x%02x %02x%02x",
-          ((unsigned char *) mac)[i], ((unsigned char *) mac)[i+1],
-          ((unsigned char *) mac)[i+2], ((unsigned char *) mac)[i+3],
-          ((unsigned char *) mac)[i+4], ((unsigned char *) mac)[i+5],
-          ((unsigned char *) mac)[i+6], ((unsigned char *) mac)[i+7]);
-        i += 8;
-      }
-}
-#endif
+  hmac_ctx = &(hmac_read_ctxs[read_mac_idx]);
+  umac_ctx = umac_read_ctxs[read_mac_idx];
 
-      SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL);
-    }
+  if (mac->key == NULL) {
+    pkt->mac = NULL;
+    pkt->mac_len = 0;
 
     return 0;
   }
 
+  res = get_mac(pkt, mac, hmac_ctx, umac_ctx, SFTP_MAC_FL_READ_MAC);
+  if (res < 0) {
+    return -1;
+  }
+
   return 0;
 }
 
@@ -555,10 +677,18 @@
   }
 
   write_macs[idx].digest = sftp_crypto_get_digest(algo, &mac_len);
-  if (write_macs[idx].digest == NULL)
+  if (write_macs[idx].digest == NULL) {
     return -1;
+  }
 
   write_macs[idx].algo = algo;
+  if (strncmp(write_macs[idx].algo, "umac-64@openssh.com", 12) == 0) {
+    write_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_UMAC64;
+
+  } else {
+    write_macs[idx].algo_type = SFTP_MAC_ALGO_TYPE_HMAC;
+  }
+
   write_macs[idx].mac_len = mac_len;
   return 0;
 }
@@ -570,12 +700,14 @@
   uint32_t buflen, bufsz, id_len;
   char letter;
   struct sftp_mac *mac;
-  HMAC_CTX *mac_ctx;
+  HMAC_CTX *hmac_ctx;
+  struct umac_ctx *umac_ctx;
 
   switch_write_mac();
 
   mac = &(write_macs[write_mac_idx]);
-  mac_ctx = &(write_ctxs[write_mac_idx]);
+  hmac_ctx = &(hmac_write_ctxs[write_mac_idx]);
+  umac_ctx = umac_write_ctxs[write_mac_idx];
 
   bufsz = buflen = 1024;
   ptr = buf = sftp_msg_getbuf(p, bufsz);
@@ -589,13 +721,9 @@
   letter = 'F';
   set_mac_key(mac, hash, ptr, (bufsz - buflen), h, hlen, &letter, id, id_len);
 
-#if OPENSSL_VERSION_NUMBER > 0x000907000L
-  HMAC_CTX_init(mac_ctx);
-#else
-  /* Reset the HMAC context. */
-  HMAC_Init(mac_ctx, NULL, 0, NULL);
-#endif
-  HMAC_Init(mac_ctx, mac->key, mac->key_len, mac->digest);
+  if (init_mac(p, mac, hmac_ctx, umac_ctx) < 0) {
+    return -1;
+  }
 
   pr_memscrub(ptr, bufsz);
   return 0;
@@ -603,109 +731,40 @@
 
 int sftp_mac_write_data(struct ssh2_packet *pkt) {
   struct sftp_mac *mac;
-  HMAC_CTX *mac_ctx;
+  HMAC_CTX *hmac_ctx;
+  struct umac_ctx *umac_ctx;
+  int res;
 
   mac = &(write_macs[write_mac_idx]);
-  mac_ctx = &(write_ctxs[write_mac_idx]);
-
-  if (mac->key) {
-    unsigned char *mac_data;
-    unsigned char *buf, *ptr;
-    uint32_t buflen, bufsz = (sizeof(uint32_t) * 2) + pkt->packet_len,
-      mac_len = 0;
-
-    mac_data = pcalloc(pkt->pool, EVP_MAX_MD_SIZE);
-
-    buflen = bufsz;
-    ptr = buf = sftp_msg_getbuf(pkt->pool, bufsz);
-
-    sftp_msg_write_int(&buf, &buflen, pkt->seqno);
-    sftp_msg_write_int(&buf, &buflen, pkt->packet_len);
-    sftp_msg_write_byte(&buf, &buflen, pkt->padding_len);
-    sftp_msg_write_data(&buf, &buflen, pkt->payload, pkt->payload_len, FALSE);
-    sftp_msg_write_data(&buf, &buflen, pkt->padding, pkt->padding_len, FALSE);
-
-#if OPENSSL_VERSION_NUMBER > 0x000907000L
-# if OPENSSL_VERSION_NUMBER >= 0x10000001L
-    if (HMAC_Init_ex(mac_ctx, NULL, 0, NULL, NULL) != 1) {
-      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "error resetting HMAC context: %s", sftp_crypto_get_errors());
-      errno = EPERM;
-      return -1;
-    }
-# else
-    HMAC_Init_ex(mac_ctx, NULL, 0, NULL, NULL);
-# endif /* OpenSSL-1.0.0 and later */
-
-#else
-    HMAC_Init(mac_ctx, NULL, 0, NULL);
-#endif /* OpenSSL-0.9.7 and later */
-
-#if OPENSSL_VERSION_NUMBER >= 0x10000001L
-    if (HMAC_Update(mac_ctx, ptr, (bufsz - buflen)) != 1) {
-      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "error adding %lu bytes of data to  HMAC context: %s",
-        (unsigned long) (bufsz - buflen), sftp_crypto_get_errors());
-      errno = EPERM;
-      return -1;
-    }
+  hmac_ctx = &(hmac_write_ctxs[write_mac_idx]);
+  umac_ctx = umac_write_ctxs[write_mac_idx];
 
-    if (HMAC_Final(mac_ctx, mac_data, &mac_len) != 1) {
-      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "error finalizing HMAC context: %s", sftp_crypto_get_errors());
-      errno = EPERM;
-      return -1;
-    }
-#else
-    HMAC_Update(mac_ctx, ptr, (bufsz - buflen));
-    HMAC_Final(mac_ctx, mac_data, &mac_len);
-#endif /* OpenSSL-1.0.0 and later */
+  if (mac->key == NULL) {
+    pkt->mac = NULL;
+    pkt->mac_len = 0;
 
-    if (mac_len == 0) {
-      pkt->mac = NULL;
-      pkt->mac_len = 0;
+    return 0;
+  }
 
-      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-        "error computing MAC using %s: %s", mac->algo,
-        sftp_crypto_get_errors());
+  res = get_mac(pkt, mac, hmac_ctx, umac_ctx, SFTP_MAC_FL_WRITE_MAC);
+  if (res < 0) {
+    return -1;
+  }
 
-      errno = EIO;
-      return -1;
-    }
+  return 0;
+}
 
-    if (mac->mac_len != 0) {
-      mac_len = mac->mac_len;
-    }
+int sftp_mac_init(void) {
 
-    pkt->mac_len = mac_len;
-    pkt->mac = pcalloc(pkt->pool, pkt->mac_len);
-    memcpy(pkt->mac, mac_data, mac_len);
+  umac_read_ctxs[0] = umac_alloc();
+  umac_read_ctxs[1] = umac_alloc();
 
-#ifdef SFTP_DEBUG_PACKET
-{
-  unsigned int i;
+  umac_write_ctxs[0] = umac_alloc();
+  umac_write_ctxs[1] = umac_alloc();
 
-  (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-    "server MAC (len %lu, seqno %lu):",
-    (unsigned long) pkt->mac_len, (unsigned long) pkt->seqno);
-  for (i = 0; i < mac_len;) {
-    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-      "  %02x%02x %02x%02x %02x%02x %02x%02x",
-      ((unsigned char *) pkt->mac)[i], ((unsigned char *) pkt->mac)[i+1],
-      ((unsigned char *) pkt->mac)[i+2], ((unsigned char *) pkt->mac)[i+3],
-      ((unsigned char *) pkt->mac)[i+4], ((unsigned char *) pkt->mac)[i+5],
-      ((unsigned char *) pkt->mac)[i+6], ((unsigned char *) pkt->mac)[i+7]);
-    i += 8;
-  }
+  return 0;
 }
-#endif
-
-    return 0;
-  }
-
-  pkt->mac = NULL;
-  pkt->mac_len = 0;
 
+int sftp_mac_free(void) {
   return 0;
 }
-

Index: Makefile.in
===================================================================
RCS file: /cvsroot/proftp/proftpd/contrib/mod_sftp/Makefile.in,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- Makefile.in	6 Mar 2012 01:17:58 -0000	1.8
+++ Makefile.in	28 Mar 2013 18:48:31 -0000	1.9
@@ -11,12 +11,12 @@
 VPATH=@srcdir@
 
 MODULE_NAME=mod_sftp
-MODULE_OBJS=mod_sftp.o msg.o packet.o cipher.o mac.o compress.o kex.o keys.o \
-  crypto.o utf8.o session.o service.o kbdint.o auth-hostbased.o auth-kbdint.o \
-  auth-password.o auth-publickey.o auth.o disconnect.o rfc4716.o keystore.o \
-  channel.o blacklist.o agent.o interop.o tap.o fxp.o scp.o display.o misc.o \
-  date.o
-SHARED_MODULE_OBJS=mod_sftp.lo msg.lo packet.lo cipher.lo mac.lo \
+MODULE_OBJS=mod_sftp.o msg.o packet.o cipher.o mac.o umac.o \
+  compress.o kex.o keys.o crypto.o utf8.o session.o service.o kbdint.o \
+  auth-hostbased.o auth-kbdint.o auth-password.o auth-publickey.o auth.o \
+  disconnect.o rfc4716.o keystore.o channel.o blacklist.o agent.o \
+  interop.o tap.o fxp.o scp.o display.o misc.o date.o
+SHARED_MODULE_OBJS=mod_sftp.lo msg.lo packet.lo cipher.lo mac.lo umac.lo \
   compress.lo kex.lo keys.lo crypto.lo utf8.lo session.lo service.lo kbdint.lo \
   auth-hostbased.lo auth-kbdint.lo auth-password.lo auth-publickey.lo auth.lo \
   disconnect.lo rfc4716.lo keystore.lo channel.lo blacklist.lo agent.lo \

Index: fxp.c
===================================================================
RCS file: /cvsroot/proftp/proftpd/contrib/mod_sftp/fxp.c,v
retrieving revision 1.189
retrieving revision 1.190
diff -u -d -r1.189 -r1.190
--- fxp.c	13 Mar 2013 18:05:41 -0000	1.189
+++ fxp.c	28 Mar 2013 18:48:31 -0000	1.190
@@ -1228,34 +1228,6 @@
 }
 #endif
 
-static uint64_t fxp_msg_read_long(pool *p, unsigned char **buf,
-    uint32_t *buflen) {
-  uint64_t val;
-  unsigned char data[8];
-
-  if (*buflen < sizeof(data)) {
-    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-      "SFTP message format error: unable to read long (buflen = %lu)",
-      (unsigned long) *buflen); 
-    SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
-  }
-
-  memcpy(data, *buf, sizeof(data));
-  (*buf) += sizeof(data);
-  (*buflen) -= sizeof(data);
-
-  val = (uint64_t) data[0] << 56;
-  val |= (uint64_t) data[1] << 48;
-  val |= (uint64_t) data[2] << 40;
-  val |= (uint64_t) data[3] << 32;
-  val |= (uint64_t) data[4] << 24;
-  val |= (uint64_t) data[5] << 16;
-  val |= (uint64_t) data[6] << 8;
-  val |= (uint64_t) data[7];
-
-  return val;
-}
-
 static struct fxp_extpair *fxp_msg_read_extpair(pool *p, unsigned char **buf,
     uint32_t *buflen) {
   uint32_t namelen, datalen;
@@ -1313,29 +1285,6 @@
   return len;
 }
 
-static uint32_t fxp_msg_write_long(unsigned char **buf, uint32_t *buflen,
-    uint64_t val) {
-  unsigned char data[8];
-
-  if (*buflen < sizeof(uint64_t)) {
-    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
-      "SFTP message format error: unable to write long (buflen = %lu)",
-      (unsigned long) *buflen);
-    SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
-  }
-
-  data[0] = (unsigned char) (val >> 56) & 0xFF;
-  data[1] = (unsigned char) (val >> 48) & 0xFF;
-  data[2] = (unsigned char) (val >> 40) & 0xFF;
-  data[3] = (unsigned char) (val >> 32) & 0xFF;
-  data[4] = (unsigned char) (val >> 24) & 0xFF;
-  data[5] = (unsigned char) (val >> 16) & 0xFF;
-  data[6] = (unsigned char) (val >> 8) & 0xFF;
-  data[7] = (unsigned char) val & 0xFF;
-
-  return sftp_msg_write_data(buf, buflen, data, sizeof(data), FALSE);
-}
-
 static void fxp_msg_write_extpair(unsigned char **buf, uint32_t *buflen,
     struct fxp_extpair *extpair) {
   uint32_t len;
@@ -1920,7 +1869,7 @@
 
   if (fxp_session->client_version <= 3) {
     if (*flags & SSH2_FX_ATTR_SIZE) {
-      st->st_size = fxp_msg_read_long(fxp->pool, buf, buflen);
+      st->st_size = sftp_msg_read_long(fxp->pool, buf, buflen);
     }
 
     if (*flags & SSH2_FX_ATTR_UIDGID) {
@@ -1995,14 +1944,14 @@
     }
 
     if (*flags & SSH2_FX_ATTR_SIZE) {
-      st->st_size = fxp_msg_read_long(fxp->pool, buf, buflen);
+      st->st_size = sftp_msg_read_long(fxp->pool, buf, buflen);
     }
 
     if (*flags & SSH2_FX_ATTR_ALLOCATION_SIZE) {
       /* Read (and ignore) any allocation size attribute. */
       uint64_t allosz;
 
-      allosz = fxp_msg_read_long(fxp->pool, buf, buflen);
+      allosz = sftp_msg_read_long(fxp->pool, buf, buflen);
       pr_trace_msg(trace_channel, 15,
         "protocol version %lu: read ALLOCATION_SIZE attribute: %" PR_LU,
         (unsigned long) fxp_session->client_version, (pr_off_t) allosz);
@@ -2091,7 +2040,7 @@
     }
 
     if (*flags & SSH2_FX_ATTR_ACCESSTIME) {
-      st->st_atime = fxp_msg_read_long(fxp->pool, buf, buflen);
+      st->st_atime = sftp_msg_read_long(fxp->pool, buf, buflen);
 
       if (*flags & SSH2_FX_ATTR_SUBSECOND_TIMES) {
         /* Read (and ignore) the nanoseconds field. */
@@ -2109,7 +2058,7 @@
       /* Read (and ignore) the create time attribute. */
       uint64_t create_time;
 
-      create_time = fxp_msg_read_long(fxp->pool, buf, buflen);
+      create_time = sftp_msg_read_long(fxp->pool, buf, buflen);
       pr_trace_msg(trace_channel, 15,
         "protocol version %lu: read CREATETIME attribute: %" PR_LU,
         (unsigned long) fxp_session->client_version, (pr_off_t) create_time);
@@ -2127,7 +2076,7 @@
     }
 
     if (*flags & SSH2_FX_ATTR_MODIFYTIME) {
-      st->st_mtime = fxp_msg_read_long(fxp->pool, buf, buflen);
+      st->st_mtime = sftp_msg_read_long(fxp->pool, buf, buflen);
 
       if (*flags & SSH2_FX_ATTR_SUBSECOND_TIMES) {
         /* Read (and ignore) the nanoseconds field. */
@@ -2145,7 +2094,7 @@
       /* Read (and ignore) the ctime attribute. */
       uint64_t change_time;
 
-      change_time = fxp_msg_read_long(fxp->pool, buf, buflen);
+      change_time = sftp_msg_read_long(fxp->pool, buf, buflen);
       pr_trace_msg(trace_channel, 15,
         "protocol version %lu: read CTIME attribute: %" PR_LU,
         (unsigned long) fxp_session->client_version, (pr_off_t) change_time);
@@ -2341,7 +2290,7 @@
     perms = st->st_mode;
 
     len += sftp_msg_write_int(buf, buflen, flags);
-    len += fxp_msg_write_long(buf, buflen, st->st_size);
+    len += sftp_msg_write_long(buf, buflen, st->st_size);
     len += sftp_msg_write_int(buf, buflen, st->st_uid);
     len += sftp_msg_write_int(buf, buflen, st->st_gid);
     len += sftp_msg_write_int(buf, buflen, perms);
@@ -2365,7 +2314,7 @@
 
     len += sftp_msg_write_int(buf, buflen, flags);
     len += sftp_msg_write_byte(buf, buflen, file_type);
-    len += fxp_msg_write_long(buf, buflen, st->st_size);
+    len += sftp_msg_write_long(buf, buflen, st->st_size);
 
     if (user_owner == NULL) {
       len += sftp_msg_write_string(buf, buflen,
@@ -2384,8 +2333,8 @@
     }
 
     len += sftp_msg_write_int(buf, buflen, perms);
-    len += fxp_msg_write_long(buf, buflen, st->st_atime);
-    len += fxp_msg_write_long(buf, buflen, st->st_mtime);
+    len += sftp_msg_write_long(buf, buflen, st->st_atime);
+    len += sftp_msg_write_long(buf, buflen, st->st_mtime);
   }
 
   return len;
@@ -3296,7 +3245,7 @@
   sftp_msg_write_string(&buf2, &buflen2, vendor_name);
   sftp_msg_write_string(&buf2, &buflen2, product_name);
   sftp_msg_write_string(&buf2, &buflen2, product_version);
-  fxp_msg_write_long(&buf2, &buflen2, build_number);
+  sftp_msg_write_long(&buf2, &buflen2, build_number);
 
   ext.ext_name = "vendor-id";
   ext.ext_data = ptr2;
@@ -4643,16 +4592,16 @@
   sftp_msg_write_int(&buf, &buflen, fxp->request_id);
 
   /* Total bytes on device */
-  fxp_msg_write_long(&buf, &buflen, (uint64_t) get_fs_bytes_total(&fs));
+  sftp_msg_write_long(&buf, &buflen, (uint64_t) get_fs_bytes_total(&fs));
 
   /* Unused bytes on device. */
-  fxp_msg_write_long(&buf, &buflen, (uint64_t) get_fs_bytes_unused(&fs));
+  sftp_msg_write_long(&buf, &buflen, (uint64_t) get_fs_bytes_unused(&fs));
 
   /* Total bytes available to user. */
-  fxp_msg_write_long(&buf, &buflen, (uint64_t) get_user_bytes_avail(&fs));
+  sftp_msg_write_long(&buf, &buflen, (uint64_t) get_user_bytes_avail(&fs));
 
   /* Unused bytes available to user. */
-  fxp_msg_write_long(&buf, &buflen, (uint64_t) get_user_bytes_unused(&fs));
+  sftp_msg_write_long(&buf, &buflen, (uint64_t) get_user_bytes_unused(&fs));
 
   fxp_msg_write_short(&buf, &buflen, (uint32_t) fs.f_frsize);
 
@@ -4714,14 +4663,14 @@
 
   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_FXP_EXTENDED_REPLY);
   sftp_msg_write_int(&buf, &buflen, fxp->request_id);
-  fxp_msg_write_long(&buf, &buflen, fs.f_bsize);
-  fxp_msg_write_long(&buf, &buflen, fs.f_frsize);
-  fxp_msg_write_long(&buf, &buflen, fs.f_blocks);
-  fxp_msg_write_long(&buf, &buflen, fs.f_bfree);
-  fxp_msg_write_long(&buf, &buflen, fs.f_bavail);
-  fxp_msg_write_long(&buf, &buflen, fs.f_files);
-  fxp_msg_write_long(&buf, &buflen, fs.f_ffree);
-  fxp_msg_write_long(&buf, &buflen, fs.f_favail);
+  sftp_msg_write_long(&buf, &buflen, fs.f_bsize);
+  sftp_msg_write_long(&buf, &buflen, fs.f_frsize);
+  sftp_msg_write_long(&buf, &buflen, fs.f_blocks);
+  sftp_msg_write_long(&buf, &buflen, fs.f_bfree);
+  sftp_msg_write_long(&buf, &buflen, fs.f_bavail);
+  sftp_msg_write_long(&buf, &buflen, fs.f_files);
+  sftp_msg_write_long(&buf, &buflen, fs.f_ffree);
+  sftp_msg_write_long(&buf, &buflen, fs.f_favail);
 
   /* AIX requires this machination because a) its statvfs struct has
    * non-standard data types for the fsid value:
@@ -4739,7 +4688,7 @@
 #if !defined(AIX4) && !defined(AIX5)
   memcpy(&fs_id, &(fs.f_fsid), sizeof(fs_id));
 #endif
-  fxp_msg_write_long(&buf, &buflen, fs_id);
+  sftp_msg_write_long(&buf, &buflen, fs_id);
 
   /* These flags and values are defined by OpenSSH's PROTOCOL document.
    *
@@ -4759,8 +4708,8 @@
   }
 #endif
 
-  fxp_msg_write_long(&buf, &buflen, fs_flags);
-  fxp_msg_write_long(&buf, &buflen, fs.f_namemax);
+  sftp_msg_write_long(&buf, &buflen, fs_flags);
+  sftp_msg_write_long(&buf, &buflen, fs.f_namemax);
 
   resp = fxp_packet_create(fxp->pool, fxp->channel_id);
   resp->payload = ptr;
@@ -4787,7 +4736,7 @@
   product_version = sftp_msg_read_string(fxp->pool, &fxp->payload,
     &fxp->payload_sz);
 
-  build_number = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+  build_number = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
 
   if (fxp_session->client_version >= fxp_utf8_protocol_version) {
     vendor_name = sftp_utf8_decode_str(fxp->pool, vendor_name);
@@ -5304,8 +5253,8 @@
     path = sftp_msg_read_string(fxp->pool, &fxp->payload, &fxp->payload_sz);
     digest_list = sftp_msg_read_string(fxp->pool, &fxp->payload,
       &fxp->payload_sz);
-    offset = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
-    len = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+    offset = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+    len = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
     blocksz = sftp_msg_read_int(fxp->pool, &fxp->payload, &fxp->payload_sz);
 
     res = fxp_handle_ext_check_file(fxp, digest_list, path, offset, len,
@@ -5373,8 +5322,8 @@
 
     digest_list = sftp_msg_read_string(fxp->pool, &fxp->payload,
       &fxp->payload_sz);
-    offset = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
-    len = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+    offset = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+    len = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
     blocksz = sftp_msg_read_int(fxp->pool, &fxp->payload, &fxp->payload_sz);
 
     res = fxp_handle_ext_check_file(fxp, digest_list, path, offset, len,
@@ -6165,8 +6114,8 @@
   cmd_rec *cmd;
   
   name = sftp_msg_read_string(fxp->pool, &fxp->payload, &fxp->payload_sz);
-  offset = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
-  lock_len = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+  offset = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+  lock_len = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
   lock_flags = sftp_msg_read_int(fxp->pool, &fxp->payload, &fxp->payload_sz);
 
   cmd = fxp_cmd_alloc(fxp->pool, "LOCK", name);
@@ -7743,7 +7692,7 @@
   cmd_rec *cmd, *cmd2;
 
   name = sftp_msg_read_string(fxp->pool, &fxp->payload, &fxp->payload_sz);
-  offset = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+  offset = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
   datalen = sftp_msg_read_int(fxp->pool, &fxp->payload, &fxp->payload_sz);
 
 #if 0
@@ -10300,7 +10249,7 @@
   cmd_rec *cmd, *cmd2;
 
   name = sftp_msg_read_string(fxp->pool, &fxp->payload, &fxp->payload_sz);
-  offset = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+  offset = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
   datalen = sftp_msg_read_int(fxp->pool, &fxp->payload, &fxp->payload_sz);
   data = sftp_msg_read_data(fxp->pool, &fxp->payload, &fxp->payload_sz,
     datalen);
@@ -10650,8 +10599,8 @@
   cmd_rec *cmd;
   
   name = sftp_msg_read_string(fxp->pool, &fxp->payload, &fxp->payload_sz);
-  offset = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
-  lock_len = fxp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+  offset = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
+  lock_len = sftp_msg_read_long(fxp->pool, &fxp->payload, &fxp->payload_sz);
   lock_flags = sftp_msg_read_int(fxp->pool, &fxp->payload, &fxp->payload_sz);
 
   cmd = fxp_cmd_alloc(fxp->pool, "UNLOCK", name);

Index: mod_sftp.c
===================================================================
RCS file: /cvsroot/proftp/proftpd/contrib/mod_sftp/mod_sftp.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -d -r1.74 -r1.75
--- mod_sftp.c	14 Mar 2013 21:49:19 -0000	1.74
+++ mod_sftp.c	28 Mar 2013 18:48:31 -0000	1.75
@@ -1421,6 +1421,7 @@
     sftp_interop_free();
     sftp_keystore_free();
     sftp_keys_free();
+    sftp_mac_free();
     pr_response_block(FALSE);
     sftp_utf8_free();
 
@@ -1473,6 +1474,7 @@
   sftp_interop_free();
   sftp_keystore_free();
   sftp_keys_free();
+  sftp_mac_free();
   sftp_utf8_free();
 
   /* Clean up the OpenSSL stuff. */
@@ -1578,6 +1580,7 @@
   pr_log_debug(DEBUG2, MOD_SFTP_VERSION ": using " OPENSSL_VERSION_TEXT);
 
   sftp_keystore_init();
+  sftp_mac_init();
 
   pr_event_register(&sftp_module, "mod_ban.ban-class", sftp_ban_class_ev, NULL);
   pr_event_register(&sftp_module, "mod_ban.ban-host", sftp_ban_host_ev, NULL);

--- NEW FILE: umac.c ---
/* -----------------------------------------------------------------------
 * 
 * umac.c -- C Implementation UMAC Message Authentication
 *
 * Version 0.93b of rfc4418.txt -- 2006 July 18
 *
 * For a full description of UMAC message authentication see the UMAC
 * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac
 * Please report bugs and suggestions to the UMAC webpage.
 *
 * Copyright (c) 1999-2006 Ted Krovetz
 *                                                                 
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and with or without fee, is hereby
 * granted provided that the above copyright notice appears in all copies
 * and in supporting documentation, and that the name of the copyright
 * holder not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 *
[...1247 lines suppressed...]
/* ---------------------------------------------------------------------- */

#if 0
int umac(struct umac_ctx *ctx, unsigned char *input, 
         long len, unsigned char tag[],
         unsigned char nonce[8])
/* All-in-one version simply calls umac_update() and umac_final().        */
{
    uhash(&ctx->hash, input, len, (unsigned char *)tag);
    pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag);
    
    return (1);
}
#endif

/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ----- End UMAC Section ----------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */

--- NEW FILE: umac.h ---
/* -----------------------------------------------------------------------
 * 
 * umac.h -- C Implementation UMAC Message Authentication
 *
 * Version 0.93a of rfc4418.txt -- 2006 July 14
 *
 * For a full description of UMAC message authentication see the UMAC
 * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac
 * Please report bugs and suggestions to the UMAC webpage.
 *
 * Copyright (c) 1999-2004 Ted Krovetz
 *                                                                 
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and with or without fee, is hereby
 * granted provided that the above copyright notice appears in all copies
 * and in supporting documentation, and that the name of the copyright
 * holder not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 *
 * Comments should be directed to Ted Krovetz (tdk@acm.org)
 *                                                                   
 * ---------------------------------------------------------------------- */
 
 /* ////////////////////// IMPORTANT NOTES /////////////////////////////////
  *
  * 1) This version does not work properly on messages larger than 16MB
  *
  * 2) If you set the switch to use SSE2, then all data must be 16-byte
  *    aligned
  *
  * 3) When calling the function umac(), it is assumed that msg is in
  * a writable buffer of length divisible by 32 bytes. The message itself
  * does not have to fill the entire buffer, but bytes beyond msg may be
  * zeroed.
  *
  * 4) Two free AES implementations are supported by this implementation of
  * UMAC. Paulo Barreto's version is in the public domain and can be found
  * at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for
  * "Barreto"). The only two files needed are rijndael-alg-fst.c and
  * rijndael-alg-fst.h.
  * Brian Gladman's version is distributed with GNU Public lisence
  * and can be found at http://fp.gladman.plus.com/AES/index.htm. It
  * includes a fast IA-32 assembly version.
  *
  /////////////////////////////////////////////////////////////////////// */
#ifndef HEADER_UMAC_H
#define HEADER_UMAC_H

#ifdef __cplusplus
    extern "C" {
#endif

size_t umac_ctx_size(void);
/* Returns size of umac_ctx struct. */

struct umac_ctx *umac_alloc(void);
/* Dynamically allocate a umac_ctx struct. */

struct umac_ctx *umac_new(unsigned char key[]);
/* Dynamically allocate a umac_ctx struct, initialize variables, 
 * generate subkeys from key.
 */

void umac_init(struct umac_ctx *ctx, unsigned char key[]);
/* Initialize a previously allocated umac_ctx struct. */

int umac_reset(struct umac_ctx *ctx);
/* Reset a umac_ctx to begin authenicating a new message */

int umac_update(struct umac_ctx *ctx, unsigned char *input, long len);
/* Incorporate len bytes pointed to by input into context ctx */

int umac_final(struct umac_ctx *ctx, unsigned char tag[], unsigned char nonce[8]);
/* Incorporate any pending data and the ctr value, and return tag. 
 * This function returns error code if ctr < 0. 
 */

int umac_delete(struct umac_ctx *ctx);
/* Deallocate the context structure */

#if 0
int umac(struct umac_ctx *ctx, unsigned char *input, 
         long len, unsigned char tag[],
         unsigned char nonce[8]);
/* All-in-one implementation of the functions Reset, Update and Final */
#endif

/* uhash.h */


#if 0
typedef struct uhash_ctx *uhash_ctx_t;
  /* The uhash_ctx structure is defined by the implementation of the    */
  /* UHASH functions.                                                   */
 
uhash_ctx_t uhash_alloc(unsigned char key[16]);
  /* Dynamically allocate a uhash_ctx struct and generate subkeys using */
  /* the kdf and kdf_key passed in. If kdf_key_len is 0 then RC6 is     */
  /* used to generate key with a fixed key. If kdf_key_len > 0 but kdf  */
  /* is NULL then the first 16 bytes pointed at by kdf_key is used as a */
  /* key for an RC6 based KDF.                                          */
  
int uhash_free(uhash_ctx_t ctx);

int uhash_set_params(uhash_ctx_t ctx,
                   void       *params);

int uhash_reset(uhash_ctx_t ctx);

int uhash_update(uhash_ctx_t ctx,
               unsigned char       *input,
               long        len);

int uhash_final(uhash_ctx_t ctx,
              unsigned char        ouput[]);

int uhash(uhash_ctx_t ctx,
        unsigned char       *input,
        long        len,
        unsigned char        output[]);
#endif

#ifdef __cplusplus
    }
#endif

#endif /* HEADER_UMAC_H */

Index: mac.h
===================================================================
RCS file: /cvsroot/proftp/proftpd/contrib/mod_sftp/mac.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- mac.h	23 May 2011 20:40:13 -0000	1.3
+++ mac.h	28 Mar 2013 18:48:31 -0000	1.4
@@ -31,6 +31,9 @@
 
 #include "packet.h"
 
+int sftp_mac_init(void);
+int sftp_mac_free(void);
+
 /* Returns the block size of the negotiated MAC algorithm, or 0 if no MAC
  * has been negotiated yet.
  */


------------------------------------------------------------------------------
Own the Future-Intel&reg; Level Up Game Demo Contest 2013
Rise to greatness in Intel's independent game demo contest.
Compete for recognition, cash, and the chance to get your game 
on Steam. $5K grand prize plus 10 genre and skill prizes. 
Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d
_______________________________________________
ProFTPD Committers Mailing List
proftpd-committers@proftpd.org
https://lists.sourceforge.net/lists/listinfo/proftp-committers
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic