/* Recursively called function */
static uschar *expand_string_internal(uschar *, BOOL, uschar **, BOOL, BOOL, BOOL *);
+static int_eximarith_t expanded_string_integer(uschar *, BOOL);
#ifdef STAND_ALONE
#ifndef SUPPORT_CRYPTEQ
US"rxquote",
US"s",
US"sha1",
+ US"sha256",
US"stat",
US"str2b64",
US"strlen",
EOP_RXQUOTE,
EOP_S,
EOP_SHA1,
+ EOP_SHA256,
EOP_STAT,
EOP_STR2B64,
EOP_STRLEN,
};
-/* 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) */
#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);
{ "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 },
{ "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
}
else
{
- num[i] = expand_string_integer(sub[i], FALSE);
+ num[i] = expanded_string_integer(sub[i], FALSE);
if (expand_string_message != NULL) return NULL;
}
}
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)
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. */
#ifdef SUPPORT_TLS
case EITEM_CERTEXTRACT:
{
- int i;
- int field_number = 1;
uschar *save_lookup_value = lookup_value;
uschar *sub[2];
int save_expand_nmax =
/* strip spaces fore & aft */
{
int len;
- int x = 0;
uschar *p = sub[0];
while (isspace(*p)) p++;
int c;
uschar *arg = NULL;
uschar *sub;
- var_entry *vp;
+ var_entry *vp = NULL;
/* Owing to an historical mis-design, an underscore may be part of the
operator name, or it may introduce arguments. We therefore first scan the
as we do not want to do the usual expansion. For most, expand the string.*/
switch(c)
{
- case EOP_SHA1:
+#ifdef SUPPORT_TLS
case EOP_MD5:
+ case EOP_SHA1:
+ case EOP_SHA256:
if (s[1] == '$')
{
uschar * s1 = s;
s = s1+1;
break;
}
+ vp = NULL;
}
- vp = NULL;
/*FALLTHROUGH*/
+#endif
default:
sub = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
if (!sub) goto EXPAND_FAILED;
}
case EOP_MD5:
+#ifdef SUPPORT_TLS
if (vp && *(void **)vp->value)
{
uschar * cp = tls_cert_fprt_md5(*(void **)vp->value);
- yield = string_cat(yield, &size, &ptr, cp, (int)strlen(cp));
+ yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
}
else
+#endif
{
md5 base;
uschar digest[16];
continue;
case EOP_SHA1:
+#ifdef SUPPORT_TLS
if (vp && *(void **)vp->value)
{
uschar * cp = tls_cert_fprt_sha1(*(void **)vp->value);
- yield = string_cat(yield, &size, &ptr, cp, (int)strlen(cp));
+ yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
}
else
+#endif
{
sha1 base;
uschar digest[20];
}
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:
case EOP_UTF8CLEAN:
{
int seq_len, index = 0;
- int bytes_left = 0;
+ int bytes_left = 0;
uschar seq_buff[4]; /* accumulate utf-8 here */
while (*sub != 0)
complete = 0;
c = *sub++;
- if(bytes_left)
+ if (bytes_left)
{
if ((c & 0xc0) != 0x80)
{
int_eximarith_t max;
uschar *s;
- max = expand_string_integer(sub, TRUE);
+ max = expanded_string_integer(sub, TRUE);
if (expand_string_message != NULL)
goto EXPAND_FAILED;
s = string_sprintf("%d", vaguely_random_number((int)max));
int_eximarith_t
expand_string_integer(uschar *string, BOOL isplus)
{
+return expanded_string_integer(expand_string(string), isplus);
+}
+
+
+/*************************************************
+ * Interpret string as an integer *
+ *************************************************/
+
+/* Convert a string (that has already been expanded) into an integer.
+
+This function is used inside the expansion code.
+
+Arguments:
+ s the string to be expanded
+ isplus TRUE if a non-negative number is expected
+
+Returns: the integer value, or
+ -1 if string is NULL (which implies an expansion error)
+ -2 for an integer interpretation error
+ expand_string_message is set NULL for an OK integer
+*/
+
+static int_eximarith_t
+expanded_string_integer(uschar *s, BOOL isplus)
+{
int_eximarith_t value;
-uschar *s = expand_string(string);
uschar *msg = US"invalid integer \"%s\"";
uschar *endptr;