/* 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
};
-/* 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);
{ "host_data", vtype_stringptr, &host_data },
{ "host_lookup_deferred",vtype_int, &host_lookup_deferred },
{ "host_lookup_failed", vtype_int, &host_lookup_failed },
+ { "host_port", vtype_int, &deliver_host_port },
{ "inode", vtype_ino, &deliver_inode },
{ "interface_address", vtype_stringptr, &interface_address },
{ "interface_port", vtype_int, &interface_port },
{ "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_certificate_verified", vtype_int,&tls_out.certificate_verified },
{ "tls_out_cipher", vtype_stringptr, &tls_out.cipher },
+#ifdef EXPERIMENTAL_DANE
+ { "tls_out_dane", vtype_bool, &tls_out.dane_verified },
+#endif
{ "tls_out_ocsp", vtype_int, &tls_out.ocsp },
{ "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
+#ifdef EXPERIMENTAL_DANE
+ { "tls_out_tlsa_usage", vtype_int, &tls_out.tlsa_usage },
+#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
{ "tod_zone", vtype_todzone, NULL },
{ "tod_zulu", vtype_todzulu, NULL },
#ifdef EXPERIMENTAL_TPDA
+ { "tpda_data", vtype_stringptr, &tpda_data },
+
+ /*XXX want to use generic vars for as many of these as possible*/
{ "tpda_defer_errno", vtype_int, &tpda_defer_errno },
- { "tpda_defer_errstr", vtype_stringptr, &tpda_defer_errstr },
- { "tpda_delivery_confirmation", vtype_stringptr, &tpda_delivery_confirmation },
- { "tpda_delivery_domain", vtype_stringptr, &tpda_delivery_domain },
- { "tpda_delivery_fqdn", vtype_stringptr, &tpda_delivery_fqdn },
- { "tpda_delivery_ip", vtype_stringptr, &tpda_delivery_ip },
- { "tpda_delivery_local_part",vtype_stringptr,&tpda_delivery_local_part },
- { "tpda_delivery_port", vtype_int, &tpda_delivery_port },
+
+ { "tpda_event", vtype_stringptr, &tpda_event },
#endif
{ "transport_name", vtype_stringptr, &transport_name },
{ "value", vtype_stringptr, &lookup_value },
#ifdef HAVE_ARC4RANDOM
/* cryptographically strong randomness, common on *BSD platforms, not
so much elsewhere. Alas. */
+#ifndef NOT_HAVE_ARC4RANDOM_STIR
arc4random_stir();
+#endif
#elif defined(HAVE_SRANDOM) || defined(HAVE_SRANDOMDEV)
#ifdef HAVE_SRANDOMDEV
/* uses random(4) for seeding */
#endif
}
+
+return NULL; /* Unknown variable. Silences static checkers. */
}
}
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. */
if (vp && *(void **)vp->value)
{
uschar * cp = tls_cert_fprt_sha256(*(void **)vp->value);
- yield = string_cat(yield, &size, &ptr, cp, (int)strlen(cp));
+ yield = string_cat(yield, &size, &ptr, cp, (int)Ustrlen(cp));
}
else
#endif
case EOP_UTF8CLEAN:
{
- int seq_len, index = 0;
+ int seq_len = 0, index = 0;
int bytes_left = 0;
+ long codepoint = -1;
uschar seq_buff[4]; /* accumulate utf-8 here */
while (*sub != 0)
{
- int complete;
- long codepoint;
- uschar c;
+ int complete = 0;
+ uschar c = *sub++;
- complete = 0;
- c = *sub++;
if (bytes_left)
{
if ((c & 0xc0) != 0x80)
if (--bytes_left == 0) /* codepoint complete */
{
if(codepoint > 0x10FFFF) /* is it too large? */
- complete = -1; /* error */
+ complete = -1; /* error (RFC3629 limit) */
else
{ /* finished; output utf-8 sequence */
yield = string_cat(yield, &size, &ptr, seq_buff, seq_len);
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;