X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fexpand.c;h=ba2c6f7cdc61fdb6de6de9b43ff1db5878f1438b;hb=594706ea2e56fe8c972eab772bd3e58c7a0c89ab;hp=9532d9d3364f2987e9bfaf6ce816932307138df3;hpb=6a8a60e0f273b61a24a48afd3217ff84106779bd;p=exim.git diff --git a/src/src/expand.c b/src/src/expand.c index 9532d9d33..ba2c6f7cd 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -14,6 +14,7 @@ /* 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 @@ -205,6 +206,7 @@ static uschar *op_table_main[] = { US"rxquote", US"s", US"sha1", + US"sha256", US"stat", US"str2b64", US"strlen", @@ -242,6 +244,7 @@ enum { EOP_RXQUOTE, EOP_S, EOP_SHA1, + EOP_SHA256, EOP_STAT, EOP_STR2B64, EOP_STRLEN, @@ -346,25 +349,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 +384,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,22 +678,28 @@ 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 }, { "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 @@ -1876,6 +1885,8 @@ switch (vp->type) #endif } + +return NULL; /* Unknown variable. Silences static checkers. */ } @@ -2443,7 +2454,7 @@ switch(cond_type) } else { - num[i] = expand_string_integer(sub[i], FALSE); + num[i] = expanded_string_integer(sub[i], FALSE); if (expand_string_message != NULL) return NULL; } } @@ -4665,6 +4676,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 +4702,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. */ @@ -5365,8 +5381,6 @@ while (*s != 0) #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 = @@ -5382,7 +5396,6 @@ while (*s != 0) /* strip spaces fore & aft */ { int len; - int x = 0; uschar *p = sub[0]; while (isspace(*p)) p++; @@ -5725,7 +5738,7 @@ while (*s != 0) 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 @@ -5747,8 +5760,10 @@ while (*s != 0) 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; @@ -5761,9 +5776,10 @@ while (*s != 0) 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; @@ -5855,12 +5871,14 @@ while (*s != 0) } 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]; @@ -5874,12 +5892,14 @@ while (*s != 0) 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]; @@ -5892,6 +5912,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: @@ -6342,19 +6374,19 @@ while (*s != 0) case EOP_UTF8CLEAN: { - int seq_len, index = 0; - int bytes_left = 0; + int seq_len = 0, index = 0; + int bytes_left = 0; uschar seq_buff[4]; /* accumulate utf-8 here */ while (*sub != 0) { int complete; - long codepoint; + long codepoint = 0; uschar c; complete = 0; c = *sub++; - if(bytes_left) + if (bytes_left) { if ((c & 0xc0) != 0x80) { @@ -6656,7 +6688,7 @@ while (*s != 0) 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)); @@ -6856,8 +6888,32 @@ Returns: the integer value, or 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;