Use Ustrlen() on a uschar
[exim.git] / src / src / expand.c
index 127134dbc389b3d4aaaa6bd16ff3ae2bd0017879..88a5ee399db9c15c2a94cd95aae6f364afab3249 100644 (file)
@@ -205,6 +205,7 @@ static uschar *op_table_main[] = {
   US"rxquote",
   US"s",
   US"sha1",
+  US"sha256",
   US"stat",
   US"str2b64",
   US"strlen",
@@ -242,6 +243,7 @@ enum {
   EOP_RXQUOTE,
   EOP_S,
   EOP_SHA1,
+  EOP_SHA256,
   EOP_STAT,
   EOP_STR2B64,
   EOP_STRLEN,
@@ -346,25 +348,9 @@ enum {
 };
 
 
-/* Type for main variable table */
-
-typedef struct {
-  const char *name;
-  int         type;
-  void       *value;
-} var_entry;
-
-/* Type for entries pointing to address/length pairs. Not currently
-in use. */
-
-typedef struct {
-  uschar **address;
-  int  *length;
-} alblock;
-
 /* Types of table entry */
 
-enum {
+enum vtypes {
   vtype_int,            /* value is address of int */
   vtype_filter_int,     /* ditto, but recognized only when filtering */
   vtype_ino,            /* value is address of ino_t (not always an int) */
@@ -397,7 +383,23 @@ enum {
   #ifndef DISABLE_DKIM
   ,vtype_dkim           /* Lookup of value in DKIM signature */
   #endif
-  };
+};
+
+/* Type for main variable table */
+
+typedef struct {
+  const char *name;
+  enum vtypes type;
+  void       *value;
+} var_entry;
+
+/* Type for entries pointing to address/length pairs. Not currently
+in use. */
+
+typedef struct {
+  uschar **address;
+  int  *length;
+} alblock;
 
 static uschar * fn_recipients(void);
 
@@ -675,7 +677,7 @@ static var_entry var_table[] = {
   { "tls_in_ourcert",      vtype_cert,        &tls_in.ourcert },
   { "tls_in_peercert",     vtype_cert,        &tls_in.peercert },
   { "tls_in_peerdn",       vtype_stringptr,   &tls_in.peerdn },
-#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
+#if defined(SUPPORT_TLS)
   { "tls_in_sni",          vtype_stringptr,   &tls_in.sni },
 #endif
   { "tls_out_bits",        vtype_int,         &tls_out.bits },
@@ -685,12 +687,12 @@ static var_entry var_table[] = {
   { "tls_out_ourcert",     vtype_cert,        &tls_out.ourcert },
   { "tls_out_peercert",    vtype_cert,        &tls_out.peercert },
   { "tls_out_peerdn",      vtype_stringptr,   &tls_out.peerdn },
-#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
+#if defined(SUPPORT_TLS)
   { "tls_out_sni",         vtype_stringptr,   &tls_out.sni },
 #endif
 
   { "tls_peerdn",          vtype_stringptr,   &tls_in.peerdn },        /* mind the alphabetical order! */
-#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
+#if defined(SUPPORT_TLS)
   { "tls_sni",             vtype_stringptr,   &tls_in.sni },   /* mind the alphabetical order! */
 #endif
 
@@ -4665,6 +4667,9 @@ while (*s != 0)
 
         DEBUG(D_expand) debug_printf("connected to socket %s\n", sub_arg[0]);
 
+       /* Allow sequencing of test actions */
+       if (running_in_test_harness) millisleep(100);
+
         /* Write the request string, if not empty */
 
         if (sub_arg[1][0] != 0)
@@ -4688,6 +4693,8 @@ while (*s != 0)
         shutdown(fd, SHUT_WR);
         #endif
 
+       if (running_in_test_harness) millisleep(100);
+
         /* Now we need to read from the socket, under a timeout. The function
         that reads a file can be used. */
 
@@ -5745,8 +5752,9 @@ while (*s != 0)
     switch(c)
       {
 #ifdef SUPPORT_TLS
-      case EOP_SHA1:
       case EOP_MD5:
+      case EOP_SHA1:
+      case EOP_SHA256:
        if (s[1] == '$')
          {
          uschar * s1 = s;
@@ -5759,6 +5767,7 @@ while (*s != 0)
            s = s1+1;
            break;
            }
+         vp = NULL;
          }
         /*FALLTHROUGH*/
 #endif
@@ -5894,6 +5903,18 @@ while (*s != 0)
          }
         continue;
 
+      case EOP_SHA256:
+#ifdef SUPPORT_TLS
+       if (vp && *(void **)vp->value)
+         {
+         uschar * cp = tls_cert_fprt_sha256(*(void **)vp->value);
+         yield = string_cat(yield, &size, &ptr, cp, (int)Ustrlen(cp));
+         }
+       else
+#endif
+         expand_string_message = US"sha256 only supported for certificates";
+        continue;
+
       /* Convert hex encoding to base64 encoding */
 
       case EOP_HEX2B64: