static int
find_control(const uschar * name, control_def * ol, int last)
{
-int first = 0;
-while (last > first)
+for (int first = 0; last > first; )
{
int middle = (first + last)/2;
uschar * s = ol[middle].name;
static int
acl_checkcondition(uschar * name, condition_def * list, int end)
{
-int start = 0;
-while (start < end)
+for (int start = 0; start < end; )
{
int mid = (start + end)/2;
int c = Ustrcmp(name, list[mid].name);
static int
acl_checkname(uschar *name, uschar **list, int end)
{
-int start = 0;
-
-while (start < end)
+for (int start = 0; start < end; )
{
int mid = (start + end)/2;
int c = Ustrcmp(name, list[mid]);
acl_block *this = NULL;
acl_condition_block *cond;
acl_condition_block **condp = NULL;
-uschar *s;
+uschar * s;
*error = NULL;
fn_hdrs_added(void)
{
gstring * g = NULL;
-header_line * h;
-for (h = acl_added_headers; h; h = h->next)
+for (header_line * h = acl_added_headers; h; h = h->next)
{
int i = h->slen;
if (h->text[i-1] == '\n') i--;
/* Search previously logged warnings. They are kept in malloc
store so they can be freed at the start of a new message. */
- for (logged = acl_warn_logged; logged != NULL; logged = logged->next)
+ for (logged = acl_warn_logged; logged; logged = logged->next)
if (Ustrcmp(logged->text, text) == 0) break;
- if (logged == NULL)
+ if (!logged)
{
int length = Ustrlen(text) + 1;
log_write(0, LOG_MAIN, "%s", text);
/* If there's no user message, we are done. */
-if (user_message == NULL) return;
+if (!user_message) return;
/* If this isn't a message ACL, we can't do anything with a user message.
Log an error. */
if ((rc = host_name_lookup()) != OK)
{
- *log_msgptr = (rc == DEFER)?
- US"host lookup deferred for reverse lookup check"
- :
- string_sprintf("host lookup failed for reverse lookup check%s",
- host_lookup_msg);
+ *log_msgptr = rc == DEFER
+ ? US"host lookup deferred for reverse lookup check"
+ : string_sprintf("host lookup failed for reverse lookup check%s",
+ host_lookup_msg);
return rc; /* DEFER or FAIL */
}
acl_verify_csa_address(dns_answer *dnsa, dns_scan *dnss, int reset,
uschar *target)
{
-dns_record *rr;
-dns_address *da;
-
-BOOL target_found = FALSE;
+int rc = CSA_FAIL_NOADDR;
-for (rr = dns_next_rr(dnsa, dnss, reset);
- rr != NULL;
+for (dns_record * rr = dns_next_rr(dnsa, dnss, reset);
+ rr;
rr = dns_next_rr(dnsa, dnss, RESET_NEXT))
{
/* Check this is an address RR for the target hostname. */
if (strcmpic(target, rr->name) != 0) continue;
- target_found = TRUE;
+ rc = CSA_FAIL_MISMATCH;
/* Turn the target address RR into a list of textual IP addresses and scan
the list. There may be more than one if it is an A6 RR. */
- for (da = dns_address_from_rr(dnsa, rr); da != NULL; da = da->next)
+ for (dns_address * da = dns_address_from_rr(dnsa, rr); da; da = da->next)
{
/* If the client IP address matches the target IP address, it's good! */
using an unauthorized IP address, otherwise the target has no authorized IP
addresses. */
-if (target_found) return CSA_FAIL_MISMATCH;
-else return CSA_FAIL_NOADDR;
+return rc;
}
/* If we didn't break the loop then no appropriate records were found. */
-if (rr == NULL) return t->data.val = CSA_UNKNOWN;
+if (!rr) return t->data.val = CSA_UNKNOWN;
/* Do not check addresses if the target is ".", in accordance with RFC 2782.
A target of "." indicates there are no valid addresses, so the client cannot
/* Handle name/address consistency verification in a separate function. */
-for (vp= verify_type_list;
+for (vp = verify_type_list;
CS vp < CS verify_type_list + sizeof(verify_type_list);
vp++
)
/* Remaining items are optional; they apply to sender and recipient
verification, including "header sender" verification. */
-while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
- != NULL)
+while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
{
if (strcmpic(ss, US"defer_ok") == 0) defer_ok = TRUE;
else if (strcmpic(ss, US"no_details") == 0) no_details = TRUE;
{
const uschar * sublist = ss;
int optsep = ',';
- uschar *opt;
uschar buffer[256];
- while (isspace(*sublist)) sublist++;
+ uschar * opt;
+ while (isspace(*sublist)) sublist++;
while ((opt = string_nextinlist(&sublist, &optsep, buffer, sizeof(buffer))))
{
callout_opt_t * op;
if (*p == '/')
{
const uschar *pp = p + 1;
- while (*pp != 0) pp++;
+ while (*pp) pp++;
fake_response_text = expand_string(string_copyn(p+1, pp-p-1));
p = pp;
}
else if (Ustrncmp(p, "/domain=", 8) == 0)
{
const uschar *pp = p + 8;
- while (*pp != 0 && *pp != '/') pp++;
+ while (*pp && *pp != '/') pp++;
submission_domain = string_copyn(p+8, pp-p-8);
p = pp;
}
else if (Ustrncmp(p, "/name=", 6) == 0)
{
const uschar *pp = p + 6;
- while (*pp != 0) pp++;
+ while (*pp) pp++;
submission_name = string_copy(parse_fix_phrase(p+6, pp-p-6,
big_buffer, big_buffer_size));
p = pp;
int logbits = 0;
int sep = 0;
const uschar *s = arg;
- uschar *ss;
+ uschar * ss;
while ((ss = string_nextinlist(&s, &sep, big_buffer, big_buffer_size)))
{
if (Ustrcmp(ss, "main") == 0) logbits |= LOG_MAIN;
{
/* Separate the regular expression and any optional parameters. */
const uschar * list = arg;
- uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
- uschar *opt;
+ uschar * ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
+ uschar * opt;
BOOL defer_ok = FALSE;
int timeout = 0;
if (*acl_text == 0) return NULL; /* No more data */
yield = acl_text; /* Potential data line */
- while (*acl_text != 0 && *acl_text != '\n') acl_text++;
+ while (*acl_text && *acl_text != '\n') acl_text++;
/* If we hit the end before a newline, we have the whole logical line. If
it's a comment, there's no more data to be given. Otherwise, yield it. */
in the ACL tree, having read it into the POOL_PERM store pool so that it
persists between multiple messages. */
-if (acl == NULL)
+if (!acl)
{
int old_pool = store_pool;
if (fd >= 0) store_pool = POOL_PERM;
acl = acl_read(acl_getline, log_msgptr);
store_pool = old_pool;
- if (acl == NULL && *log_msgptr != NULL) return ERROR;
+ if (!acl && *log_msgptr) return ERROR;
if (fd >= 0)
{
tree_node *t = store_get_perm(sizeof(tree_node) + Ustrlen(ss));
/* Now we have an ACL to use. It's possible it may be NULL. */
-while (acl != NULL)
+while (acl)
{
int cond;
int basic_errno = 0;
/* macros for reading / writing arrays */
# define SMBMACRO(macro,buf,pos,val,len,size) \
-{ int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
+{ for (int l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
# define SSMBMACRO(macro,buf,pos,val,len,size) \
-{ int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
+{ for (int l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
/* reads multiple data from an SMB buffer */
# define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1)
DEBUG_X(5,("%s%04x %s: ", \
tab_depth(depth), base,string)); \
if (charmode) print_asc(5, US (outbuf), (len)); else \
- { int idx; for (idx = 0; idx < len; idx++) { DEBUG_X(5,("%02x ", (outbuf)[idx])); } } \
+ for (int idx = 0; idx < len; idx++) { DEBUG_X(5,("%02x ", (outbuf)[idx])); } \
DEBUG_X(5,("\n")); }
# define DBG_RW_PSVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
DEBUG_X(5,("%s%04x %s: ", \
tab_depth(depth), base,string)); \
if (charmode) print_asc(5, US (outbuf), 2*(len)); else \
- { int idx; for (idx = 0; idx < len; idx++) { DEBUG_X(5,("%04x ", (outbuf)[idx])); } } \
+ for (int idx = 0; idx < len; idx++) { DEBUG_X(5,("%04x ", (outbuf)[idx])); } \
DEBUG_X(5,("\n")); }
# define DBG_RW_PIVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
DEBUG_X(5,("%s%04x %s: ", \
tab_depth(depth), base,string)); \
if (charmode) print_asc(5, US (outbuf), 4*(len)); else \
- { int idx; for (idx = 0; idx < len; idx++) { DEBUG_X(5,("%08x ", (outbuf)[idx])); } } \
+ for (int idx = 0; idx < len; idx++) { DEBUG_X(5,("%08x ", (outbuf)[idx])); } \
DEBUG_X(5,("\n")); }
# define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \
static void
permute (char *out, char *in, uschar * p, int n)
{
- int i;
- for (i = 0; i < n; i++)
- out[i] = in[p[i] - 1];
+for (int i = 0; i < n; i++)
+ out[i] = in[p[i] - 1];
}
static void
lshift (char *d, int count, int n)
{
- char out[64];
- int i;
- for (i = 0; i < n; i++)
- out[i] = d[(i + count) % n];
- for (i = 0; i < n; i++)
- d[i] = out[i];
+char out[64];
+for (int i = 0; i < n; i++)
+ out[i] = d[(i + count) % n];
+for (int i = 0; i < n; i++)
+ d[i] = out[i];
}
static void
concat (char *out, char *in1, char *in2, int l1, int l2)
{
- while (l1--)
- *out++ = *in1++;
- while (l2--)
- *out++ = *in2++;
+while (l1--)
+ *out++ = *in1++;
+while (l2--)
+ *out++ = *in2++;
}
static void
xor (char *out, char *in1, char *in2, int n)
{
- int i;
- for (i = 0; i < n; i++)
- out[i] = in1[i] ^ in2[i];
+for (int i = 0; i < n; i++)
+ out[i] = in1[i] ^ in2[i];
}
static void
dohash (char *out, char *in, char *key, int forw)
{
- int i, j, k;
- char pk1[56];
- char c[28];
- char d[28];
- char cd[56];
- char ki[16][48];
- char pd1[64];
- char l[32], r[32];
- char rl[64];
-
- permute (pk1, key, perm1, 56);
-
- for (i = 0; i < 28; i++)
- c[i] = pk1[i];
- for (i = 0; i < 28; i++)
- d[i] = pk1[i + 28];
-
- for (i = 0; i < 16; i++)
- {
- lshift (c, sc[i], 28);
- lshift (d, sc[i], 28);
-
- concat (cd, c, d, 28, 28);
- permute (ki[i], cd, perm2, 48);
- }
+int i, j, k;
+char pk1[56];
+char c[28];
+char d[28];
+char cd[56];
+char ki[16][48];
+char pd1[64];
+char l[32], r[32];
+char rl[64];
+
+permute (pk1, key, perm1, 56);
+
+for (i = 0; i < 28; i++)
+ c[i] = pk1[i];
+for (i = 0; i < 28; i++)
+ d[i] = pk1[i + 28];
+
+for (i = 0; i < 16; i++)
+ {
+ lshift (c, sc[i], 28);
+ lshift (d, sc[i], 28);
+
+ concat (cd, c, d, 28, 28);
+ permute (ki[i], cd, perm2, 48);
+ }
- permute (pd1, in, perm3, 64);
+permute (pd1, in, perm3, 64);
- for (j = 0; j < 32; j++)
- {
- l[j] = pd1[j];
- r[j] = pd1[j + 32];
- }
+for (j = 0; j < 32; j++)
+ {
+ l[j] = pd1[j];
+ r[j] = pd1[j + 32];
+ }
- for (i = 0; i < 16; i++)
- {
- char er[48];
- char erk[48];
- char b[8][6];
- char cb[32];
- char pcb[32];
- char r2[32];
+for (i = 0; i < 16; i++)
+ {
+ char er[48];
+ char erk[48];
+ char b[8][6];
+ char cb[32];
+ char pcb[32];
+ char r2[32];
- permute (er, r, perm4, 48);
+ permute (er, r, perm4, 48);
- xor (erk, er, ki[forw ? i : 15 - i], 48);
+ xor (erk, er, ki[forw ? i : 15 - i], 48);
- for (j = 0; j < 8; j++)
- for (k = 0; k < 6; k++)
- b[j][k] = erk[j * 6 + k];
+ for (j = 0; j < 8; j++)
+ for (k = 0; k < 6; k++)
+ b[j][k] = erk[j * 6 + k];
- for (j = 0; j < 8; j++)
- {
- int m, n;
- m = (b[j][0] << 1) | b[j][5];
+ for (j = 0; j < 8; j++)
+ {
+ int m, n;
+ m = (b[j][0] << 1) | b[j][5];
- n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] << 1) | b[j][4];
+ n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] << 1) | b[j][4];
- for (k = 0; k < 4; k++)
- b[j][k] = (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
- }
+ for (k = 0; k < 4; k++)
+ b[j][k] = (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
+ }
- for (j = 0; j < 8; j++)
- for (k = 0; k < 4; k++)
- cb[j * 4 + k] = b[j][k];
- permute (pcb, cb, perm5, 32);
+ for (j = 0; j < 8; j++)
+ for (k = 0; k < 4; k++)
+ cb[j * 4 + k] = b[j][k];
+ permute (pcb, cb, perm5, 32);
- xor (r2, l, pcb, 32);
+ xor (r2, l, pcb, 32);
- for (j = 0; j < 32; j++)
- l[j] = r[j];
+ for (j = 0; j < 32; j++)
+ l[j] = r[j];
- for (j = 0; j < 32; j++)
- r[j] = r2[j];
- }
+ for (j = 0; j < 32; j++)
+ r[j] = r2[j];
+ }
- concat (rl, r, l, 32, 32);
+concat (rl, r, l, 32, 32);
- permute (out, rl, perm6, 64);
+permute (out, rl, perm6, 64);
}
static void
str_to_key (uschar *str, uschar *key)
{
- int i;
-
- key[0] = str[0] >> 1;
- key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
- key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
- key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
- key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
- key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
- key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
- key[7] = str[6] & 0x7F;
- for (i = 0; i < 8; i++)
- {
- key[i] = (key[i] << 1);
- }
+int i;
+
+key[0] = str[0] >> 1;
+key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
+key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
+key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
+key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
+key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
+key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
+key[7] = str[6] & 0x7F;
+for (i = 0; i < 8; i++)
+ key[i] = (key[i] << 1);
}
static void
smbhash (uschar *out, uschar *in, uschar *key, int forw)
{
- int i;
- char outb[64];
- char inb[64];
- char keyb[64];
- uschar key2[8];
-
- str_to_key (key, key2);
-
- for (i = 0; i < 64; i++)
- {
- inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
- keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
- outb[i] = 0;
- }
+int i;
+char outb[64];
+char inb[64];
+char keyb[64];
+uschar key2[8];
+
+str_to_key (key, key2);
+
+for (i = 0; i < 64; i++)
+ {
+ inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
+ keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
+ outb[i] = 0;
+ }
- dohash (outb, inb, keyb, forw);
+dohash (outb, inb, keyb, forw);
- for (i = 0; i < 8; i++)
- {
- out[i] = 0;
- }
+for (i = 0; i < 8; i++)
+ out[i] = 0;
- for (i = 0; i < 64; i++)
- {
- if (outb[i])
- out[i / 8] |= (1 << (7 - (i % 8)));
- }
+for (i = 0; i < 64; i++)
+ if (outb[i])
+ out[i / 8] |= (1 << (7 - (i % 8)));
}
void
E_P16 (uschar *p14, uschar *p16)
{
- uschar sp8[8] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
- smbhash (p16, sp8, p14, 1);
- smbhash (p16 + 8, sp8, p14 + 7, 1);
+uschar sp8[8] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+smbhash (p16, sp8, p14, 1);
+smbhash (p16 + 8, sp8, p14 + 7, 1);
}
void
E_P24 (uschar *p21, uschar *c8, uschar *p24)
{
- smbhash (p24, c8, p21, 1);
- smbhash (p24 + 8, c8, p21 + 7, 1);
- smbhash (p24 + 16, c8, p21 + 14, 1);
+smbhash (p24, c8, p21, 1);
+smbhash (p24 + 8, c8, p21 + 7, 1);
+smbhash (p24 + 16, c8, p21 + 14, 1);
}
void
D_P16 (uschar *p14, uschar *in, uschar *out)
{
- smbhash (out, in, p14, 0);
- smbhash (out + 8, in + 8, p14 + 7, 0);
+smbhash (out, in, p14, 0);
+smbhash (out + 8, in + 8, p14 + 7, 0);
}
/****************************************************************************
char *
StrnCpy (char *dest, const char *src, size_t n)
{
- char *d = dest;
- if (!dest)
- return (NULL);
- if (!src)
- {
- *dest = 0;
- return (dest);
- }
- while (n-- && (*d++ = *src++));
- *d = 0;
+char *d = dest;
+if (!dest)
+ return (NULL);
+if (!src)
+ {
+ *dest = 0;
return (dest);
+ }
+while (n-- && (*d++ = *src++));
+*d = 0;
+return (dest);
}
size_t
skip_multibyte_char (char c)
{
- /* bogus if to get rid of unused compiler warning */
- if (c)
- return 0;
- else
- return 0;
+/* bogus if to get rid of unused compiler warning */
+if (c)
+ return 0;
+else
+ return 0;
}
char *
safe_strcpy (char *dest, const char *src, size_t maxlength)
{
- size_t len;
+size_t len;
- if (!dest)
- {
- DEBUG_X (0, ("ERROR: NULL dest in safe_strcpy\n"));
- return NULL;
- }
+if (!dest)
+ {
+ DEBUG_X (0, ("ERROR: NULL dest in safe_strcpy\n"));
+ return NULL;
+ }
- if (!src)
- {
- *dest = 0;
- return dest;
- }
+if (!src)
+ {
+ *dest = 0;
+ return dest;
+ }
- len = strlen (src);
+len = strlen (src);
- if (len > maxlength)
- {
- DEBUG_X (0, ("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
- (int) (len - maxlength), src));
- len = maxlength;
- }
+if (len > maxlength)
+ {
+ DEBUG_X (0, ("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
+ (int) (len - maxlength), src));
+ len = maxlength;
+ }
- memcpy (dest, src, len);
- dest[len] = 0;
- return dest;
+memcpy (dest, src, len);
+dest[len] = 0;
+return dest;
}
void
strupper (char *s)
{
- while (*s)
- {
- {
- size_t skip = skip_multibyte_char (*s);
- if (skip != 0)
- s += skip;
- else
- {
- if (islower ((uschar)(*s)))
- *s = toupper (*s);
- s++;
- }
- }
- }
+while (*s)
+ {
+ size_t skip = skip_multibyte_char (*s);
+ if (skip != 0)
+ s += skip;
+ else
+ {
+ if (islower ((uschar)(*s)))
+ *s = toupper (*s);
+ s++;
+ }
+ }
}
void
spa_smb_encrypt (uschar * passwd, uschar * c8, uschar * p24)
{
- uschar p14[15], p21[21];
+uschar p14[15], p21[21];
- memset (p21, '\0', 21);
- memset (p14, '\0', 14);
- StrnCpy (CS p14, CS passwd, 14);
+memset (p21, '\0', 21);
+memset (p14, '\0', 14);
+StrnCpy (CS p14, CS passwd, 14);
- strupper (CS p14);
- E_P16 (p14, p21);
+strupper (CS p14);
+E_P16 (p14, p21);
- SMBOWFencrypt (p21, c8, p24);
+SMBOWFencrypt (p21, c8, p24);
#ifdef DEBUG_PASSWORD
- DEBUG_X (100, ("spa_smb_encrypt: lm#, challenge, response\n"));
- dump_data (100, CS p21, 16);
- dump_data (100, CS c8, 8);
- dump_data (100, CS p24, 24);
+DEBUG_X (100, ("spa_smb_encrypt: lm#, challenge, response\n"));
+dump_data (100, CS p21, 16);
+dump_data (100, CS c8, 8);
+dump_data (100, CS p24, 24);
#endif
}
static int
_my_wcslen (int16x * str)
{
- int len = 0;
- while (*str++ != 0)
- len++;
- return len;
+int len = 0;
+while (*str++ != 0)
+ len++;
+return len;
}
/*
static int
_my_mbstowcs (int16x * dst, uschar * src, int len)
{
- int i;
- int16x val;
-
- for (i = 0; i < len; i++)
- {
- val = *src;
- SSVAL (dst, 0, val);
- dst++;
- src++;
- if (val == 0)
- break;
- }
- return i;
+int i;
+int16x val;
+
+for (i = 0; i < len; i++)
+ {
+ val = *src;
+ SSVAL (dst, 0, val);
+ dst++;
+ src++;
+ if (val == 0)
+ break;
+ }
+return i;
}
/*
void
E_md4hash (uschar * passwd, uschar * p16)
{
- int len;
- int16x wpwd[129];
-
- /* Password cannot be longer than 128 characters */
- len = strlen (CS passwd);
- if (len > 128)
- len = 128;
- /* Password must be converted to NT unicode */
- _my_mbstowcs (wpwd, passwd, len);
- wpwd[len] = 0; /* Ensure string is null terminated */
- /* Calculate length in bytes */
- len = _my_wcslen (wpwd) * sizeof (int16x);
-
- mdfour (p16, US wpwd, len);
+int len;
+int16x wpwd[129];
+
+/* Password cannot be longer than 128 characters */
+len = strlen (CS passwd);
+if (len > 128)
+ len = 128;
+/* Password must be converted to NT unicode */
+_my_mbstowcs (wpwd, passwd, len);
+wpwd[len] = 0; /* Ensure string is null terminated */
+/* Calculate length in bytes */
+len = _my_wcslen (wpwd) * sizeof (int16x);
+
+mdfour (p16, US wpwd, len);
}
/* Does both the NT and LM owfs of a user's password */
void
nt_lm_owf_gen (char *pwd, uschar nt_p16[16], uschar p16[16])
{
- char passwd[130];
+char passwd[130];
- memset (passwd, '\0', 130);
- safe_strcpy (passwd, pwd, sizeof (passwd) - 1);
+memset (passwd, '\0', 130);
+safe_strcpy (passwd, pwd, sizeof (passwd) - 1);
- /* Calculate the MD4 hash (NT compatible) of the password */
- memset (nt_p16, '\0', 16);
- E_md4hash (US passwd, nt_p16);
+/* Calculate the MD4 hash (NT compatible) of the password */
+memset (nt_p16, '\0', 16);
+E_md4hash (US passwd, nt_p16);
#ifdef DEBUG_PASSWORD
- DEBUG_X (100, ("nt_lm_owf_gen: pwd, nt#\n"));
- dump_data (120, passwd, strlen (passwd));
- dump_data (100, CS nt_p16, 16);
+DEBUG_X (100, ("nt_lm_owf_gen: pwd, nt#\n"));
+dump_data (120, passwd, strlen (passwd));
+dump_data (100, CS nt_p16, 16);
#endif
- /* Mangle the passwords into Lanman format */
- passwd[14] = '\0';
- strupper (passwd);
+/* Mangle the passwords into Lanman format */
+passwd[14] = '\0';
+strupper (passwd);
- /* Calculate the SMB (lanman) hash functions of the password */
+/* Calculate the SMB (lanman) hash functions of the password */
- memset (p16, '\0', 16);
- E_P16 (US passwd, US p16);
+memset (p16, '\0', 16);
+E_P16 (US passwd, US p16);
#ifdef DEBUG_PASSWORD
- DEBUG_X (100, ("nt_lm_owf_gen: pwd, lm#\n"));
- dump_data (120, passwd, strlen (passwd));
- dump_data (100, CS p16, 16);
+DEBUG_X (100, ("nt_lm_owf_gen: pwd, lm#\n"));
+dump_data (120, passwd, strlen (passwd));
+dump_data (100, CS p16, 16);
#endif
- /* clear out local copy of user's password (just being paranoid). */
- memset (passwd, '\0', sizeof (passwd));
+/* clear out local copy of user's password (just being paranoid). */
+memset (passwd, '\0', sizeof (passwd));
}
/* Does the des encryption from the NT or LM MD4 hash. */
void
SMBOWFencrypt (uschar passwd[16], uschar * c8, uschar p24[24])
{
- uschar p21[21];
+uschar p21[21];
- memset (p21, '\0', 21);
+memset (p21, '\0', 21);
- memcpy (p21, passwd, 16);
- E_P24 (p21, c8, p24);
+memcpy (p21, passwd, 16);
+E_P24 (p21, c8, p24);
}
/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
void
NTLMSSPOWFencrypt (uschar passwd[8], uschar * ntlmchalresp, uschar p24[24])
{
- uschar p21[21];
+uschar p21[21];
- memset (p21, '\0', 21);
- memcpy (p21, passwd, 8);
- memset (p21 + 8, 0xbd, 8);
+memset (p21, '\0', 21);
+memcpy (p21, passwd, 8);
+memset (p21 + 8, 0xbd, 8);
- E_P24 (p21, ntlmchalresp, p24);
+E_P24 (p21, ntlmchalresp, p24);
#ifdef DEBUG_PASSWORD
- DEBUG_X (100, ("NTLMSSPOWFencrypt: p21, c8, p24\n"));
- dump_data (100, CS p21, 21);
- dump_data (100, CS ntlmchalresp, 8);
- dump_data (100, CS p24, 24);
+DEBUG_X (100, ("NTLMSSPOWFencrypt: p21, c8, p24\n"));
+dump_data (100, CS p21, 21);
+dump_data (100, CS ntlmchalresp, 8);
+dump_data (100, CS p24, 24);
#endif
}
void
spa_smb_nt_encrypt (uschar * passwd, uschar * c8, uschar * p24)
{
- uschar p21[21];
+uschar p21[21];
- memset (p21, '\0', 21);
+memset (p21, '\0', 21);
- E_md4hash (passwd, p21);
- SMBOWFencrypt (p21, c8, p24);
+E_md4hash (passwd, p21);
+SMBOWFencrypt (p21, c8, p24);
#ifdef DEBUG_PASSWORD
- DEBUG_X (100, ("spa_smb_nt_encrypt: nt#, challenge, response\n"));
- dump_data (100, CS p21, 16);
- dump_data (100, CS c8, 8);
- dump_data (100, CS p24, 24);
+DEBUG_X (100, ("spa_smb_nt_encrypt: nt#, challenge, response\n"));
+dump_data (100, CS p21, 16);
+dump_data (100, CS c8, 8);
+dump_data (100, CS p24, 24);
#endif
}
static uint32x
F (uint32x X, uint32x Y, uint32x Z)
{
- return (X & Y) | ((~X) & Z);
+return (X & Y) | ((~X) & Z);
}
static uint32x
G (uint32x X, uint32x Y, uint32x Z)
{
- return (X & Y) | (X & Z) | (Y & Z);
+return (X & Y) | (X & Z) | (Y & Z);
}
static uint32x
H (uint32x X, uint32x Y, uint32x Z)
{
- return X ^ Y ^ Z;
+return X ^ Y ^ Z;
}
static uint32x
lshift_a (uint32x x, int s)
{
- x &= 0xFFFFFFFF;
- return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
+x &= 0xFFFFFFFF;
+return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
}
#define ROUND1(a,b,c,d,k,s) a = lshift_a(a + F(b,c,d) + X[k], s)
static void
spa_mdfour64 (uint32x * M)
{
- int j;
- uint32x AA, BB, CC, DD;
- uint32x X[16];
-
- for (j = 0; j < 16; j++)
- X[j] = M[j];
-
- AA = A;
- BB = B;
- CC = C;
- DD = D;
-
- ROUND1 (A, B, C, D, 0, 3);
- ROUND1 (D, A, B, C, 1, 7);
- ROUND1 (C, D, A, B, 2, 11);
- ROUND1 (B, C, D, A, 3, 19);
- ROUND1 (A, B, C, D, 4, 3);
- ROUND1 (D, A, B, C, 5, 7);
- ROUND1 (C, D, A, B, 6, 11);
- ROUND1 (B, C, D, A, 7, 19);
- ROUND1 (A, B, C, D, 8, 3);
- ROUND1 (D, A, B, C, 9, 7);
- ROUND1 (C, D, A, B, 10, 11);
- ROUND1 (B, C, D, A, 11, 19);
- ROUND1 (A, B, C, D, 12, 3);
- ROUND1 (D, A, B, C, 13, 7);
- ROUND1 (C, D, A, B, 14, 11);
- ROUND1 (B, C, D, A, 15, 19);
-
- ROUND2 (A, B, C, D, 0, 3);
- ROUND2 (D, A, B, C, 4, 5);
- ROUND2 (C, D, A, B, 8, 9);
- ROUND2 (B, C, D, A, 12, 13);
- ROUND2 (A, B, C, D, 1, 3);
- ROUND2 (D, A, B, C, 5, 5);
- ROUND2 (C, D, A, B, 9, 9);
- ROUND2 (B, C, D, A, 13, 13);
- ROUND2 (A, B, C, D, 2, 3);
- ROUND2 (D, A, B, C, 6, 5);
- ROUND2 (C, D, A, B, 10, 9);
- ROUND2 (B, C, D, A, 14, 13);
- ROUND2 (A, B, C, D, 3, 3);
- ROUND2 (D, A, B, C, 7, 5);
- ROUND2 (C, D, A, B, 11, 9);
- ROUND2 (B, C, D, A, 15, 13);
-
- ROUND3 (A, B, C, D, 0, 3);
- ROUND3 (D, A, B, C, 8, 9);
- ROUND3 (C, D, A, B, 4, 11);
- ROUND3 (B, C, D, A, 12, 15);
- ROUND3 (A, B, C, D, 2, 3);
- ROUND3 (D, A, B, C, 10, 9);
- ROUND3 (C, D, A, B, 6, 11);
- ROUND3 (B, C, D, A, 14, 15);
- ROUND3 (A, B, C, D, 1, 3);
- ROUND3 (D, A, B, C, 9, 9);
- ROUND3 (C, D, A, B, 5, 11);
- ROUND3 (B, C, D, A, 13, 15);
- ROUND3 (A, B, C, D, 3, 3);
- ROUND3 (D, A, B, C, 11, 9);
- ROUND3 (C, D, A, B, 7, 11);
- ROUND3 (B, C, D, A, 15, 15);
-
- A += AA;
- B += BB;
- C += CC;
- D += DD;
-
- A &= 0xFFFFFFFF;
- B &= 0xFFFFFFFF;
- C &= 0xFFFFFFFF;
- D &= 0xFFFFFFFF;
-
- for (j = 0; j < 16; j++)
- X[j] = 0;
+int j;
+uint32x AA, BB, CC, DD;
+uint32x X[16];
+
+for (j = 0; j < 16; j++)
+ X[j] = M[j];
+
+AA = A;
+BB = B;
+CC = C;
+DD = D;
+
+ROUND1 (A, B, C, D, 0, 3);
+ROUND1 (D, A, B, C, 1, 7);
+ROUND1 (C, D, A, B, 2, 11);
+ROUND1 (B, C, D, A, 3, 19);
+ROUND1 (A, B, C, D, 4, 3);
+ROUND1 (D, A, B, C, 5, 7);
+ROUND1 (C, D, A, B, 6, 11);
+ROUND1 (B, C, D, A, 7, 19);
+ROUND1 (A, B, C, D, 8, 3);
+ROUND1 (D, A, B, C, 9, 7);
+ROUND1 (C, D, A, B, 10, 11);
+ROUND1 (B, C, D, A, 11, 19);
+ROUND1 (A, B, C, D, 12, 3);
+ROUND1 (D, A, B, C, 13, 7);
+ROUND1 (C, D, A, B, 14, 11);
+ROUND1 (B, C, D, A, 15, 19);
+
+ROUND2 (A, B, C, D, 0, 3);
+ROUND2 (D, A, B, C, 4, 5);
+ROUND2 (C, D, A, B, 8, 9);
+ROUND2 (B, C, D, A, 12, 13);
+ROUND2 (A, B, C, D, 1, 3);
+ROUND2 (D, A, B, C, 5, 5);
+ROUND2 (C, D, A, B, 9, 9);
+ROUND2 (B, C, D, A, 13, 13);
+ROUND2 (A, B, C, D, 2, 3);
+ROUND2 (D, A, B, C, 6, 5);
+ROUND2 (C, D, A, B, 10, 9);
+ROUND2 (B, C, D, A, 14, 13);
+ROUND2 (A, B, C, D, 3, 3);
+ROUND2 (D, A, B, C, 7, 5);
+ROUND2 (C, D, A, B, 11, 9);
+ROUND2 (B, C, D, A, 15, 13);
+
+ROUND3 (A, B, C, D, 0, 3);
+ROUND3 (D, A, B, C, 8, 9);
+ROUND3 (C, D, A, B, 4, 11);
+ROUND3 (B, C, D, A, 12, 15);
+ROUND3 (A, B, C, D, 2, 3);
+ROUND3 (D, A, B, C, 10, 9);
+ROUND3 (C, D, A, B, 6, 11);
+ROUND3 (B, C, D, A, 14, 15);
+ROUND3 (A, B, C, D, 1, 3);
+ROUND3 (D, A, B, C, 9, 9);
+ROUND3 (C, D, A, B, 5, 11);
+ROUND3 (B, C, D, A, 13, 15);
+ROUND3 (A, B, C, D, 3, 3);
+ROUND3 (D, A, B, C, 11, 9);
+ROUND3 (C, D, A, B, 7, 11);
+ROUND3 (B, C, D, A, 15, 15);
+
+A += AA;
+B += BB;
+C += CC;
+D += DD;
+
+A &= 0xFFFFFFFF;
+B &= 0xFFFFFFFF;
+C &= 0xFFFFFFFF;
+D &= 0xFFFFFFFF;
+
+for (j = 0; j < 16; j++)
+ X[j] = 0;
}
static void
copy64 (uint32x * M, uschar *in)
{
- int i;
+int i;
- for (i = 0; i < 16; i++)
- M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
- (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
+for (i = 0; i < 16; i++)
+ M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
+ (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
}
static void
copy4 (uschar *out, uint32x x)
{
- out[0] = x & 0xFF;
- out[1] = (x >> 8) & 0xFF;
- out[2] = (x >> 16) & 0xFF;
- out[3] = (x >> 24) & 0xFF;
+out[0] = x & 0xFF;
+out[1] = (x >> 8) & 0xFF;
+out[2] = (x >> 16) & 0xFF;
+out[3] = (x >> 24) & 0xFF;
}
/* produce a md4 message digest from data of length n bytes */
void
mdfour (uschar *out, uschar *in, int n)
{
- uschar buf[128];
- uint32x M[16];
- uint32x b = n * 8;
- int i;
-
- A = 0x67452301;
- B = 0xefcdab89;
- C = 0x98badcfe;
- D = 0x10325476;
-
- while (n > 64)
- {
- copy64 (M, in);
- spa_mdfour64 (M);
- in += 64;
- n -= 64;
- }
-
- for (i = 0; i < 128; i++)
- buf[i] = 0;
- memcpy (buf, in, n);
- buf[n] = 0x80;
+uschar buf[128];
+uint32x M[16];
+uint32x b = n * 8;
+int i;
+
+A = 0x67452301;
+B = 0xefcdab89;
+C = 0x98badcfe;
+D = 0x10325476;
+
+while (n > 64)
+ {
+ copy64 (M, in);
+ spa_mdfour64 (M);
+ in += 64;
+ n -= 64;
+ }
- if (n <= 55)
- {
- copy4 (buf + 56, b);
- copy64 (M, buf);
- spa_mdfour64 (M);
- }
- else
- {
- copy4 (buf + 120, b);
- copy64 (M, buf);
- spa_mdfour64 (M);
- copy64 (M, buf + 64);
- spa_mdfour64 (M);
- }
+for (i = 0; i < 128; i++)
+ buf[i] = 0;
+memcpy (buf, in, n);
+buf[n] = 0x80;
- for (i = 0; i < 128; i++)
- buf[i] = 0;
+if (n <= 55)
+ {
+ copy4 (buf + 56, b);
copy64 (M, buf);
+ spa_mdfour64 (M);
+ }
+else
+ {
+ copy4 (buf + 120, b);
+ copy64 (M, buf);
+ spa_mdfour64 (M);
+ copy64 (M, buf + 64);
+ spa_mdfour64 (M);
+ }
- copy4 (out, A);
- copy4 (out + 4, B);
- copy4 (out + 8, C);
- copy4 (out + 12, D);
+for (i = 0; i < 128; i++)
+ buf[i] = 0;
+copy64 (M, buf);
- A = B = C = D = 0;
+copy4 (out, A);
+copy4 (out + 4, B);
+copy4 (out + 8, C);
+copy4 (out + 12, D);
+
+A = B = C = D = 0;
}
char versionString[] = "libntlm version 0.21";
static void
dumpRaw (FILE * fp, uschar *buf, size_t len)
{
- int i;
+int i;
- for (i = 0; i < len; ++i)
- fprintf (fp, "%02x ", buf[i]);
+for (i = 0; i < len; ++i)
+ fprintf (fp, "%02x ", buf[i]);
- fprintf (fp, "\n");
+fprintf (fp, "\n");
}
#endif
char *
unicodeToString (char *p, size_t len)
{
- int i;
- static char buf[1024];
+int i;
+static char buf[1024];
- assert (len + 1 < sizeof buf);
+assert (len + 1 < sizeof buf);
- for (i = 0; i < len; ++i)
- {
- buf[i] = *p & 0x7f;
- p += 2;
- }
+for (i = 0; i < len; ++i)
+ {
+ buf[i] = *p & 0x7f;
+ p += 2;
+ }
- buf[i] = '\0';
- return buf;
+buf[i] = '\0';
+return buf;
}
static uschar *
strToUnicode (char *p)
{
- static uschar buf[1024];
- size_t l = strlen (p);
- int i = 0;
+static uschar buf[1024];
+size_t l = strlen (p);
+int i = 0;
- assert (l * 2 < sizeof buf);
+assert (l * 2 < sizeof buf);
- while (l--)
- {
- buf[i++] = *p++;
- buf[i++] = 0;
- }
+while (l--)
+ {
+ buf[i++] = *p++;
+ buf[i++] = 0;
+ }
- return buf;
+return buf;
}
static uschar *
toString (char *p, size_t len)
{
- static uschar buf[1024];
+static uschar buf[1024];
- assert (len + 1 < sizeof buf);
+assert (len + 1 < sizeof buf);
- memcpy (buf, p, len);
- buf[len] = 0;
- return buf;
+memcpy (buf, p, len);
+buf[len] = 0;
+return buf;
}
#ifdef notdef
void
dumpSmbNtlmAuthRequest (FILE * fp, SPAAuthRequest * request)
{
- fprintf (fp, "NTLM Request:\n");
- fprintf (fp, " Ident = %s\n", request->ident);
- fprintf (fp, " mType = %d\n", IVAL (&request->msgType, 0));
- fprintf (fp, " Flags = %08x\n", IVAL (&request->flags, 0));
- fprintf (fp, " User = %s\n", GetString (request, user));
- fprintf (fp, " Domain = %s\n", GetString (request, domain));
+fprintf (fp, "NTLM Request:\n");
+fprintf (fp, " Ident = %s\n", request->ident);
+fprintf (fp, " mType = %d\n", IVAL (&request->msgType, 0));
+fprintf (fp, " Flags = %08x\n", IVAL (&request->flags, 0));
+fprintf (fp, " User = %s\n", GetString (request, user));
+fprintf (fp, " Domain = %s\n", GetString (request, domain));
}
void
dumpSmbNtlmAuthChallenge (FILE * fp, SPAAuthChallenge * challenge)
{
- fprintf (fp, "NTLM Challenge:\n");
- fprintf (fp, " Ident = %s\n", challenge->ident);
- fprintf (fp, " mType = %d\n", IVAL (&challenge->msgType, 0));
- fprintf (fp, " Domain = %s\n", GetUnicodeString (challenge, uDomain));
- fprintf (fp, " Flags = %08x\n", IVAL (&challenge->flags, 0));
- fprintf (fp, " Challenge = ");
- dumpRaw (fp, challenge->challengeData, 8);
+fprintf (fp, "NTLM Challenge:\n");
+fprintf (fp, " Ident = %s\n", challenge->ident);
+fprintf (fp, " mType = %d\n", IVAL (&challenge->msgType, 0));
+fprintf (fp, " Domain = %s\n", GetUnicodeString (challenge, uDomain));
+fprintf (fp, " Flags = %08x\n", IVAL (&challenge->flags, 0));
+fprintf (fp, " Challenge = ");
+dumpRaw (fp, challenge->challengeData, 8);
}
void
dumpSmbNtlmAuthResponse (FILE * fp, SPAAuthResponse * response)
{
- fprintf (fp, "NTLM Response:\n");
- fprintf (fp, " Ident = %s\n", response->ident);
- fprintf (fp, " mType = %d\n", IVAL (&response->msgType, 0));
- fprintf (fp, " LmResp = ");
- DumpBuffer (fp, response, lmResponse);
- fprintf (fp, " NTResp = ");
- DumpBuffer (fp, response, ntResponse);
- fprintf (fp, " Domain = %s\n", GetUnicodeString (response, uDomain));
- fprintf (fp, " User = %s\n", GetUnicodeString (response, uUser));
- fprintf (fp, " Wks = %s\n", GetUnicodeString (response, uWks));
- fprintf (fp, " sKey = ");
- DumpBuffer (fp, response, sessionKey);
- fprintf (fp, " Flags = %08x\n", IVAL (&response->flags, 0));
+fprintf (fp, "NTLM Response:\n");
+fprintf (fp, " Ident = %s\n", response->ident);
+fprintf (fp, " mType = %d\n", IVAL (&response->msgType, 0));
+fprintf (fp, " LmResp = ");
+DumpBuffer (fp, response, lmResponse);
+fprintf (fp, " NTResp = ");
+DumpBuffer (fp, response, ntResponse);
+fprintf (fp, " Domain = %s\n", GetUnicodeString (response, uDomain));
+fprintf (fp, " User = %s\n", GetUnicodeString (response, uUser));
+fprintf (fp, " Wks = %s\n", GetUnicodeString (response, uWks));
+fprintf (fp, " sKey = ");
+DumpBuffer (fp, response, sessionKey);
+fprintf (fp, " Flags = %08x\n", IVAL (&response->flags, 0));
}
#endif
void
spa_build_auth_request (SPAAuthRequest * request, char *user, char *domain)
{
- char *u = strdup (user);
- char *p = strchr (u, '@');
-
- if (p)
- {
- if (!domain)
- domain = p + 1;
- *p = '\0';
- }
+char *u = strdup (user);
+char *p = strchr (u, '@');
+
+if (p)
+ {
+ if (!domain)
+ domain = p + 1;
+ *p = '\0';
+ }
- request->bufIndex = 0;
- memcpy (request->ident, "NTLMSSP\0\0\0", 8);
- SIVAL (&request->msgType, 0, 1);
- SIVAL (&request->flags, 0, 0x0000b207); /* have to figure out what these mean */
- spa_string_add (request, user, u);
- spa_string_add (request, domain, domain);
- free (u);
+request->bufIndex = 0;
+memcpy (request->ident, "NTLMSSP\0\0\0", 8);
+SIVAL (&request->msgType, 0, 1);
+SIVAL (&request->flags, 0, 0x0000b207); /* have to figure out what these mean */
+spa_string_add (request, user, u);
+spa_string_add (request, domain, domain);
+free (u);
}
void
spa_build_auth_challenge (SPAAuthRequest * request, SPAAuthChallenge * challenge)
{
- char chalstr[8];
- int i;
- int p = (int)getpid();
- int random_seed = (int)time(NULL) ^ ((p << 16) | p);
+char chalstr[8];
+int i;
+int p = (int)getpid();
+int random_seed = (int)time(NULL) ^ ((p << 16) | p);
- request = request; /* Added by PH to stop compilers whinging */
+request = request; /* Added by PH to stop compilers whinging */
- /* Ensure challenge data is cleared, in case it isn't all used. This
- patch added by PH on suggestion of Russell King */
+/* Ensure challenge data is cleared, in case it isn't all used. This
+patch added by PH on suggestion of Russell King */
- memset(challenge, 0, sizeof(SPAAuthChallenge));
+memset(challenge, 0, sizeof(SPAAuthChallenge));
- challenge->bufIndex = 0;
- memcpy (challenge->ident, "NTLMSSP\0", 8);
- SIVAL (&challenge->msgType, 0, 2);
- SIVAL (&challenge->flags, 0, 0x00008201);
- SIVAL (&challenge->uDomain.len, 0, 0x0000);
- SIVAL (&challenge->uDomain.maxlen, 0, 0x0000);
- SIVAL (&challenge->uDomain.offset, 0, 0x00002800);
+challenge->bufIndex = 0;
+memcpy (challenge->ident, "NTLMSSP\0", 8);
+SIVAL (&challenge->msgType, 0, 2);
+SIVAL (&challenge->flags, 0, 0x00008201);
+SIVAL (&challenge->uDomain.len, 0, 0x0000);
+SIVAL (&challenge->uDomain.maxlen, 0, 0x0000);
+SIVAL (&challenge->uDomain.offset, 0, 0x00002800);
- /* generate eight pseudo random bytes (method ripped from host.c) */
+/* generate eight pseudo random bytes (method ripped from host.c) */
- for(i=0;i<8;i++) {
- chalstr[i] = (uschar)(random_seed >> 16) % 256;
- random_seed = (1103515245 - (chalstr[i])) * random_seed + 12345;
- };
+for(i=0;i<8;i++)
+ {
+ chalstr[i] = (uschar)(random_seed >> 16) % 256;
+ random_seed = (1103515245 - (chalstr[i])) * random_seed + 12345;
+ }
- memcpy(challenge->challengeData,chalstr,8);
+memcpy(challenge->challengeData,chalstr,8);
}
SPAAuthResponse * response, char *user,
char *password)
{
- uint8x lmRespData[24];
- uint8x ntRespData[24];
- char *d = strdup (GetUnicodeString (challenge, uDomain));
- char *domain = d;
- char *u = strdup (user);
- char *p = strchr (u, '@');
-
- if (p)
- {
- domain = p + 1;
- *p = '\0';
- }
+uint8x lmRespData[24];
+uint8x ntRespData[24];
+char *d = strdup (GetUnicodeString (challenge, uDomain));
+char *domain = d;
+char *u = strdup (user);
+char *p = strchr (u, '@');
+
+if (p)
+ {
+ domain = p + 1;
+ *p = '\0';
+ }
- spa_smb_encrypt (US password, challenge->challengeData, lmRespData);
- spa_smb_nt_encrypt (US password, challenge->challengeData, ntRespData);
+spa_smb_encrypt (US password, challenge->challengeData, lmRespData);
+spa_smb_nt_encrypt (US password, challenge->challengeData, ntRespData);
- response->bufIndex = 0;
- memcpy (response->ident, "NTLMSSP\0\0\0", 8);
- SIVAL (&response->msgType, 0, 3);
+response->bufIndex = 0;
+memcpy (response->ident, "NTLMSSP\0\0\0", 8);
+SIVAL (&response->msgType, 0, 3);
- spa_bytes_add (response, lmResponse, lmRespData, 24);
- spa_bytes_add (response, ntResponse, ntRespData, 24);
- spa_unicode_add_string (response, uDomain, domain);
- spa_unicode_add_string (response, uUser, u);
- spa_unicode_add_string (response, uWks, u);
- spa_string_add (response, sessionKey, NULL);
+spa_bytes_add (response, lmResponse, lmRespData, 24);
+spa_bytes_add (response, ntResponse, ntRespData, 24);
+spa_unicode_add_string (response, uDomain, domain);
+spa_unicode_add_string (response, uUser, u);
+spa_unicode_add_string (response, uWks, u);
+spa_string_add (response, sessionKey, NULL);
- response->flags = challenge->flags;
+response->flags = challenge->flags;
- free (d);
- free (u);
+free (d);
+free (u);
}
#endif
SPAAuthResponse * response, char *user,
char *password)
{
- uint8x lmRespData[24];
- uint8x ntRespData[24];
- uint32x cf = IVAL(&challenge->flags, 0);
- char *u = strdup (user);
- char *p = strchr (u, '@');
- char *d = NULL;
- char *domain;
-
- if (p)
- {
- domain = p + 1;
- *p = '\0';
- }
+uint8x lmRespData[24];
+uint8x ntRespData[24];
+uint32x cf = IVAL(&challenge->flags, 0);
+char *u = strdup (user);
+char *p = strchr (u, '@');
+char *d = NULL;
+char *domain;
+
+if (p)
+ {
+ domain = p + 1;
+ *p = '\0';
+ }
- else domain = d = strdup((cf & 0x1)?
- CCS GetUnicodeString(challenge, uDomain) :
- CCS GetString(challenge, uDomain));
+else domain = d = strdup((cf & 0x1)?
+ CCS GetUnicodeString(challenge, uDomain) :
+ CCS GetString(challenge, uDomain));
- spa_smb_encrypt (US password, challenge->challengeData, lmRespData);
- spa_smb_nt_encrypt (US password, challenge->challengeData, ntRespData);
+spa_smb_encrypt (US password, challenge->challengeData, lmRespData);
+spa_smb_nt_encrypt (US password, challenge->challengeData, ntRespData);
- response->bufIndex = 0;
- memcpy (response->ident, "NTLMSSP\0\0\0", 8);
- SIVAL (&response->msgType, 0, 3);
+response->bufIndex = 0;
+memcpy (response->ident, "NTLMSSP\0\0\0", 8);
+SIVAL (&response->msgType, 0, 3);
- spa_bytes_add (response, lmResponse, lmRespData, (cf & 0x200) ? 24 : 0);
- spa_bytes_add (response, ntResponse, ntRespData, (cf & 0x8000) ? 24 : 0);
+spa_bytes_add (response, lmResponse, lmRespData, (cf & 0x200) ? 24 : 0);
+spa_bytes_add (response, ntResponse, ntRespData, (cf & 0x8000) ? 24 : 0);
- if (cf & 0x1) { /* Unicode Text */
- spa_unicode_add_string (response, uDomain, domain);
- spa_unicode_add_string (response, uUser, u);
- spa_unicode_add_string (response, uWks, u);
- } else { /* OEM Text */
- spa_string_add (response, uDomain, domain);
- spa_string_add (response, uUser, u);
- spa_string_add (response, uWks, u);
- }
+if (cf & 0x1) { /* Unicode Text */
+ spa_unicode_add_string (response, uDomain, domain);
+ spa_unicode_add_string (response, uUser, u);
+ spa_unicode_add_string (response, uWks, u);
+} else { /* OEM Text */
+ spa_string_add (response, uDomain, domain);
+ spa_string_add (response, uUser, u);
+ spa_string_add (response, uWks, u);
+}
- spa_string_add (response, sessionKey, NULL);
- response->flags = challenge->flags;
+spa_string_add (response, sessionKey, NULL);
+response->flags = challenge->flags;
- if (d != NULL) free (d);
- free (u);
+if (d != NULL) free (d);
+free (u);
}
pam_converse (int num_msg, PAM_CONVERSE_ARG2_TYPE **msg,
struct pam_response **resp, void *appdata_ptr)
{
-int i;
int sep = 0;
struct pam_response *reply;
if (reply == NULL) return PAM_CONV_ERR;
-for (i = 0; i < num_msg; i++)
+for (int i = 0; i < num_msg; i++)
{
uschar *arg;
switch (msg[i]->msg_style)
HDEBUG(D_auth)
{
- int i;
debug_printf("%s authenticator %s:\n", ablock->name, label);
- for (i = 0; i < AUTH_VARS; i++)
+ for (int i = 0; i < AUTH_VARS; i++)
{
if (auth_vars[i] != NULL)
debug_printf(" $auth%d = %s\n", i + 1, auth_vars[i]);
}
- for (i = 1; i <= expand_nmax; i++)
+ for (int i = 1; i <= expand_nmax; i++)
debug_printf(" $%d = %.*s\n", i, expand_nlength[i], expand_nstring[i]);
debug_print_string(ablock->server_debug_string); /* customized debug */
}
compute_cram_md5(uschar *secret, uschar *challenge, uschar *digestptr)
{
md5 base;
-int i;
int len = Ustrlen(secret);
uschar isecret[64];
uschar osecret[64];
memset(isecret+len, 0, 64-len);
memcpy(osecret, isecret, 64);
-for (i = 0; i < 64; i++)
+for (int i = 0; i < 64; i++)
{
isecret[i] ^= 0x36;
osecret[i] ^= 0x5c;
sasl_callback_t cbs[] = {{SASL_CB_LIST_END, NULL, NULL}};
sasl_conn_t *conn;
char * realm_expanded = NULL;
-int rc, i, firsttime = 1, clen, *negotiated_ssf_ptr = NULL, negotiated_ssf;
+int rc, firsttime = 1, clen, *negotiated_ssf_ptr = NULL, negotiated_ssf;
unsigned int inlen, outlen;
input = data;
So the docs are too strict and we shouldn't worry about :: contractions. */
/* Set properties for remote and local host-ip;port */
-for (i = 0; i < 2; ++i)
+for (int i = 0; i < 2; ++i)
{
struct sockaddr_storage ss;
int (*query)(int, struct sockaddr *, socklen_t *);
auth_instance *ablock, /* authenticator block */
void * sx, /* connexction */
int timeout, /* command timeout */
- uschar *buffer, /* for reading response */
+ uschar *buffer, /* for reading response */
int buffsize) /* size of buffer */
{
/* We don't support clients (yet) in this implementation of cyrus_sasl */
static int
strcut(uschar *str, uschar **ptrs, int nptrs)
{
- uschar *last_sub_start = str;
- int n;
-
- for (n = 0; n < nptrs; n++)
- ptrs[n] = NULL;
- n = 1;
-
- while (*str) {
- if (*str == '\t') {
- if (n <= nptrs) {
- *ptrs++ = last_sub_start;
- last_sub_start = str + 1;
- *str = '\0';
- }
- n++;
- }
- str++;
- }
-
- /* It's acceptable for the string to end with a tab character. We see
- this in AUTH PLAIN without an initial response from the client, which
- causing us to send "334 " and get the data from the client. */
- if (n <= nptrs) {
- *ptrs = last_sub_start;
- } else {
- HDEBUG(D_auth) debug_printf("dovecot: warning: too many results from tab-splitting; saw %d fields, room for %d\n", n, nptrs);
- n = nptrs;
- }
-
- return n <= nptrs ? n : nptrs;
+uschar *last_sub_start = str;
+int n;
+
+for (n = 0; n < nptrs; n++)
+ ptrs[n] = NULL;
+n = 1;
+
+while (*str)
+ {
+ if (*str == '\t')
+ {
+ if (n <= nptrs)
+ {
+ *ptrs++ = last_sub_start;
+ last_sub_start = str + 1;
+ *str = '\0';
+ }
+ n++;
+ }
+ str++;
+ }
+
+/* It's acceptable for the string to end with a tab character. We see
+this in AUTH PLAIN without an initial response from the client, which
+causing us to send "334 " and get the data from the client. */
+if (n <= nptrs)
+ *ptrs = last_sub_start;
+else
+ {
+ HDEBUG(D_auth) debug_printf("dovecot: warning: too many results from tab-splitting; saw %d fields, room for %d\n", n, nptrs);
+ n = nptrs;
+ }
+
+return n <= nptrs ? n : nptrs;
}
static void debug_strcut(uschar **ptrs, int nlen, int alen) ARG_UNUSED;
static void
debug_strcut(uschar **ptrs, int nlen, int alen)
{
- int i;
- debug_printf("%d read but unreturned bytes; strcut() gave %d results: ",
- socket_buffer_left, nlen);
- for (i = 0; i < nlen; i++) {
- debug_printf(" {%s}", ptrs[i]);
- }
- if (nlen < alen)
- debug_printf(" last is %s\n", ptrs[i] ? ptrs[i] : US"<null>");
- else
- debug_printf(" (max for capacity)\n");
+int i;
+debug_printf("%d read but unreturned bytes; strcut() gave %d results: ",
+ socket_buffer_left, nlen);
+for (i = 0; i < nlen; i++)
+ debug_printf(" {%s}", ptrs[i]);
+if (nlen < alen)
+ debug_printf(" last is %s\n", ptrs[i] ? ptrs[i] : US"<null>");
+else
+ debug_printf(" (max for capacity)\n");
}
#define CHECK_COMMAND(str, arg_min, arg_max) do { \
void
auth_gsasl_init(auth_instance *ablock)
{
- char *p;
- int rc, supported;
- auth_gsasl_options_block *ob =
- (auth_gsasl_options_block *)(ablock->options_block);
-
- /* As per existing Cyrus glue, use the authenticator's public name as
- the default for the mechanism name; we don't handle multiple mechanisms
- in one authenticator, but the same driver can be used multiple times. */
-
- if (ob->server_mech == NULL)
- ob->server_mech = string_copy(ablock->public_name);
-
- /* Can get multiple session contexts from one library context, so just
- initialise the once. */
- if (gsasl_ctx == NULL) {
- rc = gsasl_init(&gsasl_ctx);
- if (rc != GSASL_OK) {
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
- "couldn't initialise GNU SASL library: %s (%s)",
- ablock->name, gsasl_strerror_name(rc), gsasl_strerror(rc));
- }
- gsasl_callback_set(gsasl_ctx, main_callback);
+char *p;
+int rc, supported;
+auth_gsasl_options_block *ob =
+ (auth_gsasl_options_block *)(ablock->options_block);
+
+/* As per existing Cyrus glue, use the authenticator's public name as
+the default for the mechanism name; we don't handle multiple mechanisms
+in one authenticator, but the same driver can be used multiple times. */
+
+if (ob->server_mech == NULL)
+ ob->server_mech = string_copy(ablock->public_name);
+
+/* Can get multiple session contexts from one library context, so just
+initialise the once. */
+if (gsasl_ctx == NULL) {
+ rc = gsasl_init(&gsasl_ctx);
+ if (rc != GSASL_OK) {
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
+ "couldn't initialise GNU SASL library: %s (%s)",
+ ablock->name, gsasl_strerror_name(rc), gsasl_strerror(rc));
}
+ gsasl_callback_set(gsasl_ctx, main_callback);
+}
- /* We don't need this except to log it for debugging. */
- rc = gsasl_server_mechlist(gsasl_ctx, &p);
- if (rc != GSASL_OK)
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
- "failed to retrieve list of mechanisms: %s (%s)",
- ablock->name, gsasl_strerror_name(rc), gsasl_strerror(rc));
- HDEBUG(D_auth) debug_printf("GNU SASL supports: %s\n", p);
+/* We don't need this except to log it for debugging. */
+rc = gsasl_server_mechlist(gsasl_ctx, &p);
+if (rc != GSASL_OK)
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
+ "failed to retrieve list of mechanisms: %s (%s)",
+ ablock->name, gsasl_strerror_name(rc), gsasl_strerror(rc));
+HDEBUG(D_auth) debug_printf("GNU SASL supports: %s\n", p);
- supported = gsasl_client_support_p(gsasl_ctx, CCS ob->server_mech);
- if (!supported)
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
- "GNU SASL does not support mechanism \"%s\"",
- ablock->name, ob->server_mech);
-
- if ((ablock->server_condition == NULL) &&
- (streqic(ob->server_mech, US"EXTERNAL") ||
- streqic(ob->server_mech, US"ANONYMOUS") ||
- streqic(ob->server_mech, US"PLAIN") ||
- streqic(ob->server_mech, US"LOGIN")))
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
- "Need server_condition for %s mechanism",
- ablock->name, ob->server_mech);
+supported = gsasl_client_support_p(gsasl_ctx, CCS ob->server_mech);
+if (!supported)
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
+ "GNU SASL does not support mechanism \"%s\"",
+ ablock->name, ob->server_mech);
+
+if ((ablock->server_condition == NULL) &&
+ (streqic(ob->server_mech, US"EXTERNAL") ||
+ streqic(ob->server_mech, US"ANONYMOUS") ||
+ streqic(ob->server_mech, US"PLAIN") ||
+ streqic(ob->server_mech, US"LOGIN")))
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
+ "Need server_condition for %s mechanism",
+ ablock->name, ob->server_mech);
- /* This does *not* scale to new SASL mechanisms. Need a better way to ask
- which properties will be needed. */
- if ((ob->server_realm == NULL) &&
- streqic(ob->server_mech, US"DIGEST-MD5"))
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
- "Need server_realm for %s mechanism",
- ablock->name, ob->server_mech);
+/* This does *not* scale to new SASL mechanisms. Need a better way to ask
+which properties will be needed. */
+if ((ob->server_realm == NULL) &&
+ streqic(ob->server_mech, US"DIGEST-MD5"))
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
+ "Need server_realm for %s mechanism",
+ ablock->name, ob->server_mech);
- /* At present, for mechanisms we don't panic on absence of server_condition;
- need to figure out the most generically correct approach to deciding when
- it's critical and when it isn't. Eg, for simple validation (PLAIN mechanism,
- etc) it clearly is critical.
+/* At present, for mechanisms we don't panic on absence of server_condition;
+need to figure out the most generically correct approach to deciding when
+it's critical and when it isn't. Eg, for simple validation (PLAIN mechanism,
+etc) it clearly is critical.
- So don't activate without server_condition, this might be relaxed in the future.
- */
- if (ablock->server_condition != NULL) ablock->server = TRUE;
- ablock->client = FALSE;
+So don't activate without server_condition, this might be relaxed in the future.
+*/
+if (ablock->server_condition != NULL) ablock->server = TRUE;
+ablock->client = FALSE;
}
static int
main_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
{
- int rc = 0;
- struct callback_exim_state *cb_state =
- (struct callback_exim_state *)gsasl_session_hook_get(sctx);
-
- HDEBUG(D_auth)
- debug_printf("GNU SASL Callback entered, prop=%d (loop prop=%d)\n",
- prop, callback_loop);
-
- if (cb_state == NULL) {
- HDEBUG(D_auth) debug_printf(" not from our server/client processing.\n");
- return GSASL_NO_CALLBACK;
+int rc = 0;
+struct callback_exim_state *cb_state =
+ (struct callback_exim_state *)gsasl_session_hook_get(sctx);
+
+HDEBUG(D_auth)
+ debug_printf("GNU SASL Callback entered, prop=%d (loop prop=%d)\n",
+ prop, callback_loop);
+
+if (cb_state == NULL)
+ {
+ HDEBUG(D_auth) debug_printf(" not from our server/client processing.\n");
+ return GSASL_NO_CALLBACK;
}
- if (callback_loop > 0) {
- /* Most likely is that we were asked for property foo, and to
- expand the string we asked for property bar to put into an auth
- variable, but property bar is not supplied for this mechanism. */
- HDEBUG(D_auth)
- debug_printf("Loop, asked for property %d while handling property %d\n",
- prop, callback_loop);
- return GSASL_NO_CALLBACK;
+if (callback_loop > 0)
+ {
+ /* Most likely is that we were asked for property foo, and to
+ expand the string we asked for property bar to put into an auth
+ variable, but property bar is not supplied for this mechanism. */
+ HDEBUG(D_auth)
+ debug_printf("Loop, asked for property %d while handling property %d\n",
+ prop, callback_loop);
+ return GSASL_NO_CALLBACK;
}
- callback_loop = prop;
+callback_loop = prop;
- if (cb_state->currently == CURRENTLY_CLIENT)
- rc = client_callback(ctx, sctx, prop, cb_state->ablock);
- else if (cb_state->currently == CURRENTLY_SERVER)
- rc = server_callback(ctx, sctx, prop, cb_state->ablock);
- else {
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
- "unhandled callback state, bug in Exim", cb_state->ablock->name);
- /* NOTREACHED */
- }
+if (cb_state->currently == CURRENTLY_CLIENT)
+ rc = client_callback(ctx, sctx, prop, cb_state->ablock);
+else if (cb_state->currently == CURRENTLY_SERVER)
+ rc = server_callback(ctx, sctx, prop, cb_state->ablock);
+else
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
+ "unhandled callback state, bug in Exim", cb_state->ablock->name);
+ /* NOTREACHED */
- callback_loop = 0;
- return rc;
+callback_loop = 0;
+return rc;
}
int
auth_gsasl_server(auth_instance *ablock, uschar *initial_data)
{
- char *tmps;
- char *to_send, *received;
- Gsasl_session *sctx = NULL;
- auth_gsasl_options_block *ob =
- (auth_gsasl_options_block *)(ablock->options_block);
- struct callback_exim_state cb_state;
- int rc, auth_result, exim_error, exim_error_override;
-
- HDEBUG(D_auth)
- debug_printf("GNU SASL: initialising session for %s, mechanism %s.\n",
- ablock->name, ob->server_mech);
-
- rc = gsasl_server_start(gsasl_ctx, CCS ob->server_mech, &sctx);
- if (rc != GSASL_OK) {
- auth_defer_msg = string_sprintf("GNU SASL: session start failure: %s (%s)",
- gsasl_strerror_name(rc), gsasl_strerror(rc));
- HDEBUG(D_auth) debug_printf("%s\n", auth_defer_msg);
- return DEFER;
+char *tmps;
+char *to_send, *received;
+Gsasl_session *sctx = NULL;
+auth_gsasl_options_block *ob =
+ (auth_gsasl_options_block *)(ablock->options_block);
+struct callback_exim_state cb_state;
+int rc, auth_result, exim_error, exim_error_override;
+
+HDEBUG(D_auth)
+ debug_printf("GNU SASL: initialising session for %s, mechanism %s.\n",
+ ablock->name, ob->server_mech);
+
+rc = gsasl_server_start(gsasl_ctx, CCS ob->server_mech, &sctx);
+if (rc != GSASL_OK)
+ {
+ auth_defer_msg = string_sprintf("GNU SASL: session start failure: %s (%s)",
+ gsasl_strerror_name(rc), gsasl_strerror(rc));
+ HDEBUG(D_auth) debug_printf("%s\n", auth_defer_msg);
+ return DEFER;
}
- /* Hereafter: gsasl_finish(sctx) please */
-
- gsasl_session_hook_set(sctx, (void *)ablock);
- cb_state.ablock = ablock;
- cb_state.currently = CURRENTLY_SERVER;
- gsasl_session_hook_set(sctx, (void *)&cb_state);
-
- tmps = CS expand_string(ob->server_service);
- gsasl_property_set(sctx, GSASL_SERVICE, tmps);
- tmps = CS expand_string(ob->server_hostname);
- gsasl_property_set(sctx, GSASL_HOSTNAME, tmps);
- if (ob->server_realm) {
- tmps = CS expand_string(ob->server_realm);
- if (tmps && *tmps) {
- gsasl_property_set(sctx, GSASL_REALM, tmps);
- }
+/* Hereafter: gsasl_finish(sctx) please */
+
+gsasl_session_hook_set(sctx, (void *)ablock);
+cb_state.ablock = ablock;
+cb_state.currently = CURRENTLY_SERVER;
+gsasl_session_hook_set(sctx, (void *)&cb_state);
+
+tmps = CS expand_string(ob->server_service);
+gsasl_property_set(sctx, GSASL_SERVICE, tmps);
+tmps = CS expand_string(ob->server_hostname);
+gsasl_property_set(sctx, GSASL_HOSTNAME, tmps);
+if (ob->server_realm)
+ {
+ tmps = CS expand_string(ob->server_realm);
+ if (tmps && *tmps)
+ gsasl_property_set(sctx, GSASL_REALM, tmps);
}
- /* We don't support protection layers. */
- gsasl_property_set(sctx, GSASL_QOPS, "qop-auth");
+/* We don't support protection layers. */
+gsasl_property_set(sctx, GSASL_QOPS, "qop-auth");
#ifdef SUPPORT_TLS
- if (tls_channelbinding_b64) {
- /* Some auth mechanisms can ensure that both sides are talking within the
- same security context; for TLS, this means that even if a bad certificate
- has been accepted, they remain MitM-proof because both sides must be within
- the same negotiated session; if someone is terminating one session and
- proxying data on within a second, authentication will fail.
-
- We might not have this available, depending upon TLS implementation,
- ciphersuite, phase of moon ...
-
- If we do, it results in extra SASL mechanisms being available; here,
- Exim's one-mechanism-per-authenticator potentially causes problems.
- It depends upon how GNU SASL will implement the PLUS variants of GS2
- and whether it automatically mandates a switch to the bound PLUS
- if the data is available. Since default-on, despite being more secure,
- would then result in mechanism name changes on a library update, we
- have little choice but to default it off and let the admin choose to
- enable it. *sigh*
- */
- if (ob->server_channelbinding) {
- HDEBUG(D_auth) debug_printf("Auth %s: Enabling channel-binding\n",
- ablock->name);
- gsasl_property_set(sctx, GSASL_CB_TLS_UNIQUE,
- CCS tls_channelbinding_b64);
- } else {
- HDEBUG(D_auth)
- debug_printf("Auth %s: Not enabling channel-binding (data available)\n",
- ablock->name);
+if (tls_channelbinding_b64)
+ {
+ /* Some auth mechanisms can ensure that both sides are talking withing the
+ same security context; for TLS, this means that even if a bad certificate
+ has been accepted, they remain MitM-proof because both sides must be within
+ the same negotiated session; if someone is terminating one session and
+ proxying data on within a second, authentication will fail.
+
+ We might not have this available, depending upon TLS implementation,
+ ciphersuite, phase of moon ...
+
+ If we do, it results in extra SASL mechanisms being available; here,
+ Exim's one-mechanism-per-authenticator potentially causes problems.
+ It depends upon how GNU SASL will implement the PLUS variants of GS2
+ and whether it automatically mandates a switch to the bound PLUS
+ if the data is available. Since default-on, despite being more secure,
+ would then result in mechanism name changes on a library update, we
+ have little choice but to default it off and let the admin choose to
+ enable it. *sigh*
+ */
+ if (ob->server_channelbinding)
+ {
+ HDEBUG(D_auth) debug_printf("Auth %s: Enabling channel-binding\n",
+ ablock->name);
+ gsasl_property_set(sctx, GSASL_CB_TLS_UNIQUE,
+ CCS tls_channelbinding_b64);
}
- } else {
+ else
+ {
HDEBUG(D_auth)
- debug_printf("Auth %s: no channel-binding data available\n",
- ablock->name);
+ debug_printf("Auth %s: Not enabling channel-binding (data available)\n",
+ ablock->name);
+ }
}
+else
+ HDEBUG(D_auth)
+ debug_printf("Auth %s: no channel-binding data available\n",
+ ablock->name);
#endif
- checked_server_condition = FALSE;
-
- received = CS initial_data;
- to_send = NULL;
- exim_error = exim_error_override = OK;
-
- do {
- rc = gsasl_step64(sctx, received, &to_send);
-
- switch (rc) {
- case GSASL_OK:
- if (!to_send)
- goto STOP_INTERACTION;
- break;
-
- case GSASL_NEEDS_MORE:
- break;
-
- case GSASL_AUTHENTICATION_ERROR:
- case GSASL_INTEGRITY_ERROR:
- case GSASL_NO_AUTHID:
- case GSASL_NO_ANONYMOUS_TOKEN:
- case GSASL_NO_AUTHZID:
- case GSASL_NO_PASSWORD:
- case GSASL_NO_PASSCODE:
- case GSASL_NO_PIN:
- case GSASL_BASE64_ERROR:
- HDEBUG(D_auth) debug_printf("GNU SASL permanent error: %s (%s)\n",
- gsasl_strerror_name(rc), gsasl_strerror(rc));
- log_write(0, LOG_REJECT, "%s authenticator (%s):\n "
- "GNU SASL permanent failure: %s (%s)",
- ablock->name, ob->server_mech,
- gsasl_strerror_name(rc), gsasl_strerror(rc));
- if (rc == GSASL_BASE64_ERROR)
- exim_error_override = BAD64;
- goto STOP_INTERACTION;
-
- default:
- auth_defer_msg = string_sprintf("GNU SASL temporary error: %s (%s)",
- gsasl_strerror_name(rc), gsasl_strerror(rc));
- HDEBUG(D_auth) debug_printf("%s\n", auth_defer_msg);
- exim_error_override = DEFER;
- goto STOP_INTERACTION;
+checked_server_condition = FALSE;
+
+received = CS initial_data;
+to_send = NULL;
+exim_error = exim_error_override = OK;
+
+do {
+ rc = gsasl_step64(sctx, received, &to_send);
+
+ switch (rc)
+ {
+ case GSASL_OK:
+ if (!to_send)
+ goto STOP_INTERACTION;
+ break;
+
+ case GSASL_NEEDS_MORE:
+ break;
+
+ case GSASL_AUTHENTICATION_ERROR:
+ case GSASL_INTEGRITY_ERROR:
+ case GSASL_NO_AUTHID:
+ case GSASL_NO_ANONYMOUS_TOKEN:
+ case GSASL_NO_AUTHZID:
+ case GSASL_NO_PASSWORD:
+ case GSASL_NO_PASSCODE:
+ case GSASL_NO_PIN:
+ case GSASL_BASE64_ERROR:
+ HDEBUG(D_auth) debug_printf("GNU SASL permanent error: %s (%s)\n",
+ gsasl_strerror_name(rc), gsasl_strerror(rc));
+ log_write(0, LOG_REJECT, "%s authenticator (%s):\n "
+ "GNU SASL permanent failure: %s (%s)",
+ ablock->name, ob->server_mech,
+ gsasl_strerror_name(rc), gsasl_strerror(rc));
+ if (rc == GSASL_BASE64_ERROR)
+ exim_error_override = BAD64;
+ goto STOP_INTERACTION;
+
+ default:
+ auth_defer_msg = string_sprintf("GNU SASL temporary error: %s (%s)",
+ gsasl_strerror_name(rc), gsasl_strerror(rc));
+ HDEBUG(D_auth) debug_printf("%s\n", auth_defer_msg);
+ exim_error_override = DEFER;
+ goto STOP_INTERACTION;
}
- if ((rc == GSASL_NEEDS_MORE) ||
- (to_send && *to_send))
- exim_error =
- auth_get_no64_data((uschar **)&received, US to_send);
+ if ((rc == GSASL_NEEDS_MORE) ||
+ (to_send && *to_send))
+ exim_error =
+ auth_get_no64_data((uschar **)&received, US to_send);
- if (to_send) {
- free(to_send);
- to_send = NULL;
+ if (to_send)
+ {
+ free(to_send);
+ to_send = NULL;
}
- if (exim_error)
- break; /* handles * cancelled check */
+ if (exim_error)
+ break; /* handles * cancelled check */
} while (rc == GSASL_NEEDS_MORE);
STOP_INTERACTION:
- auth_result = rc;
+auth_result = rc;
- gsasl_finish(sctx);
+gsasl_finish(sctx);
- /* Can return: OK DEFER FAIL CANCELLED BAD64 UNEXPECTED */
+/* Can return: OK DEFER FAIL CANCELLED BAD64 UNEXPECTED */
- if (exim_error != OK)
- return exim_error;
+if (exim_error != OK)
+ return exim_error;
- if (auth_result != GSASL_OK) {
- HDEBUG(D_auth) debug_printf("authentication returned %s (%s)\n",
- gsasl_strerror_name(auth_result), gsasl_strerror(auth_result));
- if (exim_error_override != OK)
- return exim_error_override; /* might be DEFER */
- if (sasl_error_should_defer) /* overriding auth failure SASL error */
- return DEFER;
- return FAIL;
+if (auth_result != GSASL_OK)
+ {
+ HDEBUG(D_auth) debug_printf("authentication returned %s (%s)\n",
+ gsasl_strerror_name(auth_result), gsasl_strerror(auth_result));
+ if (exim_error_override != OK)
+ return exim_error_override; /* might be DEFER */
+ if (sasl_error_should_defer) /* overriding auth failure SASL error */
+ return DEFER;
+ return FAIL;
}
- /* Auth succeeded, check server_condition unless already done in callback */
- return checked_server_condition ? OK : auth_check_serv_cond(ablock);
+/* Auth succeeded, check server_condition unless already done in callback */
+return checked_server_condition ? OK : auth_check_serv_cond(ablock);
}
+
/* returns the GSASL status of expanding the Exim string given */
static int
condition_check(auth_instance *ablock, uschar *label, uschar *condition_string)
{
- int exim_rc;
+int exim_rc;
- exim_rc = auth_check_some_cond(ablock, label, condition_string, FAIL);
+exim_rc = auth_check_some_cond(ablock, label, condition_string, FAIL);
- if (exim_rc == OK) {
- return GSASL_OK;
- } else if (exim_rc == DEFER) {
- sasl_error_should_defer = TRUE;
- return GSASL_AUTHENTICATION_ERROR;
- } else if (exim_rc == FAIL) {
- return GSASL_AUTHENTICATION_ERROR;
+if (exim_rc == OK)
+ return GSASL_OK;
+else if (exim_rc == DEFER)
+ {
+ sasl_error_should_defer = TRUE;
+ return GSASL_AUTHENTICATION_ERROR;
}
-
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
- "Unhandled return from checking %s: %d",
- ablock->name, label, exim_rc);
- /* NOTREACHED */
+else if (exim_rc == FAIL)
return GSASL_AUTHENTICATION_ERROR;
+
+log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
+ "Unhandled return from checking %s: %d",
+ ablock->name, label, exim_rc);
+/* NOTREACHED */
+return GSASL_AUTHENTICATION_ERROR;
}
static int
server_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop, auth_instance *ablock)
{
- char *tmps;
- uschar *propval;
- int cbrc = GSASL_NO_CALLBACK;
- int i;
- auth_gsasl_options_block *ob =
- (auth_gsasl_options_block *)(ablock->options_block);
-
- HDEBUG(D_auth)
- debug_printf("GNU SASL callback %d for %s/%s as server\n",
- prop, ablock->name, ablock->public_name);
-
- for (i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL;
- expand_nmax = 0;
-
- switch (prop) {
- case GSASL_VALIDATE_SIMPLE:
- /* GSASL_AUTHID, GSASL_AUTHZID, and GSASL_PASSWORD */
- propval = US gsasl_property_fast(sctx, GSASL_AUTHID);
- auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
- propval = US gsasl_property_fast(sctx, GSASL_AUTHZID);
- auth_vars[1] = expand_nstring[2] = propval ? propval : US"";
- propval = US gsasl_property_fast(sctx, GSASL_PASSWORD);
- auth_vars[2] = expand_nstring[3] = propval ? propval : US"";
- expand_nmax = 3;
- for (i = 1; i <= 3; ++i)
- expand_nlength[i] = Ustrlen(expand_nstring[i]);
-
- cbrc = condition_check(ablock, US"server_condition", ablock->server_condition);
- checked_server_condition = TRUE;
+char *tmps;
+uschar *propval;
+int cbrc = GSASL_NO_CALLBACK;
+auth_gsasl_options_block *ob =
+ (auth_gsasl_options_block *)(ablock->options_block);
+
+HDEBUG(D_auth)
+ debug_printf("GNU SASL callback %d for %s/%s as server\n",
+ prop, ablock->name, ablock->public_name);
+
+for (int i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL;
+expand_nmax = 0;
+
+switch (prop)
+ {
+ case GSASL_VALIDATE_SIMPLE:
+ /* GSASL_AUTHID, GSASL_AUTHZID, and GSASL_PASSWORD */
+ propval = US gsasl_property_fast(sctx, GSASL_AUTHID);
+ auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
+ propval = US gsasl_property_fast(sctx, GSASL_AUTHZID);
+ auth_vars[1] = expand_nstring[2] = propval ? propval : US"";
+ propval = US gsasl_property_fast(sctx, GSASL_PASSWORD);
+ auth_vars[2] = expand_nstring[3] = propval ? propval : US"";
+ expand_nmax = 3;
+ for (int i = 1; i <= 3; ++i)
+ expand_nlength[i] = Ustrlen(expand_nstring[i]);
+
+ cbrc = condition_check(ablock, US"server_condition", ablock->server_condition);
+ checked_server_condition = TRUE;
+ break;
+
+ case GSASL_VALIDATE_EXTERNAL:
+ if (ablock->server_condition == NULL)
+ {
+ HDEBUG(D_auth) debug_printf("No server_condition supplied, to validate EXTERNAL.\n");
+ cbrc = GSASL_AUTHENTICATION_ERROR;
break;
-
- case GSASL_VALIDATE_EXTERNAL:
- if (ablock->server_condition == NULL) {
- HDEBUG(D_auth) debug_printf("No server_condition supplied, to validate EXTERNAL.\n");
- cbrc = GSASL_AUTHENTICATION_ERROR;
- break;
}
- propval = US gsasl_property_fast(sctx, GSASL_AUTHZID);
- /* We always set $auth1, even if only to empty string. */
- auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
- expand_nlength[1] = Ustrlen(expand_nstring[1]);
- expand_nmax = 1;
-
- cbrc = condition_check(ablock,
- US"server_condition (EXTERNAL)", ablock->server_condition);
- checked_server_condition = TRUE;
+ propval = US gsasl_property_fast(sctx, GSASL_AUTHZID);
+ /* We always set $auth1, even if only to empty string. */
+ auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
+ expand_nlength[1] = Ustrlen(expand_nstring[1]);
+ expand_nmax = 1;
+
+ cbrc = condition_check(ablock,
+ US"server_condition (EXTERNAL)", ablock->server_condition);
+ checked_server_condition = TRUE;
+ break;
+
+ case GSASL_VALIDATE_ANONYMOUS:
+ if (ablock->server_condition == NULL)
+ {
+ HDEBUG(D_auth) debug_printf("No server_condition supplied, to validate ANONYMOUS.\n");
+ cbrc = GSASL_AUTHENTICATION_ERROR;
break;
-
- case GSASL_VALIDATE_ANONYMOUS:
- if (ablock->server_condition == NULL) {
- HDEBUG(D_auth) debug_printf("No server_condition supplied, to validate ANONYMOUS.\n");
- cbrc = GSASL_AUTHENTICATION_ERROR;
- break;
}
- propval = US gsasl_property_fast(sctx, GSASL_ANONYMOUS_TOKEN);
- /* We always set $auth1, even if only to empty string. */
- auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
- expand_nlength[1] = Ustrlen(expand_nstring[1]);
- expand_nmax = 1;
-
- cbrc = condition_check(ablock,
- US"server_condition (ANONYMOUS)", ablock->server_condition);
- checked_server_condition = TRUE;
- break;
-
- case GSASL_VALIDATE_GSSAPI:
- /* GSASL_AUTHZID and GSASL_GSSAPI_DISPLAY_NAME
- The display-name is authenticated as part of GSS, the authzid is claimed
- by the SASL integration after authentication; protected against tampering
- (if the SASL mechanism supports that, which Kerberos does) but is
- unverified, same as normal for other mechanisms.
-
- First coding, we had these values swapped, but for consistency and prior
- to the first release of Exim with this authenticator, they've been
- switched to match the ordering of GSASL_VALIDATE_SIMPLE. */
- propval = US gsasl_property_fast(sctx, GSASL_GSSAPI_DISPLAY_NAME);
- auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
- propval = US gsasl_property_fast(sctx, GSASL_AUTHZID);
- auth_vars[1] = expand_nstring[2] = propval ? propval : US"";
- expand_nmax = 2;
- for (i = 1; i <= 2; ++i)
- expand_nlength[i] = Ustrlen(expand_nstring[i]);
-
- /* In this one case, it perhaps makes sense to default back open?
- But for consistency, let's just mandate server_condition here too. */
- cbrc = condition_check(ablock,
- US"server_condition (GSSAPI family)", ablock->server_condition);
- checked_server_condition = TRUE;
- break;
-
- case GSASL_PASSWORD:
- /* DIGEST-MD5: GSASL_AUTHID, GSASL_AUTHZID and GSASL_REALM
- CRAM-MD5: GSASL_AUTHID
- PLAIN: GSASL_AUTHID and GSASL_AUTHZID
- LOGIN: GSASL_AUTHID
- */
- if (ob->server_scram_iter) {
- tmps = CS expand_string(ob->server_scram_iter);
- gsasl_property_set(sctx, GSASL_SCRAM_ITER, tmps);
+ propval = US gsasl_property_fast(sctx, GSASL_ANONYMOUS_TOKEN);
+ /* We always set $auth1, even if only to empty string. */
+ auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
+ expand_nlength[1] = Ustrlen(expand_nstring[1]);
+ expand_nmax = 1;
+
+ cbrc = condition_check(ablock,
+ US"server_condition (ANONYMOUS)", ablock->server_condition);
+ checked_server_condition = TRUE;
+ break;
+
+ case GSASL_VALIDATE_GSSAPI:
+ /* GSASL_AUTHZID and GSASL_GSSAPI_DISPLAY_NAME
+ The display-name is authenticated as part of GSS, the authzid is claimed
+ by the SASL integration after authentication; protected against tampering
+ (if the SASL mechanism supports that, which Kerberos does) but is
+ unverified, same as normal for other mechanisms.
+
+ First coding, we had these values swapped, but for consistency and prior
+ to the first release of Exim with this authenticator, they've been
+ switched to match the ordering of GSASL_VALIDATE_SIMPLE. */
+ propval = US gsasl_property_fast(sctx, GSASL_GSSAPI_DISPLAY_NAME);
+ auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
+ propval = US gsasl_property_fast(sctx, GSASL_AUTHZID);
+ auth_vars[1] = expand_nstring[2] = propval ? propval : US"";
+ expand_nmax = 2;
+ for (int i = 1; i <= 2; ++i)
+ expand_nlength[i] = Ustrlen(expand_nstring[i]);
+
+ /* In this one case, it perhaps makes sense to default back open?
+ But for consistency, let's just mandate server_condition here too. */
+ cbrc = condition_check(ablock,
+ US"server_condition (GSSAPI family)", ablock->server_condition);
+ checked_server_condition = TRUE;
+ break;
+
+ case GSASL_PASSWORD:
+ /* DIGEST-MD5: GSASL_AUTHID, GSASL_AUTHZID and GSASL_REALM
+ CRAM-MD5: GSASL_AUTHID
+ PLAIN: GSASL_AUTHID and GSASL_AUTHZID
+ LOGIN: GSASL_AUTHID
+ */
+ if (ob->server_scram_iter)
+ {
+ tmps = CS expand_string(ob->server_scram_iter);
+ gsasl_property_set(sctx, GSASL_SCRAM_ITER, tmps);
}
- if (ob->server_scram_salt) {
- tmps = CS expand_string(ob->server_scram_salt);
- gsasl_property_set(sctx, GSASL_SCRAM_SALT, tmps);
+ if (ob->server_scram_salt)
+ {
+ tmps = CS expand_string(ob->server_scram_salt);
+ gsasl_property_set(sctx, GSASL_SCRAM_SALT, tmps);
}
- /* Asking for GSASL_AUTHZID calls back into us if we use
- gsasl_property_get(), thus the use of gsasl_property_fast().
- Do we really want to hardcode limits per mechanism? What happens when
- a new mechanism is added to the library. It *shouldn't* result in us
- needing to add more glue, since avoiding that is a large part of the
- point of SASL. */
- propval = US gsasl_property_fast(sctx, GSASL_AUTHID);
- auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
- propval = US gsasl_property_fast(sctx, GSASL_AUTHZID);
- auth_vars[1] = expand_nstring[2] = propval ? propval : US"";
- propval = US gsasl_property_fast(sctx, GSASL_REALM);
- auth_vars[2] = expand_nstring[3] = propval ? propval : US"";
- expand_nmax = 3;
- for (i = 1; i <= 3; ++i)
- expand_nlength[i] = Ustrlen(expand_nstring[i]);
-
- tmps = CS expand_string(ob->server_password);
- if (tmps == NULL) {
- sasl_error_should_defer = f.expand_string_forcedfail ? FALSE : TRUE;
- HDEBUG(D_auth) debug_printf("server_password expansion failed, so "
- "can't tell GNU SASL library the password for %s\n", auth_vars[0]);
- return GSASL_AUTHENTICATION_ERROR;
+ /* Asking for GSASL_AUTHZID calls back into us if we use
+ gsasl_property_get(), thus the use of gsasl_property_fast().
+ Do we really want to hardcode limits per mechanism? What happens when
+ a new mechanism is added to the library. It *shouldn't* result in us
+ needing to add more glue, since avoiding that is a large part of the
+ point of SASL. */
+ propval = US gsasl_property_fast(sctx, GSASL_AUTHID);
+ auth_vars[0] = expand_nstring[1] = propval ? propval : US"";
+ propval = US gsasl_property_fast(sctx, GSASL_AUTHZID);
+ auth_vars[1] = expand_nstring[2] = propval ? propval : US"";
+ propval = US gsasl_property_fast(sctx, GSASL_REALM);
+ auth_vars[2] = expand_nstring[3] = propval ? propval : US"";
+ expand_nmax = 3;
+ for (int i = 1; i <= 3; ++i)
+ expand_nlength[i] = Ustrlen(expand_nstring[i]);
+
+ tmps = CS expand_string(ob->server_password);
+ if (tmps == NULL)
+ {
+ sasl_error_should_defer = f.expand_string_forcedfail ? FALSE : TRUE;
+ HDEBUG(D_auth) debug_printf("server_password expansion failed, so "
+ "can't tell GNU SASL library the password for %s\n", auth_vars[0]);
+ return GSASL_AUTHENTICATION_ERROR;
}
- gsasl_property_set(sctx, GSASL_PASSWORD, tmps);
- /* This is inadequate; don't think Exim's store stacks are geared
- for memory wiping, so expanding strings will leave stuff laying around.
- But no need to compound the problem, so get rid of the one we can. */
- memset(tmps, '\0', strlen(tmps));
- cbrc = GSASL_OK;
- break;
-
- default:
- HDEBUG(D_auth) debug_printf("Unrecognised callback: %d\n", prop);
- cbrc = GSASL_NO_CALLBACK;
+ gsasl_property_set(sctx, GSASL_PASSWORD, tmps);
+ /* This is inadequate; don't think Exim's store stacks are geared
+ for memory wiping, so expanding strings will leave stuff laying around.
+ But no need to compound the problem, so get rid of the one we can. */
+ memset(tmps, '\0', strlen(tmps));
+ cbrc = GSASL_OK;
+ break;
+
+ default:
+ HDEBUG(D_auth) debug_printf("Unrecognised callback: %d\n", prop);
+ cbrc = GSASL_NO_CALLBACK;
}
- HDEBUG(D_auth) debug_printf("Returning %s (%s)\n",
- gsasl_strerror_name(cbrc), gsasl_strerror(cbrc));
+HDEBUG(D_auth) debug_printf("Returning %s (%s)\n",
+ gsasl_strerror_name(cbrc), gsasl_strerror(cbrc));
- return cbrc;
+return cbrc;
}
uschar *buffer, /* buffer for reading response */
int buffsize) /* size of buffer */
{
- HDEBUG(D_auth)
- debug_printf("Client side NOT IMPLEMENTED: you should not see this!\n");
- /* NOT IMPLEMENTED */
- return FAIL;
+HDEBUG(D_auth)
+ debug_printf("Client side NOT IMPLEMENTED: you should not see this!\n");
+/* NOT IMPLEMENTED */
+return FAIL;
}
static int
client_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop, auth_instance *ablock)
{
- int cbrc = GSASL_NO_CALLBACK;
- HDEBUG(D_auth)
- debug_printf("GNU SASL callback %d for %s/%s as client\n",
- prop, ablock->name, ablock->public_name);
+int cbrc = GSASL_NO_CALLBACK;
+HDEBUG(D_auth)
+ debug_printf("GNU SASL callback %d for %s/%s as client\n",
+ prop, ablock->name, ablock->public_name);
- HDEBUG(D_auth)
- debug_printf("Client side NOT IMPLEMENTED: you should not see this!\n");
+HDEBUG(D_auth)
+ debug_printf("Client side NOT IMPLEMENTED: you should not see this!\n");
- return cbrc;
+return cbrc;
}
/*************************************************
void
auth_gsasl_version_report(FILE *f)
{
- const char *runtime;
- runtime = gsasl_check_version(NULL);
- fprintf(f, "Library version: GNU SASL: Compile: %s\n"
- " Runtime: %s\n",
- GSASL_VERSION, runtime);
+const char *runtime;
+runtime = gsasl_check_version(NULL);
+fprintf(f, "Library version: GNU SASL: Compile: %s\n"
+ " Runtime: %s\n",
+ GSASL_VERSION, runtime);
}
#endif /*!MACRO_PREDEF*/
void
auth_heimdal_gssapi_init(auth_instance *ablock)
{
- krb5_context context;
- krb5_keytab keytab;
- krb5_kt_cursor cursor;
- krb5_keytab_entry entry;
- krb5_error_code krc;
- char *principal, *enctype_s;
- const char *k_keytab_typed_name = NULL;
- auth_heimdal_gssapi_options_block *ob =
- (auth_heimdal_gssapi_options_block *)(ablock->options_block);
-
- ablock->server = FALSE;
- ablock->client = FALSE;
-
- if (!ob->server_service || !*ob->server_service) {
- HDEBUG(D_auth) debug_printf("heimdal: missing server_service\n");
- return;
- }
+krb5_context context;
+krb5_keytab keytab;
+krb5_kt_cursor cursor;
+krb5_keytab_entry entry;
+krb5_error_code krc;
+char *principal, *enctype_s;
+const char *k_keytab_typed_name = NULL;
+auth_heimdal_gssapi_options_block *ob =
+ (auth_heimdal_gssapi_options_block *)(ablock->options_block);
+
+ablock->server = FALSE;
+ablock->client = FALSE;
+
+if (!ob->server_service || !*ob->server_service)
+ {
+ HDEBUG(D_auth) debug_printf("heimdal: missing server_service\n");
+ return;
+}
- krc = krb5_init_context(&context);
- if (krc != 0) {
- int kerr = errno;
- HDEBUG(D_auth) debug_printf("heimdal: failed to initialise krb5 context: %s\n",
- strerror(kerr));
- return;
+krc = krb5_init_context(&context);
+if (krc != 0)
+ {
+ int kerr = errno;
+ HDEBUG(D_auth) debug_printf("heimdal: failed to initialise krb5 context: %s\n",
+ strerror(kerr));
+ return;
}
- if (ob->server_keytab) {
- k_keytab_typed_name = CCS string_sprintf("file:%s", expand_string(ob->server_keytab));
- HDEBUG(D_auth) debug_printf("heimdal: using keytab %s\n", k_keytab_typed_name);
- krc = krb5_kt_resolve(context, k_keytab_typed_name, &keytab);
- if (krc) {
- HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_resolve", context, krc);
- return;
+if (ob->server_keytab)
+ {
+ k_keytab_typed_name = CCS string_sprintf("file:%s", expand_string(ob->server_keytab));
+ HDEBUG(D_auth) debug_printf("heimdal: using keytab %s\n", k_keytab_typed_name);
+ krc = krb5_kt_resolve(context, k_keytab_typed_name, &keytab);
+ if (krc)
+ {
+ HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_resolve", context, krc);
+ return;
}
- } else {
- HDEBUG(D_auth) debug_printf("heimdal: using system default keytab\n");
- krc = krb5_kt_default(context, &keytab);
- if (krc) {
- HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_default", context, krc);
- return;
+ }
+else
+ {
+ HDEBUG(D_auth) debug_printf("heimdal: using system default keytab\n");
+ krc = krb5_kt_default(context, &keytab);
+ if (krc)
+ {
+ HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_default", context, krc);
+ return;
}
}
- HDEBUG(D_auth) {
- /* http://www.h5l.org/manual/HEAD/krb5/krb5_keytab_intro.html */
- krc = krb5_kt_start_seq_get(context, keytab, &cursor);
- if (krc)
- exim_heimdal_error_debug("krb5_kt_start_seq_get", context, krc);
- else {
- while ((krc = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
- principal = enctype_s = NULL;
- krb5_unparse_name(context, entry.principal, &principal);
- krb5_enctype_to_string(context, entry.keyblock.keytype, &enctype_s);
- debug_printf("heimdal: keytab principal: %s vno=%d type=%s\n",
- principal ? principal : "??",
- entry.vno,
- enctype_s ? enctype_s : "??");
- free(principal);
- free(enctype_s);
- krb5_kt_free_entry(context, &entry);
+HDEBUG(D_auth)
+ {
+ /* http://www.h5l.org/manual/HEAD/krb5/krb5_keytab_intro.html */
+ krc = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if (krc)
+ exim_heimdal_error_debug("krb5_kt_start_seq_get", context, krc);
+ else
+ {
+ while ((krc = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0)
+ {
+ principal = enctype_s = NULL;
+ krb5_unparse_name(context, entry.principal, &principal);
+ krb5_enctype_to_string(context, entry.keyblock.keytype, &enctype_s);
+ debug_printf("heimdal: keytab principal: %s vno=%d type=%s\n",
+ principal ? principal : "??",
+ entry.vno,
+ enctype_s ? enctype_s : "??");
+ free(principal);
+ free(enctype_s);
+ krb5_kt_free_entry(context, &entry);
}
- krc = krb5_kt_end_seq_get(context, keytab, &cursor);
- if (krc)
- exim_heimdal_error_debug("krb5_kt_end_seq_get", context, krc);
+ krc = krb5_kt_end_seq_get(context, keytab, &cursor);
+ if (krc)
+ exim_heimdal_error_debug("krb5_kt_end_seq_get", context, krc);
}
}
- krc = krb5_kt_close(context, keytab);
- if (krc)
- HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_close", context, krc);
+krc = krb5_kt_close(context, keytab);
+if (krc)
+ HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_close", context, krc);
- krb5_free_context(context);
+krb5_free_context(context);
- /* RFC 4121 section 5.2, SHOULD support 64K input buffers */
- if (big_buffer_size < (64 * 1024)) {
- uschar *newbuf;
- big_buffer_size = 64 * 1024;
- newbuf = store_malloc(big_buffer_size);
- store_free(big_buffer);
- big_buffer = newbuf;
+/* RFC 4121 section 5.2, SHOULD support 64K input buffers */
+if (big_buffer_size < (64 * 1024))
+ {
+ uschar *newbuf;
+ big_buffer_size = 64 * 1024;
+ newbuf = store_malloc(big_buffer_size);
+ store_free(big_buffer);
+ big_buffer = newbuf;
}
- ablock->server = TRUE;
+ablock->server = TRUE;
}
exim_heimdal_error_debug(const char *label,
krb5_context context, krb5_error_code err)
{
- const char *kerrsc;
- kerrsc = krb5_get_error_message(context, err);
- debug_printf("heimdal %s: %s\n", label, kerrsc ? kerrsc : "unknown error");
- krb5_free_error_message(context, kerrsc);
+const char *kerrsc;
+kerrsc = krb5_get_error_message(context, err);
+debug_printf("heimdal %s: %s\n", label, kerrsc ? kerrsc : "unknown error");
+krb5_free_error_message(context, kerrsc);
}
/*************************************************
int
auth_heimdal_gssapi_server(auth_instance *ablock, uschar *initial_data)
{
- gss_name_t gclient = GSS_C_NO_NAME;
- gss_name_t gserver = GSS_C_NO_NAME;
- gss_cred_id_t gcred = GSS_C_NO_CREDENTIAL;
- gss_ctx_id_t gcontext = GSS_C_NO_CONTEXT;
- uschar *ex_server_str;
- gss_buffer_desc gbufdesc = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc gbufdesc_in = GSS_C_EMPTY_BUFFER;
- gss_buffer_desc gbufdesc_out = GSS_C_EMPTY_BUFFER;
- gss_OID mech_type;
- OM_uint32 maj_stat, min_stat;
- int step, error_out, i;
- uschar *tmp1, *tmp2, *from_client;
- auth_heimdal_gssapi_options_block *ob =
- (auth_heimdal_gssapi_options_block *)(ablock->options_block);
- BOOL handled_empty_ir;
- uschar *store_reset_point;
- uschar *keytab;
- uschar sasl_config[4];
- uschar requested_qop;
-
- store_reset_point = store_get(0);
-
- HDEBUG(D_auth)
- debug_printf("heimdal: initialising auth context for %s\n", ablock->name);
-
- /* Construct our gss_name_t gserver describing ourselves */
- tmp1 = expand_string(ob->server_service);
- tmp2 = expand_string(ob->server_hostname);
- ex_server_str = string_sprintf("%s@%s", tmp1, tmp2);
- gbufdesc.value = (void *) ex_server_str;
- gbufdesc.length = Ustrlen(ex_server_str);
- maj_stat = gss_import_name(&min_stat,
- &gbufdesc, GSS_C_NT_HOSTBASED_SERVICE, &gserver);
+gss_name_t gclient = GSS_C_NO_NAME;
+gss_name_t gserver = GSS_C_NO_NAME;
+gss_cred_id_t gcred = GSS_C_NO_CREDENTIAL;
+gss_ctx_id_t gcontext = GSS_C_NO_CONTEXT;
+uschar *ex_server_str;
+gss_buffer_desc gbufdesc = GSS_C_EMPTY_BUFFER;
+gss_buffer_desc gbufdesc_in = GSS_C_EMPTY_BUFFER;
+gss_buffer_desc gbufdesc_out = GSS_C_EMPTY_BUFFER;
+gss_OID mech_type;
+OM_uint32 maj_stat, min_stat;
+int step, error_out;
+uschar *tmp1, *tmp2, *from_client;
+auth_heimdal_gssapi_options_block *ob =
+ (auth_heimdal_gssapi_options_block *)(ablock->options_block);
+BOOL handled_empty_ir;
+uschar *store_reset_point;
+uschar *keytab;
+uschar sasl_config[4];
+uschar requested_qop;
+
+store_reset_point = store_get(0);
+
+HDEBUG(D_auth)
+ debug_printf("heimdal: initialising auth context for %s\n", ablock->name);
+
+/* Construct our gss_name_t gserver describing ourselves */
+tmp1 = expand_string(ob->server_service);
+tmp2 = expand_string(ob->server_hostname);
+ex_server_str = string_sprintf("%s@%s", tmp1, tmp2);
+gbufdesc.value = (void *) ex_server_str;
+gbufdesc.length = Ustrlen(ex_server_str);
+maj_stat = gss_import_name(&min_stat,
+ &gbufdesc, GSS_C_NT_HOSTBASED_SERVICE, &gserver);
+if (GSS_ERROR(maj_stat))
+ return exim_gssapi_error_defer(store_reset_point, maj_stat, min_stat,
+ "gss_import_name(%s)", CS gbufdesc.value);
+
+/* Use a specific keytab, if specified */
+if (ob->server_keytab)
+ {
+ keytab = expand_string(ob->server_keytab);
+ maj_stat = gsskrb5_register_acceptor_identity(CCS keytab);
if (GSS_ERROR(maj_stat))
return exim_gssapi_error_defer(store_reset_point, maj_stat, min_stat,
- "gss_import_name(%s)", CS gbufdesc.value);
-
- /* Use a specific keytab, if specified */
- if (ob->server_keytab) {
- keytab = expand_string(ob->server_keytab);
- maj_stat = gsskrb5_register_acceptor_identity(CCS keytab);
- if (GSS_ERROR(maj_stat))
- return exim_gssapi_error_defer(store_reset_point, maj_stat, min_stat,
- "registering keytab \"%s\"", keytab);
- HDEBUG(D_auth)
- debug_printf("heimdal: using keytab \"%s\"\n", keytab);
+ "registering keytab \"%s\"", keytab);
+ HDEBUG(D_auth)
+ debug_printf("heimdal: using keytab \"%s\"\n", keytab);
}
- /* Acquire our credentials */
- maj_stat = gss_acquire_cred(&min_stat,
- gserver, /* desired name */
- 0, /* time */
- GSS_C_NULL_OID_SET, /* desired mechs */
- GSS_C_ACCEPT, /* cred usage */
- &gcred, /* handle */
- NULL /* actual mechs */,
- NULL /* time rec */);
- if (GSS_ERROR(maj_stat))
- return exim_gssapi_error_defer(store_reset_point, maj_stat, min_stat,
- "gss_acquire_cred(%s)", ex_server_str);
-
- maj_stat = gss_release_name(&min_stat, &gserver);
-
- HDEBUG(D_auth) debug_printf("heimdal: have server credentials.\n");
-
- /* Loop talking to client */
- step = 0;
- from_client = initial_data;
- handled_empty_ir = FALSE;
- error_out = OK;
-
- /* buffer sizes: auth_get_data() uses big_buffer, which we grow per
- GSSAPI RFC in _init, if needed, to meet the SHOULD size of 64KB.
- (big_buffer starts life at the MUST size of 16KB). */
-
- /* step values
- 0: getting initial data from client to feed into GSSAPI
- 1: iterating for as long as GSS_S_CONTINUE_NEEDED
- 2: GSS_S_COMPLETE, SASL wrapping for authz and qop to send to client
- 3: unpick final auth message from client
- 4: break/finish (non-step)
- */
- while (step < 4) {
- switch (step) {
- case 0:
- if (!from_client || *from_client == '\0') {
- if (handled_empty_ir) {
- HDEBUG(D_auth) debug_printf("gssapi: repeated empty input, grr.\n");
- error_out = BAD64;
- goto ERROR_OUT;
- } else {
- HDEBUG(D_auth) debug_printf("gssapi: missing initial response, nudging.\n");
- error_out = auth_get_data(&from_client, US"", 0);
- if (error_out != OK)
- goto ERROR_OUT;
- handled_empty_ir = TRUE;
- continue;
- }
- }
- /* We should now have the opening data from the client, base64-encoded. */
- step += 1;
- HDEBUG(D_auth) debug_printf("heimdal: have initial client data\n");
- break;
-
- case 1:
- gbufdesc_in.length = b64decode(from_client, USS &gbufdesc_in.value);
- if (gclient) {
- maj_stat = gss_release_name(&min_stat, &gclient);
- gclient = GSS_C_NO_NAME;
- }
- maj_stat = gss_accept_sec_context(&min_stat,
- &gcontext, /* context handle */
- gcred, /* acceptor cred handle */
- &gbufdesc_in, /* input from client */
- GSS_C_NO_CHANNEL_BINDINGS, /* XXX fixme: use the channel bindings from GnuTLS */
- &gclient, /* client identifier */
- &mech_type, /* mechanism in use */
- &gbufdesc_out, /* output to send to client */
- NULL, /* return flags */
- NULL, /* time rec */
- NULL /* delegated cred_handle */
- );
- if (GSS_ERROR(maj_stat)) {
- exim_gssapi_error_defer(NULL, maj_stat, min_stat,
- "gss_accept_sec_context()");
- error_out = FAIL;
- goto ERROR_OUT;
- }
- if (gbufdesc_out.length != 0) {
- error_out = auth_get_data(&from_client,
- gbufdesc_out.value, gbufdesc_out.length);
- if (error_out != OK)
- goto ERROR_OUT;
-
- gss_release_buffer(&min_stat, &gbufdesc_out);
- EmptyBuf(gbufdesc_out);
- }
- if (maj_stat == GSS_S_COMPLETE) {
- step += 1;
- HDEBUG(D_auth) debug_printf("heimdal: GSS complete\n");
- } else {
- HDEBUG(D_auth) debug_printf("heimdal: need more data\n");
- }
- break;
-
- case 2:
- memset(sasl_config, 0xFF, 4);
- /* draft-ietf-sasl-gssapi-06.txt defines bitmasks for first octet
- 0x01 No security layer
- 0x02 Integrity protection
- 0x04 Confidentiality protection
-
- The remaining three octets are the maximum buffer size for wrapped
- content. */
- sasl_config[0] = 0x01; /* Exim does not wrap/unwrap SASL layers after auth */
- gbufdesc.value = (void *) sasl_config;
- gbufdesc.length = 4;
- maj_stat = gss_wrap(&min_stat,
- gcontext,
- 0, /* conf_req_flag: integrity only */
- GSS_C_QOP_DEFAULT, /* qop requested */
- &gbufdesc, /* message to protect */
- NULL, /* conf_state: no confidentiality applied */
- &gbufdesc_out /* output buffer */
- );
- if (GSS_ERROR(maj_stat)) {
- exim_gssapi_error_defer(NULL, maj_stat, min_stat,
- "gss_wrap(SASL state after auth)");
- error_out = FAIL;
- goto ERROR_OUT;
- }
-
- HDEBUG(D_auth) debug_printf("heimdal SASL: requesting QOP with no security layers\n");
-
- error_out = auth_get_data(&from_client,
- gbufdesc_out.value, gbufdesc_out.length);
- if (error_out != OK)
- goto ERROR_OUT;
-
- gss_release_buffer(&min_stat, &gbufdesc_out);
- EmptyBuf(gbufdesc_out);
- step += 1;
- break;
-
- case 3:
- gbufdesc_in.length = b64decode(from_client, USS &gbufdesc_in.value);
- maj_stat = gss_unwrap(&min_stat,
- gcontext,
- &gbufdesc_in, /* data from client */
- &gbufdesc_out, /* results */
- NULL, /* conf state */
- NULL /* qop state */
- );
- if (GSS_ERROR(maj_stat)) {
- exim_gssapi_error_defer(NULL, maj_stat, min_stat,
- "gss_unwrap(final SASL message from client)");
- error_out = FAIL;
- goto ERROR_OUT;
- }
- if (gbufdesc_out.length < 4) {
- HDEBUG(D_auth)
- debug_printf("gssapi: final message too short; "
- "need flags, buf sizes and optional authzid\n");
- error_out = FAIL;
- goto ERROR_OUT;
- }
-
- requested_qop = (CS gbufdesc_out.value)[0];
- if ((requested_qop & 0x01) == 0) {
- HDEBUG(D_auth)
- debug_printf("gssapi: client requested security layers (%x)\n",
- (unsigned int) requested_qop);
- error_out = FAIL;
- goto ERROR_OUT;
- }
-
- for (i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL;
- expand_nmax = 0;
-
- /* Identifiers:
- The SASL provided identifier is an unverified authzid.
- GSSAPI provides us with a verified identifier, but it might be empty
- for some clients.
- */
-
- /* $auth2 is authzid requested at SASL layer */
- if (gbufdesc_out.length > 4) {
- expand_nlength[2] = gbufdesc_out.length - 4;
- auth_vars[1] = expand_nstring[2] =
- string_copyn((US gbufdesc_out.value) + 4, expand_nlength[2]);
- expand_nmax = 2;
- }
-
- gss_release_buffer(&min_stat, &gbufdesc_out);
- EmptyBuf(gbufdesc_out);
-
- /* $auth1 is GSSAPI display name */
- maj_stat = gss_display_name(&min_stat,
- gclient,
- &gbufdesc_out,
- &mech_type);
- if (GSS_ERROR(maj_stat)) {
- auth_vars[1] = expand_nstring[2] = NULL;
- expand_nmax = 0;
- exim_gssapi_error_defer(NULL, maj_stat, min_stat,
- "gss_display_name(client identifier)");
- error_out = FAIL;
- goto ERROR_OUT;
- }
-
- expand_nlength[1] = gbufdesc_out.length;
- auth_vars[0] = expand_nstring[1] =
- string_copyn(gbufdesc_out.value, gbufdesc_out.length);
-
- if (expand_nmax == 0) { /* should be: authzid was empty */
- expand_nmax = 2;
- expand_nlength[2] = expand_nlength[1];
- auth_vars[1] = expand_nstring[2] = string_copyn(expand_nstring[1], expand_nlength[1]);
- HDEBUG(D_auth)
- debug_printf("heimdal SASL: empty authzid, set to dup of GSSAPI display name\n");
- }
-
- HDEBUG(D_auth)
- debug_printf("heimdal SASL: happy with client request\n"
- " auth1 (verified GSSAPI display-name): \"%s\"\n"
- " auth2 (unverified SASL requested authzid): \"%s\"\n",
- auth_vars[0], auth_vars[1]);
-
- step += 1;
- break;
+/* Acquire our credentials */
+maj_stat = gss_acquire_cred(&min_stat,
+ gserver, /* desired name */
+ 0, /* time */
+ GSS_C_NULL_OID_SET, /* desired mechs */
+ GSS_C_ACCEPT, /* cred usage */
+ &gcred, /* handle */
+ NULL /* actual mechs */,
+ NULL /* time rec */);
+if (GSS_ERROR(maj_stat))
+ return exim_gssapi_error_defer(store_reset_point, maj_stat, min_stat,
+ "gss_acquire_cred(%s)", ex_server_str);
+
+maj_stat = gss_release_name(&min_stat, &gserver);
+
+HDEBUG(D_auth) debug_printf("heimdal: have server credentials.\n");
+
+/* Loop talking to client */
+step = 0;
+from_client = initial_data;
+handled_empty_ir = FALSE;
+error_out = OK;
+
+/* buffer sizes: auth_get_data() uses big_buffer, which we grow per
+GSSAPI RFC in _init, if needed, to meet the SHOULD size of 64KB.
+(big_buffer starts life at the MUST size of 16KB). */
+
+/* step values
+0: getting initial data from client to feed into GSSAPI
+1: iterating for as long as GSS_S_CONTINUE_NEEDED
+2: GSS_S_COMPLETE, SASL wrapping for authz and qop to send to client
+3: unpick final auth message from client
+4: break/finish (non-step)
+*/
+while (step < 4)
+ switch (step)
+ {
+ case 0:
+ if (!from_client || *from_client == '\0')
+ {
+ if (handled_empty_ir)
+ {
+ HDEBUG(D_auth) debug_printf("gssapi: repeated empty input, grr.\n");
+ error_out = BAD64;
+ goto ERROR_OUT;
+ }
+ else
+ {
+ HDEBUG(D_auth) debug_printf("gssapi: missing initial response, nudging.\n");
+ error_out = auth_get_data(&from_client, US"", 0);
+ if (error_out != OK)
+ goto ERROR_OUT;
+ handled_empty_ir = TRUE;
+ continue;
+ }
+ }
+ /* We should now have the opening data from the client, base64-encoded. */
+ step += 1;
+ HDEBUG(D_auth) debug_printf("heimdal: have initial client data\n");
+ break;
+
+ case 1:
+ gbufdesc_in.length = b64decode(from_client, USS &gbufdesc_in.value);
+ if (gclient)
+ {
+ maj_stat = gss_release_name(&min_stat, &gclient);
+ gclient = GSS_C_NO_NAME;
+ }
+ maj_stat = gss_accept_sec_context(&min_stat,
+ &gcontext, /* context handle */
+ gcred, /* acceptor cred handle */
+ &gbufdesc_in, /* input from client */
+ GSS_C_NO_CHANNEL_BINDINGS, /* XXX fixme: use the channel bindings from GnuTLS */
+ &gclient, /* client identifier */
+ &mech_type, /* mechanism in use */
+ &gbufdesc_out, /* output to send to client */
+ NULL, /* return flags */
+ NULL, /* time rec */
+ NULL /* delegated cred_handle */
+ );
+ if (GSS_ERROR(maj_stat))
+ {
+ exim_gssapi_error_defer(NULL, maj_stat, min_stat,
+ "gss_accept_sec_context()");
+ error_out = FAIL;
+ goto ERROR_OUT;
+ }
+ if (gbufdesc_out.length != 0)
+ {
+ error_out = auth_get_data(&from_client,
+ gbufdesc_out.value, gbufdesc_out.length);
+ if (error_out != OK)
+ goto ERROR_OUT;
+
+ gss_release_buffer(&min_stat, &gbufdesc_out);
+ EmptyBuf(gbufdesc_out);
+ }
+ if (maj_stat == GSS_S_COMPLETE)
+ {
+ step += 1;
+ HDEBUG(D_auth) debug_printf("heimdal: GSS complete\n");
+ }
+ else
+ HDEBUG(D_auth) debug_printf("heimdal: need more data\n");
+ break;
+
+ case 2:
+ memset(sasl_config, 0xFF, 4);
+ /* draft-ietf-sasl-gssapi-06.txt defines bitmasks for first octet
+ 0x01 No security layer
+ 0x02 Integrity protection
+ 0x04 Confidentiality protection
+
+ The remaining three octets are the maximum buffer size for wrapped
+ content. */
+ sasl_config[0] = 0x01; /* Exim does not wrap/unwrap SASL layers after auth */
+ gbufdesc.value = (void *) sasl_config;
+ gbufdesc.length = 4;
+ maj_stat = gss_wrap(&min_stat,
+ gcontext,
+ 0, /* conf_req_flag: integrity only */
+ GSS_C_QOP_DEFAULT, /* qop requested */
+ &gbufdesc, /* message to protect */
+ NULL, /* conf_state: no confidentiality applied */
+ &gbufdesc_out /* output buffer */
+ );
+ if (GSS_ERROR(maj_stat)
+ {
+ exim_gssapi_error_defer(NULL, maj_stat, min_stat,
+ "gss_wrap(SASL state after auth)");
+ error_out = FAIL;
+ goto ERROR_OUT;
+ }
+
+ HDEBUG(D_auth) debug_printf("heimdal SASL: requesting QOP with no security layers\n");
+
+ error_out = auth_get_data(&from_client,
+ gbufdesc_out.value, gbufdesc_out.length);
+ if (error_out != OK)
+ goto ERROR_OUT;
+
+ gss_release_buffer(&min_stat, &gbufdesc_out);
+ EmptyBuf(gbufdesc_out);
+ step += 1;
+ break;
+
+ case 3:
+ gbufdesc_in.length = b64decode(from_client, USS &gbufdesc_in.value);
+ maj_stat = gss_unwrap(&min_stat,
+ gcontext,
+ &gbufdesc_in, /* data from client */
+ &gbufdesc_out, /* results */
+ NULL, /* conf state */
+ NULL /* qop state */
+ );
+ if (GSS_ERROR(maj_stat))
+ {
+ exim_gssapi_error_defer(NULL, maj_stat, min_stat,
+ "gss_unwrap(final SASL message from client)");
+ error_out = FAIL;
+ goto ERROR_OUT;
+ }
+ if (gbufdesc_out.length < 4)
+ {
+ HDEBUG(D_auth)
+ debug_printf("gssapi: final message too short; "
+ "need flags, buf sizes and optional authzid\n");
+ error_out = FAIL;
+ goto ERROR_OUT;
+ }
+
+ requested_qop = (CS gbufdesc_out.value)[0];
+ if ((requested_qop & 0x01) == 0)
+ {
+ HDEBUG(D_auth)
+ debug_printf("gssapi: client requested security layers (%x)\n",
+ (unsigned int) requested_qop);
+ error_out = FAIL;
+ goto ERROR_OUT;
+ }
+
+ for (int i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL;
+ expand_nmax = 0;
+
+ /* Identifiers:
+ The SASL provided identifier is an unverified authzid.
+ GSSAPI provides us with a verified identifier, but it might be empty
+ for some clients.
+ */
+
+ /* $auth2 is authzid requested at SASL layer */
+ if (gbufdesc_out.length > 4)
+ {
+ expand_nlength[2] = gbufdesc_out.length - 4;
+ auth_vars[1] = expand_nstring[2] =
+ string_copyn((US gbufdesc_out.value) + 4, expand_nlength[2]);
+ expand_nmax = 2;
+ }
+
+ gss_release_buffer(&min_stat, &gbufdesc_out);
+ EmptyBuf(gbufdesc_out);
+
+ /* $auth1 is GSSAPI display name */
+ maj_stat = gss_display_name(&min_stat,
+ gclient,
+ &gbufdesc_out,
+ &mech_type);
+ if (GSS_ERROR(maj_stat))
+ {
+ auth_vars[1] = expand_nstring[2] = NULL;
+ expand_nmax = 0;
+ exim_gssapi_error_defer(NULL, maj_stat, min_stat,
+ "gss_display_name(client identifier)");
+ error_out = FAIL;
+ goto ERROR_OUT;
+ }
+
+ expand_nlength[1] = gbufdesc_out.length;
+ auth_vars[0] = expand_nstring[1] =
+ string_copyn(gbufdesc_out.value, gbufdesc_out.length);
+
+ if (expand_nmax == 0) /* should be: authzid was empty */
+ {
+ expand_nmax = 2;
+ expand_nlength[2] = expand_nlength[1];
+ auth_vars[1] = expand_nstring[2] = string_copyn(expand_nstring[1], expand_nlength[1]);
+ HDEBUG(D_auth)
+ debug_printf("heimdal SASL: empty authzid, set to dup of GSSAPI display name\n");
+ }
+
+ HDEBUG(D_auth)
+ debug_printf("heimdal SASL: happy with client request\n"
+ " auth1 (verified GSSAPI display-name): \"%s\"\n"
+ " auth2 (unverified SASL requested authzid): \"%s\"\n",
+ auth_vars[0], auth_vars[1]);
+
+ step += 1;
+ break;
} /* switch */
- } /* while step */
+ /* while step */
ERROR_OUT:
- maj_stat = gss_release_cred(&min_stat, &gcred);
- if (gclient) {
- gss_release_name(&min_stat, &gclient);
- gclient = GSS_C_NO_NAME;
- }
- if (gbufdesc_out.length) {
- gss_release_buffer(&min_stat, &gbufdesc_out);
- EmptyBuf(gbufdesc_out);
+maj_stat = gss_release_cred(&min_stat, &gcred);
+if (gclient)
+ {
+ gss_release_name(&min_stat, &gclient);
+ gclient = GSS_C_NO_NAME;
}
- if (gcontext != GSS_C_NO_CONTEXT) {
- gss_delete_sec_context(&min_stat, &gcontext, GSS_C_NO_BUFFER);
+if (gbufdesc_out.length)
+ {
+ gss_release_buffer(&min_stat, &gbufdesc_out);
+ EmptyBuf(gbufdesc_out);
}
+if (gcontext != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&min_stat, &gcontext, GSS_C_NO_BUFFER);
- store_reset(store_reset_point);
+store_reset(store_reset_point);
- if (error_out != OK)
- return error_out;
+if (error_out != OK)
+ return error_out;
- /* Auth succeeded, check server_condition */
- return auth_check_serv_cond(ablock);
+/* Auth succeeded, check server_condition */
+return auth_check_serv_cond(ablock);
}
OM_uint32 major, OM_uint32 minor,
const char *format, ...)
{
- va_list ap;
- OM_uint32 maj_stat, min_stat;
- OM_uint32 msgcontext = 0;
- gss_buffer_desc status_string;
- gstring * g;
-
- HDEBUG(D_auth)
- {
- va_start(ap, format);
- g = string_vformat(NULL, TRUE, format, ap);
- va_end(ap);
- }
+va_list ap;
+OM_uint32 maj_stat, min_stat;
+OM_uint32 msgcontext = 0;
+gss_buffer_desc status_string;
+gstring * g;
+
+HDEBUG(D_auth)
+ {
+ va_start(ap, format);
+ g = string_vformat(NULL, TRUE, format, ap);
+ va_end(ap);
+ }
- auth_defer_msg = NULL;
+auth_defer_msg = NULL;
- do {
- maj_stat = gss_display_status(&min_stat,
- major, GSS_C_GSS_CODE, GSS_C_NO_OID, &msgcontext, &status_string);
+do {
+ maj_stat = gss_display_status(&min_stat,
+ major, GSS_C_GSS_CODE, GSS_C_NO_OID, &msgcontext, &status_string);
- if (!auth_defer_msg)
- auth_defer_msg = string_copy(US status_string.value);
+ if (!auth_defer_msg)
+ auth_defer_msg = string_copy(US status_string.value);
- HDEBUG(D_auth) debug_printf("heimdal %s: %.*s\n",
- string_from_gstring(g), (int)status_string.length,
- CS status_string.value);
- gss_release_buffer(&min_stat, &status_string);
+ HDEBUG(D_auth) debug_printf("heimdal %s: %.*s\n",
+ string_from_gstring(g), (int)status_string.length,
+ CS status_string.value);
+ gss_release_buffer(&min_stat, &status_string);
} while (msgcontext != 0);
- if (store_reset_point)
- store_reset(store_reset_point);
- return DEFER;
+if (store_reset_point)
+ store_reset(store_reset_point);
+return DEFER;
}
uschar *buffer, /* buffer for reading response */
int buffsize) /* size of buffer */
{
- HDEBUG(D_auth)
- debug_printf("Client side NOT IMPLEMENTED: you should not see this!\n");
- /* NOT IMPLEMENTED */
- return FAIL;
+HDEBUG(D_auth)
+ debug_printf("Client side NOT IMPLEMENTED: you should not see this!\n");
+/* NOT IMPLEMENTED */
+return FAIL;
}
/*************************************************
void
auth_heimdal_gssapi_version_report(FILE *f)
{
- /* No build-time constants available unless we link against libraries at
- build-time and export the result as a string into a header ourselves. */
- fprintf(f, "Library version: Heimdal: Runtime: %s\n"
- " Build Info: %s\n",
- heimdal_version, heimdal_long_version);
+/* No build-time constants available unless we link against libraries at
+build-time and export the result as a string into a header ourselves. */
+fprintf(f, "Library version: Heimdal: Runtime: %s\n"
+ " Build Info: %s\n",
+ heimdal_version, heimdal_long_version);
}
#endif /*!MACRO_PREDEF*/
register unsigned int b = base->abcd[1];
register unsigned int c = base->abcd[2];
register unsigned int d = base->abcd[3];
-int i;
unsigned int X[16];
base->length += 64;
/* Load the 64 bytes into a set of working integers, treating them as 32-bit
numbers in little-endian order. */
-for (i = 0; i < 16; i++)
+for (int i = 0; i < 16; i++)
{
X[i] = (unsigned int)(text[0]) |
((unsigned int)(text[1]) << 8) |
void
md5_end(md5 *base, const uschar *text, int length, uschar *digest)
{
-int i;
uschar work[64];
/* Process in chunks of 64 until we have less than 64 bytes left. */
/* Pass back the result, low-order byte first in each word. */
-for (i = 0; i < 4; i++)
+for (int i = 0; i < 4; i++)
{
register int x = base->abcd[i];
*digest++ = x & 0xff;
for (i = 0; i < sizeof(tests)/sizeof(uschar *); i += 2)
{
- int j;
uschar s[33];
printf("%s\nShould be: %s\n", tests[i], tests[i+1]);
md5_start(&base);
md5_end(&base, tests[i], strlen(tests[i]), digest);
- for (j = 0; j < 16; j++) sprintf(s+2*j, "%02x", digest[j]);
+ for (int j = 0; j < 16; j++) sprintf(s+2*j, "%02x", digest[j]);
printf("Computed: %s\n", s);
if (strcmp(s, tests[i+1]) != 0) printf("*** No match ***\n");
printf("\n");
while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size)))
{
- int i, len, clear_len;
+ int len, clear_len;
uschar *ss = expand_string(s);
uschar *clear;
/* The character ^ is used as an escape for a binary zero character, which is
needed for the PLAIN mechanism. It must be doubled if really needed. */
- for (i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
if (ss[i] == '^')
if (ss[i+1] != '^')
ss[i] = 0;
mime_decode_base64(FILE * in, FILE * out, uschar * boundary)
{
uschar ibuf[MIME_MAX_LINE_LENGTH], obuf[MIME_MAX_LINE_LENGTH];
-uschar *ipos, *opos;
+uschar *opos;
ssize_t len, size = 0;
int bytestate = 0;
)
break;
- for (ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos != 0; ++ipos)
+ for (uschar * ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos; ++ipos)
if (*ipos == '=') /* skip padding */
++bytestate;
if ((max_for_this_host > 0) &&
(smtp_accept_count >= max_for_this_host))
{
- int i;
int host_accept_count = 0;
int other_host_count = 0; /* keep a count of non matches to optimise */
- for (i = 0; i < smtp_accept_max; ++i)
+ for (int i = 0; i < smtp_accept_max; ++i)
if (smtp_slots[i].host_address)
{
if (Ustrcmp(sender_host_address, smtp_slots[i].host_address) == 0)
{
if (smtp_out)
{
- int i, fd = fileno(smtp_in);
+ int fd = fileno(smtp_in);
uschar buf[128];
mac_smtp_fflush();
/* drain socket, for clean TCP FINs */
if (fcntl(fd, F_SETFL, O_NONBLOCK) == 0)
- for(i = 16; read(fd, buf, sizeof(buf)) > 0 && i > 0; ) i--;
+ for(int i = 16; read(fd, buf, sizeof(buf)) > 0 && i > 0; ) i--;
}
cancel_cutthrough_connection(TRUE, US"message setup dropped");
search_tidyup();
DEBUG(D_receive)
{
- int i;
if (sender_address)
debug_printf("Sender: %s\n", sender_address);
if (recipients_list)
{
debug_printf("Recipients:\n");
- for (i = 0; i < recipients_count; i++)
+ for (int i = 0; i < recipients_count; i++)
debug_printf(" %s\n", recipients_list[i].address);
}
}
never_error(US"daemon: accept process fork failed", US"Fork failed", errno);
else
{
- int i;
- for (i = 0; i < smtp_accept_max; ++i)
+ for (int i = 0; i < smtp_accept_max; ++i)
if (smtp_slots[i].pid <= 0)
{
smtp_slots[i].pid = pid;
for (ipa = addresses; ipa; ipa = ipa->next)
{
- int i;
-
if (Ustrcmp(ipa->address, "0.0.0.0") == 0)
ipa->address[0] = 0;
else if (Ustrcmp(ipa->address, "::0") == 0)
ipa->address[1] == 0 ? US"\"all IPv6\"" : ipa->address);
ipa->port = default_smtp_port[0];
- for (i = 1; default_smtp_port[i] > 0; i++)
+ for (int i = 1; default_smtp_port[i] > 0; i++)
{
ip_address_item *new = store_get(sizeof(ip_address_item));
if (smtp_accept_max > 0)
{
- int i;
smtp_slots = store_get(smtp_accept_max * sizeof(smtp_slot));
- for (i = 0; i < smtp_accept_max; i++) smtp_slots[i] = empty_smtp_slot;
+ for (int i = 0; i < smtp_accept_max; i++) smtp_slots[i] = empty_smtp_slot;
}
}
if (queue_interval > 0 && local_queue_run_max > 0)
{
- int i;
queue_pid_slots = store_get(local_queue_run_max * sizeof(pid_t));
- for (i = 0; i < local_queue_run_max; i++) queue_pid_slots[i] = 0;
+ for (int i = 0; i < local_queue_run_max; i++) queue_pid_slots[i] = 0;
}
/* Set up the handler for termination of child processes. */
else if (f.daemon_listen)
{
- int i, j;
int smtp_ports = 0;
int smtps_ports = 0;
ip_address_item * ipa, * i2;
deprecated protocol that starts TLS without using STARTTLS), and others
listening for standard SMTP. Keep their listings separate. */
- for (j = 0; j < 2; j++)
+ for (int j = 0; j < 2; j++)
{
+ int i;
for (i = 0, ipa = addresses; i < 10 && ipa; i++, ipa = ipa->next)
{
/* First time round, look for SMTP ports; second time round, look for
{
if ((pid = fork()) == 0)
{
- int sk;
-
DEBUG(D_any) debug_printf("Starting queue-runner: pid %d\n",
(int)getpid());
/* Close any open listening sockets in the child */
- for (sk = 0; sk < listen_socket_count; sk++)
+ for (int sk = 0; sk < listen_socket_count; sk++)
(void)close(listen_sockets[sk]);
/* Reset SIGHUP and SIGCHLD in the child in both cases. */
}
else
{
- int i;
- for (i = 0; i < local_queue_run_max; ++i)
+ for (int i = 0; i < local_queue_run_max; ++i)
if (queue_pid_slots[i] <= 0)
{
queue_pid_slots[i] = pid;
break;
}
DEBUG(D_any) debug_printf("%d queue-runner process%s running\n",
- queue_run_count, (queue_run_count == 1)? "" : "es");
+ queue_run_count, queue_run_count == 1 ? "" : "es");
}
}
if (f.daemon_listen)
{
- int sk, lcount, select_errno;
+ int lcount, select_errno;
int max_socket = 0;
BOOL select_failed = FALSE;
fd_set select_listen;
FD_ZERO(&select_listen);
- for (sk = 0; sk < listen_socket_count; sk++)
+ for (int sk = 0; sk < listen_socket_count; sk++)
{
FD_SET(listen_sockets[sk], &select_listen);
if (listen_sockets[sk] > max_socket) max_socket = listen_sockets[sk];
int accept_socket = -1;
if (!select_failed)
- for (sk = 0; sk < listen_socket_count; sk++)
+ for (int sk = 0; sk < listen_socket_count; sk++)
if (FD_ISSET(listen_sockets[sk], &select_listen))
{
len = sizeof(accepted);
if (sighup_seen)
{
- int sk;
log_write(0, LOG_MAIN, "pid %d: SIGHUP received: re-exec daemon",
getpid());
- for (sk = 0; sk < listen_socket_count; sk++)
+ for (int sk = 0; sk < listen_socket_count; sk++)
(void)close(listen_sockets[sk]);
ALARM_CLR(0);
signal(SIGHUP, SIG_IGN);
*/
for (matched = 0; !matched && slist; slist = slist->next)
{
- dane_mtype_list m;
unsigned char mdbuf[EVP_MAX_MD_SIZE];
unsigned char *buf = NULL;
unsigned char *buf2;
/*
* Loop over each mtype and data element
*/
- for (m = slist->value->mtype; !matched && m; m = m->next)
+ for (dane_mtype_list m = slist->value->mtype; !matched && m; m = m->next)
{
- dane_data_list d;
unsigned char *cmpbuf = buf;
unsigned int cmplen = len;
if (!EVP_Digest(buf, len, cmpbuf, &cmplen, m->value->md, 0))
matched = -1;
}
- for (d = m->value->data; !matched && d; d = d->next)
+ for (dane_data_list d = m->value->data; !matched && d; d = d->next)
if ( cmplen == d->value->datalen
&& memcmp(cmpbuf, d->value->data, cmplen) == 0)
matched = slist->value->selector + 1;
{
if (akid && akid->issuer)
{
- int i;
GENERAL_NAMES *gens = akid->issuer;
- for (i = 0; i < sk_GENERAL_NAME_num(gens); ++i)
+ for (int i = 0; i < sk_GENERAL_NAME_num(gens); ++i)
{
GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i);
static int
ta_signed(ssl_dane *dane, X509 *cert, int depth)
{
-dane_cert_list x;
-dane_pkey_list k;
EVP_PKEY *pk;
int done = 0;
* first (name comparisons), before we bother with signature checks
* (public key operations).
*/
-for (x = dane->certs; !done && x; x = x->next)
+for (dane_cert_list x = dane->certs; !done && x; x = x->next)
{
if (X509_check_issued(x->value, cert) == X509_V_OK)
{
* This may push errors onto the stack when the certificate signature is
* not of the right type or length, throw these away,
*/
-for (k = dane->pkeys; !done && k; k = k->next)
+for (dane_pkey_list k = dane->pkeys; !done && k; k = k->next)
if (X509_verify(cert, k->value) > 0)
done = wrap_issuer(dane, k->value, cert, depth, WRAP_MID) ? 1 : -1;
else
set_trust_anchor(X509_STORE_CTX *ctx, ssl_dane *dane, X509 *cert)
{
int matched = 0;
-int n;
-int i;
int depth = 0;
EVP_PKEY *takey;
X509 *ca;
*
* Caller ensures that the initial certificate is not self-signed.
*/
-for (n = sk_X509_num(in); n > 0; --n, ++depth)
+for (int n = sk_X509_num(in); n > 0; --n, ++depth)
{
+ int i;
for (i = 0; i < n; ++i)
if (X509_check_issued(sk_X509_value(in, i), cert) == X509_V_OK)
break;
match_name(const char *certid, ssl_dane *dane)
{
int multi = dane->multi;
-dane_host_list hosts;
-for (hosts = dane->hosts; hosts; hosts = hosts->next)
+for (dane_host_list hosts = dane->hosts; hosts; hosts = hosts->next)
{
int match_subdomain = 0;
const char *domain = hosts->value;
if (gens)
{
int n = sk_GENERAL_NAME_num(gens);
- int i;
- for (i = 0; i < n; ++i)
+ for (int i = 0; i < n; ++i)
{
const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i);
const char *certid;
static void
list_free(void *list, void (*f)(void *))
{
-dane_list head;
dane_list next;
-for (head = (dane_list) list; head; head = next)
+for (dane_list head = (dane_list) list; head; head = next)
{
next = head->next;
if (f && head->value)
DANESSL_cleanup(SSL *ssl)
{
ssl_dane *dane;
-int u;
DEBUG(D_tls) debug_printf("Dane lib-cleanup\n");
dane_reset(dane);
if (dane->hosts)
list_free(dane->hosts, ossl_free);
-for (u = 0; u <= DANESSL_USAGE_LAST; ++u)
+for (int u = 0; u <= DANESSL_USAGE_LAST; ++u)
if (dane->selectors[u])
list_free(dane->selectors[u], dane_selector_free);
if (dane->pkeys)
DANESSL_init(SSL *ssl, const char *sni_domain, const char **hostnames)
{
ssl_dane *dane;
-int i;
DEBUG(D_tls) debug_printf("Dane ssl_init\n");
if (dane_idx < 0)
dane->count = 0;
dane->hosts = 0;
-for (i = 0; i <= DANESSL_USAGE_LAST; ++i)
+for (int i = 0; i <= DANESSL_USAGE_LAST; ++i)
dane->selectors[i] = 0;
if (hostnames && (dane->hosts = host_list_init(hostnames)) == 0)
static void
tree_printsub(tree_node *p, int pos, int barswitch)
{
-int i;
if (p->right) tree_printsub(p->right, pos+2, 1);
-for (i = 0; i <= pos-1; i++) debug_printf("%c", tree_printline[i]);
+for (int i = 0; i <= pos-1; i++) debug_printf("%c", tree_printline[i]);
debug_printf("-->%s [%d]\n", p->name, p->balance);
tree_printline[pos] = barswitch? '|' : ' ';
if (p->left)
void
debug_print_tree(tree_node *p)
{
-int i;
-for (i = 0; i < tree_printlinesize; i++) tree_printline[i] = ' ';
+for (int i = 0; i < tree_printlinesize; i++) tree_printline[i] = ' ';
if (!p) debug_printf("Empty Tree\n"); else tree_printsub(p, 0, 0);
debug_printf("---- End of tree ----\n");
}
if (indent > 0)
{
- int i;
- for (i = indent >> 2; i > 0; i--)
+ for (int i = indent >> 2; i > 0; i--)
DEBUG(D_noutf8)
{
Ustrcpy(debug_ptr, " !");
else
{
- address_item *addr2;
if (testflag(addr, af_pfr))
{
if (testflag(addr, af_file)) address_file = addr->local_part;
else if (addr->local_part[0] == '|') address_pipe = addr->local_part;
}
- for (addr2 = addr->next; addr2; addr2 = addr2->next)
+ for (address_item * addr2 = addr->next; addr2; addr2 = addr2->next)
{
if (deliver_domain && Ustrcmp(deliver_domain, addr2->domain) != 0)
deliver_domain = NULL;
static int
open_msglog_file(uschar *filename, int mode, uschar **error)
{
-int fd, i;
-
-for (i = 2; i > 0; i--)
+for (int i = 2; i > 0; i--)
{
- fd = Uopen(filename,
+ int fd = Uopen(filename,
#ifdef O_CLOEXEC
O_CLOEXEC |
#endif
static void
replicate_status(address_item *addr)
{
-address_item *addr2;
-for (addr2 = addr->next; addr2; addr2 = addr2->next)
+for (address_item * addr2 = addr->next; addr2; addr2 = addr2->next)
{
addr2->transport = addr->transport;
addr2->transport_return = addr->transport_return;
static void
address_done(address_item *addr, uschar *now)
{
-address_item *dup;
-
update_spool = TRUE; /* Ensure spool gets updated */
/* Top-level address */
/* Check the list of duplicate addresses and ensure they are now marked
done as well. */
-for (dup = addr_duplicate; dup; dup = dup->next)
+for (address_item * dup = addr_duplicate; dup; dup = dup->next)
if (Ustrcmp(addr->unique, dup->unique) == 0)
{
tree_add_nonrecipient(dup->unique);
static void
child_done(address_item *addr, uschar *now)
{
-address_item *aa;
while (addr->parent)
{
+ address_item *aa;
+
addr = addr->parent;
if (--addr->child_count > 0) return; /* Incomplete parent */
address_done(addr, now);
&& addr->parent != topaddr)
{
uschar *s = US" (";
- address_item *addr2;
- for (addr2 = addr->parent; addr2 != topaddr; addr2 = addr2->parent)
+ for (address_item * addr2 = addr->parent; addr2 != topaddr; addr2 = addr2->parent)
{
g = string_catn(g, s, 2);
g = string_cat (g, addr2->address);
&& (addr->host_used || Ustrcmp(addr->transport->driver_name, "lmtp") == 0)
)
{
- unsigned i;
unsigned lim = big_buffer_size < 1024 ? big_buffer_size : 1024;
uschar *p = big_buffer;
uschar *ss = addr->message;
*p++ = '\"';
- for (i = 0; i < lim && ss[i] != 0; i++) /* limit logged amount */
+ for (int i = 0; i < lim && ss[i] != 0; i++) /* limit logged amount */
{
if (ss[i] == '\"' || ss[i] == '\\') *p++ = '\\'; /* quote \ and " */
*p++ = ss[i];
static void
common_error(BOOL logit, address_item *addr, int code, uschar *format, ...)
{
-address_item *addr2;
addr->basic_errno = code;
if (format)
addr->message = string_from_gstring(g);
}
-for (addr2 = addr->next; addr2; addr2 = addr2->next)
+for (address_item * addr2 = addr->next; addr2; addr2 = addr2->next)
{
addr2->basic_errno = code;
addr2->message = addr->message;
static BOOL
check_never_users(uid_t uid, uid_t *nusers)
{
-int i;
if (!nusers) return FALSE;
-for (i = 1; i <= (int)(nusers[0]); i++) if (nusers[i] == uid) return TRUE;
+for (int i = 1; i <= (int)(nusers[0]); i++) if (nusers[i] == uid) return TRUE;
return FALSE;
}
DEBUG(D_deliver)
{
- address_item *batched;
debug_printf(" home=%s current=%s\n", deliver_home, working_directory);
- for (batched = addr->next; batched; batched = batched->next)
+ for (address_item * batched = addr->next; batched; batched = batched->next)
debug_printf("additional batched address: %s\n", batched->address);
}
DEBUG(D_deliver)
{
- address_item *addr;
debug_printf("remote addresses after sorting:\n");
- for (addr = addr_remote; addr; addr = addr->next)
+ for (address_item * addr = addr_remote; addr; addr = addr->next)
debug_printf(" %s\n", addr->address);
}
}
remote_post_process(address_item *addr, int logflags, uschar *msg,
BOOL fallback)
{
-host_item *h;
-
/* If any host addresses were found to be unusable, add them to the unusable
tree so that subsequent deliveries don't try them. */
-for (h = addr->host_list; h; h = h->next)
+for (host_item * h = addr->host_list; h; h = h->next)
if (h->address)
if (h->status >= hstatus_unusable) tree_add_unusable(h);
do_remote_deliveries(BOOL fallback)
{
int parmax;
-int delivery_count;
int poffset;
parcount = 0; /* Number of executing subprocesses */
/* Now loop for each remote delivery */
-for (delivery_count = 0; addr_remote; delivery_count++)
+for (int delivery_count = 0; addr_remote; delivery_count++)
{
pid_t pid;
uid_t uid;
&& addr->host_list
)
{
- host_item * h;
ok = FALSE;
- for (h = addr->host_list; h; h = h->next)
+ for (host_item * h = addr->host_list; h; h = h->next)
if (Ustrcmp(h->name, continue_hostname) == 0)
/*XXX should also check port here */
{ ok = TRUE; break; }
interface to the transport. */
for (next = addr_remote; next && !f.continue_more; next = next->next)
- {
- host_item *h;
- for (h = next->host_list; h; h = h->next)
+ for (host_item * h = next->host_list; h; h = h->next)
if (Ustrcmp(h->name, continue_hostname) == 0)
{ f.continue_more = TRUE; break; }
- }
}
/* The transports set up the process info themselves as they may connect
continue_closedown(void)
{
if (continue_transport)
- {
- transport_instance *t;
- for (t = transports; t; t = t->next)
+ for (transport_instance * t = transports; t; t = t->next)
if (Ustrcmp(t->name, continue_transport) == 0)
{
if (t->info->closedown) (t->info->closedown)(t);
break;
}
- }
return DELIVER_NOT_ATTEMPTED;
}
DEBUG(D_deliver)
{
- address_item *p;
debug_printf("Delivery address list:\n");
- for (p = addr_new; p; p = p->next)
+ for (address_item * p = addr_new; p; p = p->next)
debug_printf(" %s %s\n", p->address,
p->onetime_parent ? p->onetime_parent : US"");
}
DEBUG(D_deliver|D_retry|D_route)
{
- address_item *p;
debug_printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
debug_printf("After routing:\n Local deliveries:\n");
- for (p = addr_local; p; p = p->next)
+ for (address_item * p = addr_local; p; p = p->next)
debug_printf(" %s\n", p->address);
debug_printf(" Remote deliveries:\n");
- for (p = addr_remote; p; p = p->next)
+ for (address_item * p = addr_remote; p; p = p->next)
debug_printf(" %s\n", p->address);
debug_printf(" Failed addresses:\n");
- for (p = addr_failed; p; p = p->next)
+ for (address_item * p = addr_failed; p; p = p->next)
debug_printf(" %s\n", p->address);
debug_printf(" Deferred addresses:\n");
- for (p = addr_defer; p; p = p->next)
+ for (address_item * p = addr_defer; p; p = p->next)
debug_printf(" %s\n", p->address);
}
{
if (addr_defer)
{
- address_item *addr, *nextaddr;
- for (addr = addr_defer; addr; addr = nextaddr)
+ address_item * nextaddr;
+ for (address_item * addr = addr_defer; addr; addr = nextaddr)
{
log_write(0, LOG_MAIN, "** %s mua_wrapper forced failure for deferred "
"delivery", addr->address);
else if (addr_defer != (address_item *)(+1))
{
- address_item *addr;
uschar *recipients = US"";
BOOL want_warning_msg = FALSE;
deliver_domain = testflag(addr_defer, af_pfr)
? addr_defer->parent->domain : addr_defer->domain;
- for (addr = addr_defer; addr; addr = addr->next)
+ for (address_item * addr = addr_defer; addr; addr = addr->next)
{
address_item *otaddr;
{
dns_answer dnsa;
dns_scan dnss;
-dns_record *rr;
gstring * g = NULL;
lookup_dnssec_authenticated = NULL;
/* Search for TXT record */
-for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
if (rr->type == T_TXT)
void
dkim_exim_verify_log_all(void)
{
-pdkim_signature * sig;
-for (sig = dkim_signatures; sig; sig = sig->next) dkim_exim_verify_log_sig(sig);
+for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
+ dkim_exim_verify_log_sig(sig);
}
void
dkim_exim_verify_finish(void)
{
-pdkim_signature * sig;
int rc;
gstring * g = NULL;
const uschar * errstr = NULL;
/* Build a colon-separated list of signing domains (and identities, if present) in dkim_signers */
-for (sig = dkim_signatures; sig; sig = sig->next)
+for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
{
if (sig->domain) g = string_append_listele(g, ':', sig->domain);
if (sig->identity) g = string_append_listele(g, ':', sig->identity);
dkim_exim_acl_run(uschar * id, gstring ** res_ptr,
uschar ** user_msgptr, uschar ** log_msgptr)
{
-pdkim_signature * sig;
uschar * cmp_val;
int rc = -1;
/* Find signatures to run ACL on */
-for (sig = dkim_signatures; sig; sig = sig->next)
+for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
if ( (cmp_val = Ustrchr(id, '@') != NULL ? US sig->identity : US sig->domain)
&& strcmpic(cmp_val, id) == 0
)
gstring *
authres_dkim(gstring * g)
{
-pdkim_signature * sig;
int start = 0; /* compiler quietening */
DEBUG(D_acl) start = g->ptr;
-for (sig = dkim_signatures; sig; sig = sig->next)
+for (pdkim_signature * sig = dkim_signatures; sig; sig = sig->next)
{
g = string_catn(g, US";\n\tdkim=", 8);
static void
dmarc_send_forensic_report(u_char **ruf)
{
-int c;
uschar *recipient, *save_sender;
BOOL send_status = FALSE;
error_block *eblock = NULL;
da == DMARC_POLICY_DKIM_ALIGNMENT_PASS ? US"yes" : US"no");
eblock = add_to_eblock(eblock, US"DMARC Results", dmarc_status_text);
- for (c = 0; ruf[c]; c++)
+ for (int c = 0; ruf[c]; c++)
{
recipient = string_copylc(ruf[c]);
if (Ustrncmp(recipient, "mailto:",7))
if (Ustrchr(string, ':') == NULL)
#endif
{
- int i;
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
const uschar *ppp = p;
while (ppp > string && ppp[-1] != '.') ppp--;
#if HAVE_IPV6
else
{
- int i;
int v6[4];
(void)host_aton(string, v6);
nibble, and look in the ip6.int domain. The domain was subsequently
changed to ip6.arpa. */
- for (i = 3; i >= 0; i--)
- {
- int j;
- for (j = 0; j < 32; j += 4)
+ for (int i = 3; i >= 0; i--)
+ for (int j = 0; j < 32; j += 4)
pp += sprintf(CS pp, "%x.", (v6[i] >> j) & 15);
- }
Ustrcpy(pp, "ip6.arpa.");
/* Another way of doing IPv6 reverse lookups was proposed in conjunction
Ustrcpy(pp, "\\[x");
pp += 3;
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
sprintf(pp, "%08X", v6[i]);
pp += 8;
dns_extract_auth_name(const dns_answer * dnsa) /* FIXME: const dns_answer */
{
dns_scan dnss;
-dns_record * rr;
const HEADER * h = (const HEADER *) dnsa->answer;
if (h->nscount && h->aa)
- for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
+ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
if (rr->type == (h->ancount ? T_NS : T_SOA))
return string_copy(rr->name);
dns_lookup(dns_answer *dnsa, const uschar *name, int type,
const uschar **fully_qualified_name)
{
-int i;
const uschar *orig_name = name;
BOOL secure_so_far = TRUE;
but no further... The testsuite tests the latter case, mostly assuming that the
former will work. */
-for (i = 0; i <= dns_cname_loops; i++)
+for (int i = 0; i <= dns_cname_loops; i++)
{
uschar * data;
- dns_record *rr, cname_rr, type_rr;
+ dns_record cname_rr, type_rr;
dns_scan dnss;
int rc;
area in the dnsa block. */
cname_rr.data = type_rr.data = NULL;
- for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
+ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
if (rr->type == type)
{
if (rr->data + 16 <= dnsa_lim)
{
struct in6_addr in6;
- int i;
- for (i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
+ for (int i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
yield = store_get(sizeof(dns_address) + 50);
inet_ntop(AF_INET6, &in6, CS yield->address, 50);
yield->next = NULL;
void
auth_show_supported(FILE * f)
{
-auth_info * ai;
fprintf(f, "Authenticators:");
-for (ai = auths_available; ai->driver_name[0]; ai++)
+for (auth_info * ai = auths_available; ai->driver_name[0]; ai++)
fprintf(f, " %s", ai->driver_name);
fprintf(f, "\n");
}
void
route_show_supported(FILE * f)
{
-router_info * rr;
fprintf(f, "Routers:");
-for (rr = routers_available; rr->driver_name[0]; rr++)
+for (router_info * rr = routers_available; rr->driver_name[0]; rr++)
fprintf(f, " %s", rr->driver_name);
fprintf(f, "\n");
}
/* now add all lookups to the real list */
p = lookupmodules;
while (p) {
- int j;
struct lookupmodulestr *pnext;
- for (j = 0; j < p->info->lookupcount; j++)
+ for (int j = 0; j < p->info->lookupcount; j++)
add_lookup_to_list(p->info->lookups[j]);
pnext = p->next;
}
else if (Ustrcmp(keep_environment, "*") != 0)
- {
- uschar **p;
- if (environ) for (p = USS environ; *p; /* see below */)
+ if (environ) for (uschar ** p = USS environ; *p; /* see below */)
{
/* It's considered broken if we do not find the '=', according to
Florian Weimer. For now we ignore such strings. unsetenv() would complain,
store_reset(name);
}
}
- }
if (add_environment)
{
uschar * p;
if (n == 0) n = EXPAND_MAXN + 1;
if (yield)
{
- int nn;
expand_nmax = setup < 0 ? 0 : setup + 1;
- for (nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
+ for (int nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
{
expand_nstring[expand_nmax] = s + ovector[nn];
expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
void
exim_nullstd(void)
{
-int i;
int devnull = -1;
struct stat statbuf;
-for (i = 0; i <= 2; i++)
+for (int i = 0; i <= 2; i++)
{
if (fstat(i, &statbuf) < 0 && errno == EBADF)
{
save_errno = errno;
debug_printf(" auxiliary group list:");
if (group_count > 0)
- {
- int i;
- for (i = 0; i < group_count; i++) debug_printf(" %d", (int)group_list[i]);
- }
+ for (int i = 0; i < group_count; i++) debug_printf(" %d", (int)group_list[i]);
else if (group_count < 0)
debug_printf(" <error: %s>", strerror(save_errno));
else debug_printf(" <none>");
static void
show_whats_supported(FILE * fp)
{
-auth_info * authi;
-
DEBUG(D_any) {} else show_db_version(fp);
fprintf(fp, "Support for:");
Perhaps the tls_version_report should move into this too. */
DEBUG(D_any) do {
- int i;
-
/* clang defines __GNUC__ (at least, for me) so test for it first */
#if defined(__clang__)
fprintf(fp, "Compiler: CLang [%s]\n", __clang_version__);
utf8_version_report(fp);
#endif
- for (authi = auths_available; *authi->driver_name != '\0'; ++authi)
+ for (auth_info * authi = auths_available; *authi->driver_name != '\0'; ++authi)
if (authi->version_report)
(*authi->version_report)(fp);
#undef EXPAND_AND_QUOTE
init_lookup_list();
- for (i = 0; i < lookup_list_count; i++)
+ for (int i = 0; i < lookup_list_count; i++)
if (lookup_list[i]->version_report)
lookup_list[i]->version_report(fp);
static void
show_exim_information(enum commandline_info request, FILE *stream)
{
-const uschar **pp;
-
switch(request)
{
case CMDINFO_NONE:
);
return;
case CMDINFO_SIEVE:
- for (pp = exim_sieve_extension_list; *pp; ++pp)
+ for (const uschar ** pp = exim_sieve_extension_list; *pp; ++pp)
fprintf(stream, "%s\n", *pp);
return;
case CMDINFO_DSCP:
{
BOOL needs_quote = FALSE;
gstring * g;
-uschar *t;
-for (t = lpart; !needs_quote && *t != 0; t++)
+for (uschar * t = lpart; !needs_quote && *t != 0; t++)
{
needs_quote = !isalnum(*t) && strchr("!#$%&'*+-/=?^_`{|}~", *t) == NULL &&
(*t != '.' || t == lpart || t[1] == 0);
static uschar *
get_stdinput(char *(*fn_readline)(const char *), void(*fn_addhist)(const char *))
{
-int i;
gstring * g = NULL;
if (!fn_readline) { printf("> "); fflush(stdout); }
-for (i = 0;; i++)
+for (int i = 0;; i++)
{
uschar buffer[1024];
uschar *p, *ss;
macros_trusted(BOOL opt_D_used)
{
#ifdef WHITELIST_D_MACROS
-macro_item *m;
-uschar *whitelisted, *end, *p, **whites, **w;
+uschar *whitelisted, *end, *p, **whites;
int white_count, i, n;
size_t len;
BOOL prev_char_item, found;
/* The list of commandline macros should be very short.
Accept the N*M complexity. */
-for (m = macros_user; m; m = m->next) if (m->command_line)
+for (macro_item * m = macros_user; m; m = m->next) if (m->command_line)
{
found = FALSE;
- for (w = whites; *w; ++w)
+ for (uschar ** w = whites; *w; ++w)
if (Ustrcmp(*w, m->name) == 0)
{
found = TRUE;
if (!one_msg_action)
{
- int j;
- for (j = msg_action_arg; j < argc; j++) if (!mac_ismsgid(argv[j]))
+ for (int j = msg_action_arg; j < argc; j++) if (!mac_ismsgid(argv[j]))
exim_fail("exim: malformed message id %s after %s option\n",
argv[j], arg);
goto END_ARG; /* Remaining args are ids */
argument. */
if (*argrest != 0)
- {
- int i;
- for (i = 0; i < nelem(rsopts); i++)
+ for (int i = 0; i < nelem(rsopts); i++)
if (Ustrcmp(argrest, rsopts[i]) == 0)
{
if (i != 2) f.queue_run_force = TRUE;
if (i == 1 || i == 4) f.deliver_force_thaw = TRUE;
argrest += Ustrlen(rsopts[i]);
}
- }
/* -R: Set string to match in addresses for forced queue run to
pick out particular messages. */
argument. */
if (*argrest)
- {
- int i;
- for (i = 0; i < nelem(rsopts); i++)
+ for (int i = 0; i < nelem(rsopts); i++)
if (Ustrcmp(argrest, rsopts[i]) == 0)
{
if (i != 2) f.queue_run_force = TRUE;
if (i == 1 || i == 4) f.deliver_force_thaw = TRUE;
argrest += Ustrlen(rsopts[i]);
}
- }
/* -S: Set string to match in addresses for forced queue run to
pick out particular messages. */
if (real_uid == root_uid || real_uid == exim_uid || real_gid == exim_gid)
f.admin_user = TRUE;
else
- {
- int i, j;
- for (i = 0; i < group_count && !f.admin_user; i++)
+ for (int i = 0; i < group_count && !f.admin_user; i++)
if (group_list[i] == exim_gid)
f.admin_user = TRUE;
else if (admin_groups)
- for (j = 1; j <= (int)admin_groups[0] && !f.admin_user; j++)
+ for (int j = 1; j <= (int)admin_groups[0] && !f.admin_user; j++)
if (admin_groups[j] == group_list[i])
f.admin_user = TRUE;
- }
/* Another group of privileged users are the trusted users. These are root,
exim, and any caller matching trusted_users or trusted_groups. Trusted callers
f.trusted_caller = TRUE;
else
{
- int i, j;
-
if (trusted_users)
- for (i = 1; i <= (int)trusted_users[0] && !f.trusted_caller; i++)
+ for (int i = 1; i <= (int)trusted_users[0] && !f.trusted_caller; i++)
if (trusted_users[i] == real_uid)
f.trusted_caller = TRUE;
if (trusted_groups)
- for (i = 1; i <= (int)trusted_groups[0] && !f.trusted_caller; i++)
+ for (int i = 1; i <= (int)trusted_groups[0] && !f.trusted_caller; i++)
if (trusted_groups[i] == real_gid)
f.trusted_caller = TRUE;
- else for (j = 0; j < group_count && !f.trusted_caller; j++)
+ else for (int j = 0; j < group_count && !f.trusted_caller; j++)
if (trusted_groups[i] == group_list[j])
f.trusted_caller = TRUE;
}
DEBUG(D_any)
{
- int i;
debug_printf("configuration file is %s\n", config_main_filename);
debug_printf("log selectors =");
- for (i = 0; i < log_selector_size; i++)
+ for (int i = 0; i < log_selector_size; i++)
debug_printf(" %08x", log_selector[i]);
debug_printf("\n");
}
*/
#ifdef EXIM_TMPDIR
- {
- uschar **p;
- if (environ) for (p = USS environ; *p; p++)
+ if (environ) for (uschar ** p = USS environ; *p; p++)
if (Ustrncmp(*p, "TMPDIR=", 7) == 0 && Ustrcmp(*p+7, EXIM_TMPDIR) != 0)
{
uschar * newp = store_malloc(Ustrlen(EXIM_TMPDIR) + 8);
*p = newp;
DEBUG(D_any) debug_printf("reset TMPDIR=%s in environment\n", EXIM_TMPDIR);
}
- }
#endif
/* Timezone handling. If timezone_string is "utc", set a flag to cause all
if ( (debug_selector & D_any || LOGGING(arguments))
&& f.really_exim && !list_options && !checking)
{
- int i;
uschar *p = big_buffer;
Ustrcpy(p, "cwd= (failed)");
(void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc);
while (*p) p++;
- for (i = 0; i < argc; i++)
+ for (int i = 0; i < argc; i++)
{
int len = Ustrlen(argv[i]);
const uschar *printing;
printf("No retry information found\n");
else
{
- retry_rule *r;
more_errno = yield->more_errno;
printf("Retry rule: %s ", yield->pattern);
printf("auth_failed ");
else printf("* ");
- for (r = yield->rules; r; r = r->next)
+ for (retry_rule * r = yield->rules; r; r = r->next)
{
printf("%c,%s", r->rule, readconf_printtime(r->timeout)); /* Do not */
printf(",%s", readconf_printtime(r->p1)); /* amalgamate */
else
{
- int i;
int rcount = 0;
int count = argc - recipients_arg;
uschar **list = argv + recipients_arg;
/* Loop for each argument */
- for (i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
{
int start, end, domain;
uschar *errmess;
DEBUG(D_receive)
{
- int i;
if (sender_address != NULL) debug_printf("Sender: %s\n", sender_address);
if (recipients_list != NULL)
{
debug_printf("Recipients:\n");
- for (i = 0; i < recipients_count; i++)
+ for (int i = 0; i < recipients_count; i++)
debug_printf(" %s\n", recipients_list[i].address);
}
}
callout_address = NULL;
sending_ip_address = NULL;
acl_var_m = NULL;
- { int i; for(i=0; i<REGEX_VARS; i++) regex_vars[i] = NULL; }
+ for(int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
store_reset(reset_point);
}
switch(rc = EXIM_DBPUTB(d, key, content))
{
case EXIM_DBPUTB_OK:
- count++;
- break;
+ count++;
+ break;
case EXIM_DBPUTB_DUP:
- if (warn) fprintf(stderr, "** Duplicate key \"%s\"\n",
- keybuffer);
- dupcount++;
- if(duperr) yield = 1;
- if (lastdup) EXIM_DBPUT(d, key, content);
- break;
+ if (warn) fprintf(stderr, "** Duplicate key \"%s\"\n", keybuffer);
+ dupcount++;
+ if(duperr) yield = 1;
+ if (lastdup) EXIM_DBPUT(d, key, content);
+ break;
default:
- fprintf(stderr, "Error %d while writing key %s: errno=%d\n", rc,
- keybuffer, errno);
- yield = 2;
- goto TIDYUP;
+ fprintf(stderr, "Error %d while writing key %s: errno=%d\n", rc,
+ keybuffer, errno);
+ yield = 2;
+ goto TIDYUP;
}
bptr = buffer;
keystart = t;
while (*s != 0 && *s != '\"')
{
- if (*s == '\\') *t++ = string_interpret_escape((const uschar **)&s);
- else *t++ = *s;
+ *t++ = *s == '\\'
+ ? string_interpret_escape((const uschar **)&s)
+ : *s;
s++;
}
if (*s != 0) s++; /* Past terminating " */
}
if (lowercase)
- {
for (i = 0; i < EXIM_DATUM_SIZE(key) - add_zero; i++)
keybuffer[i] = tolower(keystart[i]);
- }
else
- {
for (i = 0; i < EXIM_DATUM_SIZE(key) - add_zero; i++)
keybuffer[i] = keystart[i];
- }
keybuffer[i] = 0;
started = 1;
static time_t
read_time(uschar *s)
{
-uschar *t = s;
int field = 0;
int value;
time_t now = time(NULL);
tm->tm_sec = 0;
tm->tm_isdst = -1;
-for (t = s + Ustrlen(s) - 1; t >= s; t--)
+for (uschar * t = s + Ustrlen(s) - 1; t >= s; t--)
{
if (*t == ':') continue;
if (!isdigit((uschar)*t)) return -1;
open_db *dbm;
EXIM_CURSOR *cursor;
uschar **argv = USS cargv;
-uschar *key;
uschar keybuffer[1024];
/* Check the arguments, and open the database */
that data is returned in a malloc'ed block, in order that it be
correctly aligned. */
-for (key = dbfn_scan(dbm, TRUE, &cursor);
+for (uschar * key = dbfn_scan(dbm, TRUE, &cursor);
key;
key = dbfn_scan(dbm, FALSE, &cursor))
{
dbdata_ratelimit *ratelimit;
dbdata_ratelimit_unique *rate_unique;
int count_bad = 0;
- int i, length;
+ int length;
uschar *t;
uschar name[MESSAGE_ID_LENGTH + 1];
void *value;
switch(dbdata_type)
{
case type_retry:
- retry = (dbdata_retry *)value;
- printf(" %s %d %d %s\n%s ", keybuffer, retry->basic_errno,
- retry->more_errno, retry->text,
- print_time(retry->first_failed));
- printf("%s ", print_time(retry->last_try));
- printf("%s %s\n", print_time(retry->next_try),
- (retry->expired)? "*" : "");
- break;
+ retry = (dbdata_retry *)value;
+ printf(" %s %d %d %s\n%s ", keybuffer, retry->basic_errno,
+ retry->more_errno, retry->text,
+ print_time(retry->first_failed));
+ printf("%s ", print_time(retry->last_try));
+ printf("%s %s\n", print_time(retry->next_try),
+ (retry->expired)? "*" : "");
+ break;
case type_wait:
- wait = (dbdata_wait *)value;
- printf("%s ", keybuffer);
- t = wait->text;
- name[MESSAGE_ID_LENGTH] = 0;
-
- if (wait->count > WAIT_NAME_MAX)
- {
- fprintf(stderr,
- "**** Data for %s corrupted\n count=%d=0x%x max=%d\n",
- CS keybuffer, wait->count, wait->count, WAIT_NAME_MAX);
- wait->count = WAIT_NAME_MAX;
- yield = count_bad = 1;
- }
- for (i = 1; i <= wait->count; i++)
- {
- Ustrncpy(name, t, MESSAGE_ID_LENGTH);
- if (count_bad && name[0] == 0) break;
- if (Ustrlen(name) != MESSAGE_ID_LENGTH ||
- Ustrspn(name, "0123456789"
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ-") != MESSAGE_ID_LENGTH)
- {
- int j;
- fprintf(stderr,
- "**** Data for %s corrupted: bad character in message id\n",
- CS keybuffer);
- for (j = 0; j < MESSAGE_ID_LENGTH; j++)
- fprintf(stderr, "%02x ", name[j]);
- fprintf(stderr, "\n");
- yield = 1;
- break;
- }
- printf("%s ", name);
- t += MESSAGE_ID_LENGTH;
- }
- printf("\n");
- break;
+ wait = (dbdata_wait *)value;
+ printf("%s ", keybuffer);
+ t = wait->text;
+ name[MESSAGE_ID_LENGTH] = 0;
+
+ if (wait->count > WAIT_NAME_MAX)
+ {
+ fprintf(stderr,
+ "**** Data for %s corrupted\n count=%d=0x%x max=%d\n",
+ CS keybuffer, wait->count, wait->count, WAIT_NAME_MAX);
+ wait->count = WAIT_NAME_MAX;
+ yield = count_bad = 1;
+ }
+ for (int i = 1; i <= wait->count; i++)
+ {
+ Ustrncpy(name, t, MESSAGE_ID_LENGTH);
+ if (count_bad && name[0] == 0) break;
+ if (Ustrlen(name) != MESSAGE_ID_LENGTH ||
+ Ustrspn(name, "0123456789"
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ-") != MESSAGE_ID_LENGTH)
+ {
+ fprintf(stderr,
+ "**** Data for %s corrupted: bad character in message id\n",
+ CS keybuffer);
+ for (int j = 0; j < MESSAGE_ID_LENGTH; j++)
+ fprintf(stderr, "%02x ", name[j]);
+ fprintf(stderr, "\n");
+ yield = 1;
+ break;
+ }
+ printf("%s ", name);
+ t += MESSAGE_ID_LENGTH;
+ }
+ printf("\n");
+ break;
case type_misc:
- printf("%s %s\n", print_time(((dbdata_generic *)value)->time_stamp),
- keybuffer);
- break;
+ printf("%s %s\n", print_time(((dbdata_generic *)value)->time_stamp),
+ keybuffer);
+ break;
case type_callout:
- callout = (dbdata_callout_cache *)value;
-
- /* New-style address record */
-
- if (length == sizeof(dbdata_callout_cache_address))
- {
- printf("%s %s callout=%s\n",
- print_time(((dbdata_generic *)value)->time_stamp),
- keybuffer,
- print_cache(callout->result));
- }
-
- /* New-style domain record */
-
- else if (length == sizeof(dbdata_callout_cache))
- {
- printf("%s %s callout=%s postmaster=%s",
- print_time(((dbdata_generic *)value)->time_stamp),
- keybuffer,
- print_cache(callout->result),
- print_cache(callout->postmaster_result));
- if (callout->postmaster_result != ccache_unknown)
- printf(" (%s)", print_time(callout->postmaster_stamp));
- printf(" random=%s", print_cache(callout->random_result));
- if (callout->random_result != ccache_unknown)
- printf(" (%s)", print_time(callout->random_stamp));
- printf("\n");
- }
-
- break;
+ callout = (dbdata_callout_cache *)value;
+
+ /* New-style address record */
+
+ if (length == sizeof(dbdata_callout_cache_address))
+ {
+ printf("%s %s callout=%s\n",
+ print_time(((dbdata_generic *)value)->time_stamp),
+ keybuffer,
+ print_cache(callout->result));
+ }
+
+ /* New-style domain record */
+
+ else if (length == sizeof(dbdata_callout_cache))
+ {
+ printf("%s %s callout=%s postmaster=%s",
+ print_time(((dbdata_generic *)value)->time_stamp),
+ keybuffer,
+ print_cache(callout->result),
+ print_cache(callout->postmaster_result));
+ if (callout->postmaster_result != ccache_unknown)
+ printf(" (%s)", print_time(callout->postmaster_stamp));
+ printf(" random=%s", print_cache(callout->random_result));
+ if (callout->random_result != ccache_unknown)
+ printf(" (%s)", print_time(callout->random_stamp));
+ printf("\n");
+ }
+
+ break;
case type_ratelimit:
- if (Ustrstr(key, "/unique/") != NULL && length >= sizeof(*rate_unique))
- {
- ratelimit = (dbdata_ratelimit *)value;
- rate_unique = (dbdata_ratelimit_unique *)value;
- printf("%s.%06d rate: %10.3f epoch: %s size: %u key: %s\n",
- print_time(ratelimit->time_stamp),
- ratelimit->time_usec, ratelimit->rate,
- print_time(rate_unique->bloom_epoch), rate_unique->bloom_size,
- keybuffer);
- }
- else
- {
- ratelimit = (dbdata_ratelimit *)value;
- printf("%s.%06d rate: %10.3f key: %s\n",
- print_time(ratelimit->time_stamp),
- ratelimit->time_usec, ratelimit->rate,
- keybuffer);
- }
- break;
+ if (Ustrstr(key, "/unique/") != NULL && length >= sizeof(*rate_unique))
+ {
+ ratelimit = (dbdata_ratelimit *)value;
+ rate_unique = (dbdata_ratelimit_unique *)value;
+ printf("%s.%06d rate: %10.3f epoch: %s size: %u key: %s\n",
+ print_time(ratelimit->time_stamp),
+ ratelimit->time_usec, ratelimit->rate,
+ print_time(rate_unique->bloom_epoch), rate_unique->bloom_size,
+ keybuffer);
+ }
+ else
+ {
+ ratelimit = (dbdata_ratelimit *)value;
+ printf("%s.%06d rate: %10.3f key: %s\n",
+ print_time(ratelimit->time_stamp),
+ ratelimit->time_usec, ratelimit->rate,
+ keybuffer);
+ }
+ break;
}
store_reset(value);
}
dbdata_callout_cache *callout;
dbdata_ratelimit *ratelimit;
dbdata_ratelimit_unique *rate_unique;
- int i, oldlength;
+ int oldlength;
uschar *t;
uschar field[256], value[256];
switch(dbdata_type)
{
case type_retry:
- retry = (dbdata_retry *)record;
- /* length = sizeof(dbdata_retry) + Ustrlen(retry->text); */
-
- switch(fieldno)
- {
- case 0:
- retry->basic_errno = Uatoi(value);
- break;
-
- case 1:
- retry->more_errno = Uatoi(value);
- break;
-
- case 2:
- if ((tt = read_time(value)) > 0) retry->first_failed = tt;
- else printf("bad time value\n");
- break;
-
- case 3:
- if ((tt = read_time(value)) > 0) retry->last_try = tt;
- else printf("bad time value\n");
- break;
-
- case 4:
- if ((tt = read_time(value)) > 0) retry->next_try = tt;
- else printf("bad time value\n");
- break;
-
- case 5:
- if (Ustrcmp(value, "yes") == 0) retry->expired = TRUE;
- else if (Ustrcmp(value, "no") == 0) retry->expired = FALSE;
- else printf("\"yes\" or \"no\" expected=n");
- break;
-
- default:
- printf("unknown field number\n");
- verify = 0;
- break;
- }
- break;
+ retry = (dbdata_retry *)record;
+ /* length = sizeof(dbdata_retry) + Ustrlen(retry->text); */
+
+ switch(fieldno)
+ {
+ case 0: retry->basic_errno = Uatoi(value);
+ break;
+ case 1: retry->more_errno = Uatoi(value);
+ break;
+ case 2: if ((tt = read_time(value)) > 0) retry->first_failed = tt;
+ else printf("bad time value\n");
+ break;
+ case 3: if ((tt = read_time(value)) > 0) retry->last_try = tt;
+ else printf("bad time value\n");
+ break;
+ case 4: if ((tt = read_time(value)) > 0) retry->next_try = tt;
+ else printf("bad time value\n");
+ break;
+ case 5: if (Ustrcmp(value, "yes") == 0) retry->expired = TRUE;
+ else if (Ustrcmp(value, "no") == 0) retry->expired = FALSE;
+ else printf("\"yes\" or \"no\" expected=n");
+ break;
+ default: printf("unknown field number\n");
+ verify = 0;
+ break;
+ }
+ break;
case type_wait:
- printf("Can't change contents of wait database record\n");
- break;
+ printf("Can't change contents of wait database record\n");
+ break;
case type_misc:
- printf("Can't change contents of misc database record\n");
- break;
+ printf("Can't change contents of misc database record\n");
+ break;
case type_callout:
- callout = (dbdata_callout_cache *)record;
- /* length = sizeof(dbdata_callout_cache); */
- switch(fieldno)
- {
- case 0:
- callout->result = Uatoi(value);
- break;
-
- case 1:
- callout->postmaster_result = Uatoi(value);
- break;
-
- case 2:
- callout->random_result = Uatoi(value);
- break;
-
- default:
- printf("unknown field number\n");
- verify = 0;
- break;
- }
- break;
+ callout = (dbdata_callout_cache *)record;
+ /* length = sizeof(dbdata_callout_cache); */
+ switch(fieldno)
+ {
+ case 0: callout->result = Uatoi(value);
+ break;
+ case 1: callout->postmaster_result = Uatoi(value);
+ break;
+ case 2: callout->random_result = Uatoi(value);
+ break;
+ default: printf("unknown field number\n");
+ verify = 0;
+ break;
+ }
+ break;
case type_ratelimit:
- ratelimit = (dbdata_ratelimit *)record;
- switch(fieldno)
- {
- case 0:
- if ((tt = read_time(value)) > 0) ratelimit->time_stamp = tt;
- else printf("bad time value\n");
- break;
-
- case 1:
- ratelimit->time_usec = Uatoi(value);
- break;
-
- case 2:
- ratelimit->rate = Ustrtod(value, NULL);
- break;
-
- case 3:
- if (Ustrstr(name, "/unique/") != NULL
- && oldlength >= sizeof(dbdata_ratelimit_unique))
- {
- rate_unique = (dbdata_ratelimit_unique *)record;
- if ((tt = read_time(value)) > 0) rate_unique->bloom_epoch = tt;
- else printf("bad time value\n");
- break;
- }
- /* else fall through */
-
- case 4:
- case 5:
- if (Ustrstr(name, "/unique/") != NULL
- && oldlength >= sizeof(dbdata_ratelimit_unique))
- {
- /* see acl.c */
- BOOL seen;
- unsigned n, hash, hinc;
- uschar md5sum[16];
- md5 md5info;
- md5_start(&md5info);
- md5_end(&md5info, value, Ustrlen(value), md5sum);
- hash = md5sum[0] << 0 | md5sum[1] << 8
- | md5sum[2] << 16 | md5sum[3] << 24;
- hinc = md5sum[4] << 0 | md5sum[5] << 8
- | md5sum[6] << 16 | md5sum[7] << 24;
- rate_unique = (dbdata_ratelimit_unique *)record;
- seen = TRUE;
- for (n = 0; n < 8; n++, hash += hinc)
- {
- int bit = 1 << (hash % 8);
- int byte = (hash / 8) % rate_unique->bloom_size;
- if ((rate_unique->bloom[byte] & bit) == 0)
- {
- seen = FALSE;
- if (fieldno == 5) rate_unique->bloom[byte] |= bit;
- }
- }
- printf("%s %s\n",
- seen ? "seen" : fieldno == 5 ? "added" : "unseen", value);
- break;
- }
- /* else fall through */
-
- default:
- printf("unknown field number\n");
- verify = 0;
- break;
- }
- break;
+ ratelimit = (dbdata_ratelimit *)record;
+ switch(fieldno)
+ {
+ case 0: if ((tt = read_time(value)) > 0) ratelimit->time_stamp = tt;
+ else printf("bad time value\n");
+ break;
+ case 1: ratelimit->time_usec = Uatoi(value);
+ break;
+ case 2: ratelimit->rate = Ustrtod(value, NULL);
+ break;
+ case 3: if (Ustrstr(name, "/unique/") != NULL
+ && oldlength >= sizeof(dbdata_ratelimit_unique))
+ {
+ rate_unique = (dbdata_ratelimit_unique *)record;
+ if ((tt = read_time(value)) > 0) rate_unique->bloom_epoch = tt;
+ else printf("bad time value\n");
+ break;
+ }
+ /* else fall through */
+ case 4:
+ case 5: if (Ustrstr(name, "/unique/") != NULL
+ && oldlength >= sizeof(dbdata_ratelimit_unique))
+ {
+ /* see acl.c */
+ BOOL seen;
+ unsigned hash, hinc;
+ uschar md5sum[16];
+ md5 md5info;
+ md5_start(&md5info);
+ md5_end(&md5info, value, Ustrlen(value), md5sum);
+ hash = md5sum[0] << 0 | md5sum[1] << 8
+ | md5sum[2] << 16 | md5sum[3] << 24;
+ hinc = md5sum[4] << 0 | md5sum[5] << 8
+ | md5sum[6] << 16 | md5sum[7] << 24;
+ rate_unique = (dbdata_ratelimit_unique *)record;
+ seen = TRUE;
+ for (unsigned n = 0; n < 8; n++, hash += hinc)
+ {
+ int bit = 1 << (hash % 8);
+ int byte = (hash / 8) % rate_unique->bloom_size;
+ if ((rate_unique->bloom[byte] & bit) == 0)
+ {
+ seen = FALSE;
+ if (fieldno == 5) rate_unique->bloom[byte] |= bit;
+ }
+ }
+ printf("%s %s\n",
+ seen ? "seen" : fieldno == 5 ? "added" : "unseen", value);
+ break;
+ }
+ /* else fall through */
+ default: printf("unknown field number\n");
+ verify = 0;
+ break;
+ }
+ break;
}
dbfn_write(dbm, name, record, oldlength);
switch(dbdata_type)
{
case type_retry:
- retry = (dbdata_retry *)record;
- printf("0 error number: %d %s\n", retry->basic_errno, retry->text);
- printf("1 extra data: %d\n", retry->more_errno);
- printf("2 first failed: %s\n", print_time(retry->first_failed));
- printf("3 last try: %s\n", print_time(retry->last_try));
- printf("4 next try: %s\n", print_time(retry->next_try));
- printf("5 expired: %s\n", (retry->expired)? "yes" : "no");
- break;
+ retry = (dbdata_retry *)record;
+ printf("0 error number: %d %s\n", retry->basic_errno, retry->text);
+ printf("1 extra data: %d\n", retry->more_errno);
+ printf("2 first failed: %s\n", print_time(retry->first_failed));
+ printf("3 last try: %s\n", print_time(retry->last_try));
+ printf("4 next try: %s\n", print_time(retry->next_try));
+ printf("5 expired: %s\n", (retry->expired)? "yes" : "no");
+ break;
case type_wait:
- wait = (dbdata_wait *)record;
- t = wait->text;
- printf("Sequence: %d\n", wait->sequence);
- if (wait->count > WAIT_NAME_MAX)
- {
- printf("**** Data corrupted: count=%d=0x%x max=%d ****\n", wait->count,
- wait->count, WAIT_NAME_MAX);
- wait->count = WAIT_NAME_MAX;
- count_bad = 1;
- }
- for (i = 1; i <= wait->count; i++)
- {
- Ustrncpy(value, t, MESSAGE_ID_LENGTH);
- value[MESSAGE_ID_LENGTH] = 0;
- if (count_bad && value[0] == 0) break;
- if (Ustrlen(value) != MESSAGE_ID_LENGTH ||
- Ustrspn(value, "0123456789"
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ-") != MESSAGE_ID_LENGTH)
- {
- int j;
- printf("\n**** Data corrupted: bad character in message id ****\n");
- for (j = 0; j < MESSAGE_ID_LENGTH; j++)
- printf("%02x ", value[j]);
- printf("\n");
- break;
- }
- printf("%s ", value);
- t += MESSAGE_ID_LENGTH;
- }
- printf("\n");
- break;
+ wait = (dbdata_wait *)record;
+ t = wait->text;
+ printf("Sequence: %d\n", wait->sequence);
+ if (wait->count > WAIT_NAME_MAX)
+ {
+ printf("**** Data corrupted: count=%d=0x%x max=%d ****\n", wait->count,
+ wait->count, WAIT_NAME_MAX);
+ wait->count = WAIT_NAME_MAX;
+ count_bad = 1;
+ }
+ for (int i = 1; i <= wait->count; i++)
+ {
+ Ustrncpy(value, t, MESSAGE_ID_LENGTH);
+ value[MESSAGE_ID_LENGTH] = 0;
+ if (count_bad && value[0] == 0) break;
+ if (Ustrlen(value) != MESSAGE_ID_LENGTH ||
+ Ustrspn(value, "0123456789"
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ-") != MESSAGE_ID_LENGTH)
+ {
+ printf("\n**** Data corrupted: bad character in message id ****\n");
+ for (int j = 0; j < MESSAGE_ID_LENGTH; j++)
+ printf("%02x ", value[j]);
+ printf("\n");
+ break;
+ }
+ printf("%s ", value);
+ t += MESSAGE_ID_LENGTH;
+ }
+ printf("\n");
+ break;
case type_misc:
- break;
+ break;
case type_callout:
- callout = (dbdata_callout_cache *)record;
- printf("0 callout: %s (%d)\n", print_cache(callout->result),
- callout->result);
- if (oldlength > sizeof(dbdata_callout_cache_address))
- {
- printf("1 postmaster: %s (%d)\n", print_cache(callout->postmaster_result),
- callout->postmaster_result);
- printf("2 random: %s (%d)\n", print_cache(callout->random_result),
- callout->random_result);
- }
- break;
+ callout = (dbdata_callout_cache *)record;
+ printf("0 callout: %s (%d)\n", print_cache(callout->result),
+ callout->result);
+ if (oldlength > sizeof(dbdata_callout_cache_address))
+ {
+ printf("1 postmaster: %s (%d)\n", print_cache(callout->postmaster_result),
+ callout->postmaster_result);
+ printf("2 random: %s (%d)\n", print_cache(callout->random_result),
+ callout->random_result);
+ }
+ break;
case type_ratelimit:
- ratelimit = (dbdata_ratelimit *)record;
- printf("0 time stamp: %s\n", print_time(ratelimit->time_stamp));
- printf("1 fract. time: .%06d\n", ratelimit->time_usec);
- printf("2 sender rate: % .3f\n", ratelimit->rate);
- if (Ustrstr(name, "/unique/") != NULL
- && oldlength >= sizeof(dbdata_ratelimit_unique))
- {
- rate_unique = (dbdata_ratelimit_unique *)record;
- printf("3 filter epoch: %s\n", print_time(rate_unique->bloom_epoch));
- printf("4 test filter membership\n");
- printf("5 add element to filter\n");
- }
- break;
+ ratelimit = (dbdata_ratelimit *)record;
+ printf("0 time stamp: %s\n", print_time(ratelimit->time_stamp));
+ printf("1 fract. time: .%06d\n", ratelimit->time_usec);
+ printf("2 sender rate: % .3f\n", ratelimit->rate);
+ if (Ustrstr(name, "/unique/") != NULL
+ && oldlength >= sizeof(dbdata_ratelimit_unique))
+ {
+ rate_unique = (dbdata_ratelimit_unique *)record;
+ printf("3 filter epoch: %s\n", print_time(rate_unique->bloom_epoch));
+ printf("4 test filter membership\n");
+ printf("5 add element to filter\n");
+ }
+ break;
}
}
for (;;)
{
- int offset;
int length = wait->count * MESSAGE_ID_LENGTH;
- for (offset = length - MESSAGE_ID_LENGTH;
+ for (int offset = length - MESSAGE_ID_LENGTH;
offset >= 0; offset -= MESSAGE_ID_LENGTH)
{
Ustrncpy(buffer+path_len, wait->text + offset, MESSAGE_ID_LENGTH);
if (*id++ != ':') continue;
for (i = 0; i < MESSAGE_ID_LENGTH; i++)
- {
if (i == 6 || i == 13)
{ if (id[i] != '-') break; }
else
{ if (!isalnum(id[i])) break; }
- }
if (i < MESSAGE_ID_LENGTH) continue;
Ustrncpy(buffer + path_len, id, MESSAGE_ID_LENGTH);
expand_getcertele(uschar * field, uschar * certvar)
{
var_entry * vp;
-certfield * cp;
if (!(vp = find_var_ent(certvar)))
{
if (*field >= '0' && *field <= '9')
return tls_cert_ext_by_oid(*(void **)vp->value, field, 0);
-for(cp = certfields;
- cp < certfields + nelem(certfields);
- cp++)
+for (certfield * cp = certfields;
+ cp < certfields + nelem(certfields);
+ cp++)
if (Ustrncmp(cp->name, field, cp->namelen) == 0)
{
uschar * modifier = *(field += cp->namelen) == ','
BOOL found = !name;
int len = name ? Ustrlen(name) : 0;
BOOL comma = FALSE;
-header_line * h;
gstring * g = NULL;
-for (h = header_list; h; h = h->next)
+for (header_line * h = header_list; h; h = h->next)
if (h->type != htype_old && h->text) /* NULL => Received: placeholder */
if (!name || (len <= h->slen && strncmpic(name, h->text, len) == 0))
{
{
uschar * s;
gstring * g = NULL;
-int i;
if (!f.enable_dollar_recipients) return NULL;
-for (i = 0; i < recipients_count; i++)
+for (int i = 0; i < recipients_count; i++)
{
s = recipients_list[i].address;
g = string_append2_listele_n(g, US", ", s, Ustrlen(s));
read_subs(uschar **sub, int n, int m, const uschar **sptr, BOOL skipping,
BOOL check_end, uschar *name, BOOL *resetok)
{
-int i;
const uschar *s = *sptr;
while (isspace(*s)) s++;
-for (i = 0; i < n; i++)
+for (int i = 0; i < n; i++)
{
if (*s != '{')
{
case ECOND_STR_GE:
case ECOND_STR_GEI:
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++)
{
/* Sometimes, we don't expand substrings; too many insecure configurations
created using match_address{}{} and friends, where the second param
}
else if (sublen == 32)
{
- int i;
uschar coded[36];
- for (i = 0; i < 16; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
+ for (int i = 0; i < 16; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
coded[32] = 0;
DEBUG(D_auth) debug_printf("crypteq: using MD5+hex hashing\n"
" subject=%s\n crypted=%s\n", coded, sub[1]+5);
}
else if (sublen == 40)
{
- int i;
uschar coded[44];
- for (i = 0; i < 20; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
+ for (int i = 0; i < 20; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
coded[40] = 0;
DEBUG(D_auth) debug_printf("crypteq: using SHA1+hex hashing\n"
" subject=%s\n crypted=%s\n", coded, sub[1]+6);
static int
save_expand_strings(uschar **save_expand_nstring, int *save_expand_nlength)
{
-int i;
-for (i = 0; i <= expand_nmax; i++)
+for (int i = 0; i <= expand_nmax; i++)
{
save_expand_nstring[i] = expand_nstring[i];
save_expand_nlength[i] = expand_nlength[i];
restore_expand_strings(int save_expand_nmax, uschar **save_expand_nstring,
int *save_expand_nlength)
{
-int i;
expand_nmax = save_expand_nmax;
-for (i = 0; i <= expand_nmax; i++)
+for (int i = 0; i <= expand_nmax; i++)
{
expand_nstring[i] = save_expand_nstring[i];
expand_nlength[i] = save_expand_nlength[i];
{
gstring * hash_source;
uschar * p;
-int i;
hctx h;
uschar innerhash[20];
uschar finalhash[20];
memset(innerkey, 0x36, 64);
memset(outerkey, 0x5c, 64);
-for (i = 0; i < Ustrlen(key); i++)
+for (int i = 0; i < Ustrlen(key); i++)
{
innerkey[i] ^= key[i];
outerkey[i] ^= key[i];
chash_end(HMAC_SHA1, &h, innerhash, 20, finalhash);
p = finalhash_hex;
-for (i = 0; i < 3; i++)
+for (int i = 0; i < 3; i++)
{
*p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
*p++ = hex_digits[finalhash[i] & 0x0f];
cat_file_tls(void * tls_ctx, gstring * yield, uschar * eol)
{
int rc;
-uschar * s;
uschar buffer[1024];
+/*XXX could we read direct into a pre-grown string? */
+
while ((rc = tls_read(tls_ctx, buffer, sizeof(buffer))) > 0)
- for (s = buffer; rc--; s++)
+ for (uschar * s = buffer; rc--; s++)
yield = eol && *s == '\n'
? string_cat(yield, eol) : string_catn(yield, s, 1);
}
}
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++) if (sub[i])
{
- if (sub[i] == NULL) continue;
val[i] = (int)Ustrtol(sub[i], &ret, 10);
if (*ret != 0 || (i != 0 && val[i] < 0))
{
md5 md5_base;
hctx sha1_ctx;
void *use_base;
- int type, i;
+ int type;
int hashlen; /* Number of octets for the hash algorithm's output */
int hashblocklen; /* Number of octets the hash algorithm processes */
uschar *keyptr, *p;
memset(innerkey, 0x36, hashblocklen);
memset(outerkey, 0x5c, hashblocklen);
- for (i = 0; i < keylen; i++)
+ for (int i = 0; i < keylen; i++)
{
innerkey[i] ^= keyptr[i];
outerkey[i] ^= keyptr[i];
/* Encode the final hash as a hex string */
p = finalhash_hex;
- for (i = 0; i < hashlen; i++)
+ for (int i = 0; i < hashlen; i++)
{
*p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
*p++ = hex_digits[finalhash[i] & 0x0f];
int ovector[3*(EXPAND_MAXN+1)];
int n = pcre_exec(re, NULL, CS subject, slen, moffset + moffsetextra,
PCRE_EOPT | emptyopt, ovector, nelem(ovector));
- int nn;
uschar *insert;
/* No match - if we previously set PCRE_NOTEMPTY after a null match, this
if (n == 0) n = EXPAND_MAXN + 1;
expand_nmax = 0;
- for (nn = 0; nn < n*2; nn += 2)
+ for (int nn = 0; nn < n*2; nn += 2)
{
expand_nstring[expand_nmax] = subject + ovector[nn];
expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
case EITEM_EXTRACT:
{
- int i;
- int j;
int field_number = 1;
BOOL field_number_set = FALSE;
uschar *save_lookup_value = lookup_value;
/* Check for a format-variant specifier */
if (*s != '{') /*}*/
- {
- if (Ustrncmp(s, "json", 4) == 0) {fmt = extract_json; s += 4;}
- }
+ if (Ustrncmp(s, "json", 4) == 0)
+ {fmt = extract_json; s += 4;}
/* While skipping we cannot rely on the data for expansions being
available (eg. $item) hence cannot decide on numeric vs. keyed.
if (skipping)
{
- for (j = 5; j > 0 && *s == '{'; j--) /*'}'*/
+ for (int j = 5; j > 0 && *s == '{'; j--) /*'}'*/
{
if (!expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok))
goto EXPAND_FAILED; /*'{'*/
}
}
- else for (i = 0, j = 2; i < j; i++) /* Read the proper number of arguments */
+ else for (int i = 0, j = 2; i < j; i++) /* Read the proper number of arguments */
{
while (isspace(*s)) s++;
if (*s == '{') /*'}'*/
case EITEM_LISTEXTRACT:
{
- int i;
int field_number = 1;
uschar *save_lookup_value = lookup_value;
uschar *sub[2];
/* Read the field & list arguments */
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++)
{
while (isspace(*s)) s++;
- if (*s != '{') /*}*/
+ if (*s != '{') /*'}'*/
{
expand_string_message = string_sprintf(
"missing '{' for arg %d of listextract", i+1);
/* Look up the dynamically loaded object handle in the tree. If it isn't
found, dlopen() the file and put the handle in the tree for next time. */
- t = tree_search(dlobj_anchor, argv[0]);
- if (t == NULL)
+ if (!(t = tree_search(dlobj_anchor, argv[0])))
{
void *handle = dlopen(CS argv[0], RTLD_LAZY);
if (handle == NULL)
{
md5 base;
uschar digest[16];
- int j;
md5_start(&base);
md5_end(&base, sub, Ustrlen(sub), digest);
- for (j = 0; j < 16; j++)
+ for (int j = 0; j < 16; j++)
yield = string_fmt_append(yield, "%02x", digest[j]);
}
continue;
{
hctx h;
uschar digest[20];
- int j;
sha1_start(&h);
sha1_end(&h, sub, Ustrlen(sub), digest);
- for (j = 0; j < 20; j++)
+ for (int j = 0; j < 20; j++)
yield = string_fmt_append(yield, "%02X", digest[j]);
}
continue;
uschar *out = sub;
uschar *enc;
- for (enc = sub; *enc != 0; enc++)
+ for (enc = sub; *enc; enc++)
{
if (!isxdigit(*enc))
{
if (isdigit(c)) c -= '0';
else c = toupper(c) - 'A' + 10;
if (b == -1)
- {
b = c << 4;
- }
else
{
*out++ = b | c;
case EOP_ESCAPE8BIT:
{
- const uschar * s = sub;
uschar c;
- for (s = sub; (c = *s); s++)
+ for (const uschar * s = sub; (c = *s); s++)
yield = c < 127 && c != '\\'
? string_catn(yield, s, 1)
: string_fmt_append(yield, "\\%03o", c);
{
uschar smode[12];
uschar **modetable[3];
- int i;
mode_t mode;
struct stat st;
modetable[1] = ((mode & 02000) == 0)? mtable_normal : mtable_setid;
modetable[2] = ((mode & 04000) == 0)? mtable_normal : mtable_setid;
- for (i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++)
{
memcpy(CS(smode + 7 - i*3), CS(modetable[i][mode & 7]), 3);
mode >>= 3;
{
err_ctx e = { .region_start = ptr, .region_end = US ptr + len,
.var_name = NULL, .var_data = NULL };
-int i;
-var_entry * v;
/* check acl_ variables */
tree_walk(acl_var_c, assert_variable_notin, &e);
tree_walk(acl_var_m, assert_variable_notin, &e);
/* check auth<n> variables */
-for (i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
+for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
assert_variable_notin(US"auth<n>", auth_vars[i], &e);
/* check regex<n> variables */
-for (i = 0; i < REGEX_VARS; i++) if (regex_vars[i])
+for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i])
assert_variable_notin(US"regex<n>", regex_vars[i], &e);
/* check known-name variables */
-for (v = var_table; v < var_table + var_table_size; v++)
+for (var_entry * v = var_table; v < var_table + var_table_size; v++)
if (v->type == vtype_stringptr)
assert_variable_notin(US v->name, *(USS v->value), &e);
if (n == 0) n = EXPAND_MAXN + 1;
if (yield)
{
- int nn;
- expand_nmax = (setup < 0)? 0 : setup + 1;
- for (nn = (setup < 0)? 0 : 2; nn < n*2; nn += 2)
+ expand_nmax = setup < 0 ? 0 : setup + 1;
+ for (int nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
{
expand_nstring[expand_nmax] = subject + ovector[nn];
expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
int main(int argc, uschar **argv)
{
-int i;
uschar buffer[1024];
debug_selector = D_v;
debug_fd = fileno(debug_file);
big_buffer = malloc(big_buffer_size);
-for (i = 1; i < argc; i++)
+for (int i = 1; i < argc; i++)
{
if (argv[i][0] == '+')
{
static void
native_sha1_mid(sha1 *base, const uschar *text)
{
-int i;
uint A, B, C, D, E;
uint W[80];
base->length += 64;
-for (i = 0; i < 16; i++)
+for (int i = 0; i < 16; i++)
{
W[i] = ((uint)text[0] << 24) | (text[1] << 16) | (text[2] << 8) | text[3];
text += 4;
}
-for (i = 16; i < 80; i++)
+for (int i = 16; i < 80; i++)
{
register unsigned int x = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
W[i] = (x << 1) | (x >> 31);
D = base->H[3];
E = base->H[4];
-for (i = 0; i < 20; i++)
+for (int i = 0; i < 20; i++)
{
unsigned int T;
T = ((A << 5) | (A >> 27)) + ((B & C) | ((~B) & D)) + E + W[i] + 0x5a827999;
A = T;
}
-for (i = 20; i < 40; i++)
+for (int i = 20; i < 40; i++)
{
unsigned int T;
T = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + W[i] + 0x6ed9eba1;
A = T;
}
-for (i = 40; i < 60; i++)
+for (int i = 40; i < 60; i++)
{
unsigned int T;
T = ((A << 5) | (A >> 27)) + ((B & C) | (B & D) | (C & D)) + E + W[i] +
A = T;
}
-for (i = 60; i < 80; i++)
+for (int i = 60; i < 80; i++)
{
unsigned int T;
T = ((A << 5) | (A >> 27)) + (B ^ C ^ D) + E + W[i] + 0xca62c1d6;
static void
native_sha1_end(sha1 *base, const uschar *text, int length, uschar *digest)
{
-int i;
uschar work[64];
/* Process in chunks of 64 until we have less than 64 bytes left. */
/* Pass back the result, high-order byte first in each word. */
-for (i = 0; i < 5; i++)
+for (int i = 0; i < 5; i++)
{
register int x = base->H[i];
*digest++ = (x >> 24) & 0xff;
void
header_remove(int occ, const uschar *name)
{
-header_line *h;
int hcount = 0;
int len = Ustrlen(name);
-for (h = header_list; h != NULL; h = h->next)
- {
+for (header_line * h = header_list; h; h = h->next)
if (header_testname(h, name, len, TRUE) && (occ <= 0 || ++hcount == occ))
{
h->type = htype_old;
if (occ > 0) return;
}
- }
}
one_pattern_match(uschar *name, int slen, BOOL has_addresses, uschar *pattern)
{
BOOL yield = FALSE;
-header_line *h;
const pcre *re = NULL;
/* If the pattern is a regex, compile it. Bomb out if compiling fails; these
/* Scan for the required header(s) and scan each one */
-for (h = header_list; !yield && h != NULL; h = h->next)
+for (header_line * h = header_list; !yield && h; h = h->next)
{
if (h->type == htype_old || slen > h->slen ||
strncmpic(name, h->text, slen) != 0)
{
uschar *s = h->text + slen;
- while (!yield && *s != 0)
+ while (!yield && *s)
{
uschar *error, *next;
uschar *e = parse_find_address_end(s, FALSE);
int count, ...)
{
va_list ap;
-string_item *s;
-int i;
int slen = Ustrlen(name);
-for (s = strings; s != NULL; s = s->next)
- {
- if (one_pattern_match(name, slen, has_addresses, s->text)) return cond;
- }
+for (string_item * s = strings; s; s = s->next)
+ if (one_pattern_match(name, slen, has_addresses, s->text))
+ return cond;
va_start(ap, count);
-for (i = 0; i < count; i++)
+for (int i = 0; i < count; i++)
if (one_pattern_match(name, slen, has_addresses, va_arg(ap, uschar *)))
{
va_end(ap);
struct hostent *yield;
dns_answer dnsa;
dns_scan dnss;
-dns_record *rr;
DEBUG(D_host_lookup)
debug_printf("using host_fake_gethostbyname for %s (%s)\n", name,
/* Handle a literal IP address */
-ipa = string_is_ip_address(lname, NULL);
-if (ipa != 0)
+if ((ipa = string_is_ip_address(lname, NULL)) != 0)
{
if ((ipa == 4 && af == AF_INET) ||
(ipa == 6 && af == AF_INET6))
{
- int i, n;
int x[4];
yield = store_get(sizeof(struct hostent));
alist = store_get(2 * sizeof(char *));
yield->h_length = alen;
yield->h_addr_list = CSS alist;
*alist++ = adds;
- n = host_aton(lname, x);
- for (i = 0; i < n; i++)
+ for (int n = host_aton(lname, x), i = 0; i < n; i++)
{
int y = x[i];
*adds++ = (y >> 24) & 255;
case DNS_FAIL: *error_num = NO_RECOVERY; return NULL;
}
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+ for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
rr;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
- if (rr->type == type)
- count++;
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == type)
+ count++;
yield = store_get(sizeof(struct hostent));
alist = store_get((count + 1) * sizeof(char *));
yield->h_length = alen;
yield->h_addr_list = CSS alist;
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+ for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
rr;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == type)
{
- int i, n;
int x[4];
dns_address *da;
- if (rr->type != type) continue;
if (!(da = dns_address_from_rr(&dnsa, rr))) break;
*alist++ = adds;
- n = host_aton(da->address, x);
- for (i = 0; i < n; i++)
+ for (int n = host_aton(da->address, x), i = 0; i < n; i++)
{
int y = x[i];
*adds++ = (y >> 24) & 255;
add_unique_interface(ip_address_item *list, ip_address_item *ipa)
{
ip_address_item *ipa2;
-for (ipa2 = list; ipa2 != NULL; ipa2 = ipa2->next)
+for (ipa2 = list; ipa2; ipa2 = ipa2->next)
if (Ustrcmp(ipa2->address, ipa->address) == 0) return list;
ipa2 = store_get_perm(sizeof(ip_address_item));
*ipa2 = *ipa;
US"extra_local_interfaces");
ip_address_item *ipa;
- if (dlist == NULL) dlist = xlist; else
+ if (!dlist) dlist = xlist;
+ else
{
- for (ipa = dlist; ipa->next != NULL; ipa = ipa->next);
+ for (ipa = dlist; ipa->next; ipa = ipa->next) ;
ipa->next = xlist;
}
- for (ipa = dlist; ipa != NULL; ipa = ipa->next)
+ for (ipa = dlist; ipa; ipa = ipa->next)
{
if (Ustrcmp(ipa->address, "0.0.0.0") == 0 ||
Ustrcmp(ipa->address, "::0") == 0)
{
- ip_address_item *ipa2;
BOOL ipv6 = ipa->address[0] == ':';
- if (running_interfaces == NULL)
+ if (!running_interfaces)
running_interfaces = os_find_running_interfaces();
- for (ipa2 = running_interfaces; ipa2 != NULL; ipa2 = ipa2->next)
- {
+ for (ip_address_item * ipa2 = running_interfaces; ipa2; ipa2 = ipa2->next)
if ((Ustrchr(ipa2->address, ':') != NULL) == ipv6)
local_interface_data = add_unique_interface(local_interface_data,
- ipa2);
- }
+ ipa2);
}
else
{
void
host_mask(int count, int *binary, int mask)
{
-int i;
if (mask < 0) mask = 99999;
-for (i = 0; i < count; i++)
+for (int i = 0; i < count; i++)
{
int wordmask;
if (mask == 0) wordmask = 0;
int
host_nmtoa(int count, int *binary, int mask, uschar *buffer, int sep)
{
-int i, j;
+int j;
uschar *tt = buffer;
if (count == 1)
{
j = binary[0];
- for (i = 24; i >= 0; i -= 8)
+ for (int i = 24; i >= 0; i -= 8)
tt += sprintf(CS tt, "%d.", (j >> i) & 255);
}
else
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
j = binary[i];
tt += sprintf(CS tt, "%04x%c%04x%c", (j >> 16) & 0xffff, sep, j & 0xffff, sep);
BOOL
host_is_in_net(const uschar *host, const uschar *net, int maskoffset)
{
-int i;
int address[4];
int incoming[4];
int mlen;
/* Else do the masked comparison. */
-for (i = 0; i < size; i++)
+for (int i = 0; i < size; i++)
{
int mask;
if (mlen == 0) mask = 0;
if (h->address != NULL)
{
- ip_address_item *ip;
if (Ustrcmp(h->address, "0.0.0.0") == 0) goto FOUND_LOCAL;
- for (ip = local_interface_data; ip != NULL; ip = ip->next)
+ for (ip_address_item * ip = local_interface_data; ip; ip = ip->next)
if (Ustrcmp(h->address, ip->address) == 0) goto FOUND_LOCAL;
yield = HOST_FOUND; /* At least one remote address has been found */
}
/* If the host has aliases, build a copy of the alias list */
-if (hosts->h_aliases != NULL)
+if (hosts->h_aliases)
{
int count = 1;
- uschar **aliases, **ptr;
- for (aliases = USS hosts->h_aliases; *aliases != NULL; aliases++) count++;
+ uschar **ptr;
+ for (uschar ** aliases = USS hosts->h_aliases; *aliases; aliases++) count++;
ptr = sender_host_aliases = store_get_perm(count * sizeof(uschar *));
- for (aliases = USS hosts->h_aliases; *aliases != NULL; aliases++)
+ for (uschar ** aliases = USS hosts->h_aliases; *aliases; aliases++)
{
uschar *s = *aliases;
int len = Ustrlen(s) + 1;
{
int old_pool, rc;
int sep = 0;
-uschar *hname, *save_hostname;
+uschar *save_hostname;
uschar **aliases;
uschar buffer[256];
uschar *ordername;
const uschar *list = host_lookup_order;
-dns_record *rr;
dns_answer dnsa;
dns_scan dnss;
store_pool = POOL_PERM; /* Save names in permanent storage */
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+ for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
rr;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
- if (rr->type == T_PTR)
- count++;
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR)
+ count++;
/* Get store for the list of aliases. For compatibility with
gethostbyaddr, we make an empty list if there are none. */
/* Re-scan and extract the names */
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+ for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
rr;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR)
{
- uschar *s = NULL;
- if (rr->type != T_PTR) continue;
- s = store_get(ssize);
+ uschar * s = store_get(ssize);
/* If an overlong response was received, the data will have been
truncated and dn_expand may fail. */
save_hostname = sender_host_name; /* Save for error messages */
aliases = sender_host_aliases;
-for (hname = sender_host_name; hname; hname = *aliases++)
+for (uschar * hname = sender_host_name; hname; hname = *aliases++)
{
int rc;
BOOL ok = FALSE;
|| rc == HOST_FOUND_LOCAL
)
{
- host_item *hh;
HDEBUG(D_host_lookup) debug_printf("checking addresses for %s\n", hname);
/* If the forward lookup was not secure we cancel the is-secure variable */
h.dnssec == DS_YES ? "DNSSEC verified (AD)" : "unverified");
if (h.dnssec != DS_YES) sender_host_dnssec = FALSE;
- for (hh = &h; hh; hh = hh->next)
+ for (host_item * hh = &h; hh; hh = hh->next)
if (host_is_in_net(hh->address, sender_host_address, 0))
{
HDEBUG(D_host_lookup) debug_printf(" %s OK\n", hh->address);
host_find_byname(host_item *host, const uschar *ignore_target_hosts, int flags,
const uschar **fully_qualified_name, BOOL local_host_check)
{
-int i, yield, times;
-uschar **addrlist;
+int yield, times;
host_item *last = NULL;
BOOL temp_error = FALSE;
#if HAVE_IPV6
/* Loop to look up both kinds of address in an IPv6 world */
-for (i = 1; i <= times;
+for (int i = 1; i <= times;
#if HAVE_IPV6
af = AF_INET, /* If 2 passes, IPv4 on the second */
#endif
ipv4_addr = hostdata->h_length == sizeof(struct in_addr);
- for (addrlist = USS hostdata->h_addr_list; *addrlist != NULL; addrlist++)
+ for (uschar ** addrlist = USS hostdata->h_addr_list; *addrlist; addrlist++)
{
uschar *text_address =
host_ntoa(ipv4_addr? AF_INET:AF_INET6, *addrlist, NULL, NULL);
HDEBUG(D_host_lookup)
{
- const host_item *h;
- if (fully_qualified_name != NULL)
+ if (fully_qualified_name)
debug_printf("fully qualified name = %s\n", *fully_qualified_name);
debug_printf("%s looked up these IP addresses:\n",
#if HAVE_IPV6
"gethostbyname"
#endif
);
- for (h = host; h != last->next; h = h->next)
+ for (const host_item * h = host; h != last->next; h = h->next)
debug_printf(" name=%s address=%s\n", h->name,
- (h->address == NULL)? US"<null>" : h->address);
+ h->address ? h->address : US"<null>");
}
/* Return the found status. */
const uschar **fully_qualified_name,
BOOL dnssec_request, BOOL dnssec_require, int whichrrs)
{
-dns_record *rr;
host_item *thishostlast = NULL; /* Indicates not yet filled in anything */
BOOL v6_find_again = FALSE;
BOOL dnssec_fail = FALSE;
fully_qualified_name = NULL;
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+ for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
rr;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == type)
{
- if (rr->type == type)
- {
- dns_address *da = dns_address_from_rr(&dnsa, rr);
+ dns_address * da = dns_address_from_rr(&dnsa, rr);
- DEBUG(D_host_lookup)
- if (!da) debug_printf("no addresses extracted from A6 RR for %s\n",
- host->name);
+ DEBUG(D_host_lookup)
+ if (!da) debug_printf("no addresses extracted from A6 RR for %s\n",
+ host->name);
- /* This loop runs only once for A and AAAA records, but may run
- several times for an A6 record that generated multiple addresses. */
+ /* This loop runs only once for A and AAAA records, but may run
+ several times for an A6 record that generated multiple addresses. */
- for (; da; da = da->next)
- {
- #ifndef STAND_ALONE
- if (ignore_target_hosts != NULL &&
- verify_check_this_host(&ignore_target_hosts, NULL,
- host->name, da->address, NULL) == OK)
- {
- DEBUG(D_host_lookup)
- debug_printf("ignored host %s [%s]\n", host->name, da->address);
- continue;
- }
- #endif
+ for (; da; da = da->next)
+ {
+ #ifndef STAND_ALONE
+ if (ignore_target_hosts != NULL &&
+ verify_check_this_host(&ignore_target_hosts, NULL,
+ host->name, da->address, NULL) == OK)
+ {
+ DEBUG(D_host_lookup)
+ debug_printf("ignored host %s [%s]\n", host->name, da->address);
+ continue;
+ }
+ #endif
- /* If this is the first address, stick it in the given host block,
- and change the name if the returned RR has a different name. */
+ /* If this is the first address, stick it in the given host block,
+ and change the name if the returned RR has a different name. */
- if (thishostlast == NULL)
- {
- if (strcmpic(host->name, rr->name) != 0)
- host->name = string_copy_dnsdomain(rr->name);
- host->address = da->address;
- host->sort_key = host->mx * 1000 + random_number(500) + randoffset;
- host->status = hstatus_unknown;
- host->why = hwhy_unknown;
- thishostlast = host;
- }
+ if (thishostlast == NULL)
+ {
+ if (strcmpic(host->name, rr->name) != 0)
+ host->name = string_copy_dnsdomain(rr->name);
+ host->address = da->address;
+ host->sort_key = host->mx * 1000 + random_number(500) + randoffset;
+ host->status = hstatus_unknown;
+ host->why = hwhy_unknown;
+ thishostlast = host;
+ }
- /* Not the first address. Check for, and ignore, duplicates. Then
- insert in the chain at a random point. */
+ /* Not the first address. Check for, and ignore, duplicates. Then
+ insert in the chain at a random point. */
- else
- {
- int new_sort_key;
- host_item *next;
-
- /* End of our local chain is specified by "thishostlast". */
-
- for (next = host;; next = next->next)
- {
- if (Ustrcmp(CS da->address, next->address) == 0) break;
- if (next == thishostlast) { next = NULL; break; }
- }
- if (next != NULL) continue; /* With loop for next address */
-
- /* Not a duplicate */
-
- new_sort_key = host->mx * 1000 + random_number(500) + randoffset;
- next = store_get(sizeof(host_item));
-
- /* New address goes first: insert the new block after the first one
- (so as not to disturb the original pointer) but put the new address
- in the original block. */
-
- if (new_sort_key < host->sort_key)
- {
- *next = *host; /* Copies port */
- host->next = next;
- host->address = da->address;
- host->sort_key = new_sort_key;
- if (thishostlast == host) thishostlast = next; /* Local last */
- if (*lastptr == host) *lastptr = next; /* Global last */
- }
-
- /* Otherwise scan down the addresses for this host to find the
- one to insert after. */
-
- else
- {
- host_item *h = host;
- while (h != thishostlast)
- {
- if (new_sort_key < h->next->sort_key) break;
- h = h->next;
- }
- *next = *h; /* Copies port */
- h->next = next;
- next->address = da->address;
- next->sort_key = new_sort_key;
- if (h == thishostlast) thishostlast = next; /* Local last */
- if (h == *lastptr) *lastptr = next; /* Global last */
- }
- }
- }
+ else
+ {
+ int new_sort_key;
+ host_item *next;
+
+ /* End of our local chain is specified by "thishostlast". */
+
+ for (next = host;; next = next->next)
+ {
+ if (Ustrcmp(CS da->address, next->address) == 0) break;
+ if (next == thishostlast) { next = NULL; break; }
+ }
+ if (next != NULL) continue; /* With loop for next address */
+
+ /* Not a duplicate */
+
+ new_sort_key = host->mx * 1000 + random_number(500) + randoffset;
+ next = store_get(sizeof(host_item));
+
+ /* New address goes first: insert the new block after the first one
+ (so as not to disturb the original pointer) but put the new address
+ in the original block. */
+
+ if (new_sort_key < host->sort_key)
+ {
+ *next = *host; /* Copies port */
+ host->next = next;
+ host->address = da->address;
+ host->sort_key = new_sort_key;
+ if (thishostlast == host) thishostlast = next; /* Local last */
+ if (*lastptr == host) *lastptr = next; /* Global last */
+ }
+
+ /* Otherwise scan down the addresses for this host to find the
+ one to insert after. */
+
+ else
+ {
+ host_item *h = host;
+ while (h != thishostlast)
+ {
+ if (new_sort_key < h->next->sort_key) break;
+ h = h->next;
+ }
+ *next = *h; /* Copies port */
+ h->next = next;
+ next->address = da->address;
+ next->sort_key = new_sort_key;
+ if (h == thishostlast) thishostlast = next; /* Local last */
+ if (h == *lastptr) *lastptr = next; /* Global last */
+ }
+ }
}
}
}
const uschar **fully_qualified_name, BOOL *removed)
{
host_item *h, *last;
-dns_record *rr;
int rc = DNS_FAIL;
int ind_type = 0;
int yield;
if (rc == HOST_IGNORED) rc = HOST_FIND_FAILED; /* No special action */
DEBUG(D_host_lookup)
- {
- host_item *h;
- if (host->address != NULL)
+ if (host->address)
{
- if (fully_qualified_name != NULL)
+ if (fully_qualified_name)
debug_printf("fully qualified name = %s\n", *fully_qualified_name);
- for (h = host; h != last->next; h = h->next)
+ for (host_item * h = host; h != last->next; h = h->next)
debug_printf("%s %s mx=%d sort=%d %s\n", h->name,
- (h->address == NULL)? US"<null>" : h->address, h->mx, h->sort_key,
- (h->status >= hstatus_unusable)? US"*" : US"");
+ h->address ? h->address : US"<null>", h->mx, h->sort_key,
+ h->status >= hstatus_unusable ? US"*" : US"");
}
- }
yield = rc;
goto out;
last = NULL; /* Indicates that not even the first item is filled yet */
-for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == ind_type)
{
if (ind_type == T_SRV)
{
- host_item **pptr;
+ host_item ** pptr;
if (host == last && host->name[0] == 0)
{
DEBUG(D_host_lookup)
{
- if (fully_qualified_name != NULL)
+ if (fully_qualified_name)
debug_printf("fully qualified name = %s\n", *fully_qualified_name);
debug_printf("host_find_bydns yield = %s (%d); returned hosts:\n",
- (yield == HOST_FOUND)? "HOST_FOUND" :
- (yield == HOST_FOUND_LOCAL)? "HOST_FOUND_LOCAL" :
- (yield == HOST_FIND_SECURITY)? "HOST_FIND_SECURITY" :
- (yield == HOST_FIND_AGAIN)? "HOST_FIND_AGAIN" :
- (yield == HOST_FIND_FAILED)? "HOST_FIND_FAILED" : "?",
+ yield == HOST_FOUND ? "HOST_FOUND" :
+ yield == HOST_FOUND_LOCAL ? "HOST_FOUND_LOCAL" :
+ yield == HOST_FIND_SECURITY ? "HOST_FIND_SECURITY" :
+ yield == HOST_FIND_AGAIN ? "HOST_FIND_AGAIN" :
+ yield == HOST_FIND_FAILED ? "HOST_FIND_FAILED" : "?",
yield);
for (h = host; h != last->next; h = h->next)
{
printf("> ");
while (Ufgets(buffer, 256, stdin) != NULL)
{
- int i;
int x[4];
int len = Ustrlen(buffer);
len = host_aton(buffer, x);
printf("length = %d ", len);
- for (i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
{
printf("%04x ", (x[i] >> 16) & 0xffff);
printf("%04x ", x[i] & 0xffff);
size_t slen;
uschar *sptr;
gstring * yield = NULL;
-int i = 0, j; /* compiler quietening */
+int i = 0; /* compiler quietening */
uschar c = 0; /* compiler quietening */
BOOL base64mode = FALSE;
BOOL lastsep = FALSE;
i = 0;
}
- for (j = 0; j < 2; j++, s++) switch (i++)
+ for (int j = 0; j < 2; j++, s++) switch (i++)
{
case 0:
/* Top 6 bits of the first octet */
ip_connectedsocket(int type, const uschar * hostname, int portlo, int porthi,
int timeout, host_item * connhost, uschar ** errstr, const blob * fastopen_blob)
{
-int namelen, port;
+int namelen;
host_item shost;
-host_item *h;
int af = 0, fd, fd4 = -1, fd6 = -1;
shost.next = NULL;
/* Try to connect to the server - test each IP till one works */
-for (h = &shost; h; h = h->next)
+for (host_item * h = &shost; h; h = h->next)
{
fd = Ustrchr(h->address, ':') != 0
? fd6 < 0 ? (fd6 = ip_socket(type, af = AF_INET6)) : fd6
goto bad;
}
- for(port = portlo; port <= porthi; port++)
+ for (int port = portlo; port <= porthi; port++)
if (ip_connect(fd, af, h->address, port, timeout, fastopen_blob) == 0)
{
if (fd != fd6) close(fd6);
void
dscp_list_to_stream(FILE *stream)
{
-int i;
-for (i=0; i < dscp_table_size; ++i)
+for (int i = 0; i < dscp_table_size; ++i)
fprintf(stream, "%s\n", dscp_table[i].name);
}
static void
write_syslog(int priority, const uschar *s)
{
-int len, pass;
+int len;
int linecount = 0;
if (!syslog_pid && LOGGING(pid))
/* First do a scan through the message in order to determine how many lines
it is going to end up as. Then rescan to output it. */
-for (pass = 0; pass < 2; pass++)
+for (int pass = 0; pass < 2; pass++)
{
- int i;
- int tlen;
const uschar * ss = s;
- for (i = 1, tlen = len; tlen > 0; i++)
+ for (int i = 1, tlen = len; tlen > 0; i++)
{
int plen = tlen;
uschar *nlptr = Ustrchr(ss, '\n');
if (flags & LOG_REJECT)
{
- header_line *h;
-
if (header_list && LOGGING(rejected_header))
{
uschar * p = g->s + g->ptr;
/* A header with a NULL text is an unfilled in Received: header */
- for (h = header_list; h; h = h->next) if (h->text)
+ for (header_line * h = header_list; h; h = h->next) if (h->text)
{
BOOL fitted = string_format(p, LOG_BUFFER_SIZE - g->ptr,
"%c %s", h->type, h->text);
hash_offset,
hash_offlen,
hash_slotnm;
-int loop;
/* Keep picky compilers happy */
do_cache = do_cache;
uschar * cur_pos = cur_offset + cdbp->cdb_map;
uschar * end_pos = end_offset + cdbp->cdb_map;
- for (loop = 0; (loop < hash_offlen); ++loop)
+ for (int loop = 0; (loop < hash_offlen); ++loop)
{
item_hash = cdb_unpack(cur_pos);
cur_pos += 4;
#endif /* HAVE_MMAP */
-for (loop = 0; (loop < hash_offlen); ++loop)
+for (int loop = 0; (loop < hash_offlen); ++loop)
{
uschar packbuf[8];
struct cdb_state * cdbp = handle;
#ifdef HAVE_MMAP
- if (cdbp->cdb_map) {
- munmap(CS cdbp->cdb_map, cdbp->filelen);
- if (cdbp->cdb_map == cdbp->cdb_offsets)
+if (cdbp->cdb_map)
+ {
+ munmap(CS cdbp->cdb_map, cdbp->filelen);
+ if (cdbp->cdb_map == cdbp->cdb_offsets)
cdbp->cdb_offsets = NULL;
- }
+ }
#endif /* HAVE_MMAP */
- (void)close(cdbp->fileno);
+(void)close(cdbp->fileno);
}
gstring * yield = string_get(256);
-dns_record * rr;
dns_answer dnsa;
dns_scan dnss;
/* Search the returned records */
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); rr;
+ for (dns_record * rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == searchtype)
{
if (*do_cache > rr->ttl)
if (type == T_A || type == T_AAAA || type == T_ADDRESSES)
{
- dns_address *da;
- for (da = dns_address_from_rr(&dnsa, rr); da; da = da->next)
+ for (dns_address * da = dns_address_from_rr(&dnsa, rr); da; da = da->next)
{
if (yield->ptr) yield = string_catn(yield, outsep, 1);
yield = string_cat(yield, da->address);
isc_stmt_handle stmth = NULL;
XSQLDA *out_sqlda;
XSQLVAR *var;
+int i;
char buffer[256];
ISC_STATUS status[20], *statusp = status;
gstring * result;
-int i;
int yield = DEFER;
ibase_connection *cn;
uschar *server_copy = NULL;
nextinlist temporary buffer. The copy of the string that is used for caching
has the password removed. This copy is also used for debugging output. */
-for (i = 2; i > 0; i--)
+for (int i = 2; i > 0; i--)
{
uschar *pp = Ustrrchr(server, '|');
if (cn->dbh == NULL || cn->transh == NULL)
{
- char *dpb, *p;
+ char *dpb;
short dpb_length;
static char trans_options[] =
{ isc_tpb_version3, isc_tpb_read, isc_tpb_read_committed,
*dpb++ = isc_dpb_version1;
*dpb++ = isc_dpb_user_name;
*dpb++ = strlen(sdata[1]);
- for (p = sdata[1]; *p;)
+ for (char * p = sdata[1]; *p;)
*dpb++ = *p++;
*dpb++ = isc_dpb_password;
*dpb++ = strlen(sdata[2]);
- for (p = sdata[2]; *p;)
+ for (char * p = sdata[2]; *p;)
*dpb++ = *p++;
dpb_length = dpb - buffer;
}
else
- for (i = 0; i < out_sqlda->sqld; i++)
+ for (int i = 0; i < out_sqlda->sqld; i++)
{
int len = fetch_field(buffer, sizeof(buffer), &out_sqlda->sqlvar[i]);
else if (buffer[0] == 0 || Ustrchr(buffer, ' ') != NULL)
{
- int j;
-
result = string_catn(result, US "\"", 1);
- for (j = 0; j < len; j++)
+ for (int j = 0; j < len; j++)
{
if (buffer[j] == '\"' || buffer[j] == '\\')
result = string_cat(result, US "\\", 1);
struct timeval timeout;
struct timeval *timeoutptr = NULL;
-uschar *attr;
-uschar **attrp;
gstring * data = NULL;
uschar *dn = NULL;
uschar *host;
/* Count the attributes; we need this later to tell us how to format results */
-for (attrp = USS ludp->lud_attrs; attrp && *attrp; attrp++)
+for (uschar ** attrp = USS ludp->lud_attrs; attrp && *attrp; attrp++)
attrs_requested++;
/* See if we can find a cached connection to this host. The port is not
sequence of name=value pairs, separated by (space), with the value always in quotes.
If there are multiple values, they are given within the quotes, comma separated. */
- else for (attr = US ldap_first_attribute(lcp->ld, e, &ber);
+ else for (uschar * attr = US ldap_first_attribute(lcp->ld, e, &ber);
attr; attr = US ldap_next_attribute(lcp->ld, e, ber))
{
DEBUG(D_lookup) debug_printf("LDAP attr loop\n");
internal quotes, backslashes, newlines, and must double commas. */
if (attrs_requested != 1)
- {
- int j;
- for (j = 0; j < len; j++)
+ for (int j = 0; j < len; j++)
{
if (value[j] == '\n')
data = string_catn(data, US"\\n", 2);
data = string_catn(data, value+j, 1);
}
}
- }
/* For single attributes, just double commas */
else
- {
- int j;
- for (j = 0; j < len; j++)
+ for (int j = 0; j < len; j++)
if (value[j] == ',')
data = string_catn(data, US",,", 2);
else
data = string_catn(data, value+j, 1);
- }
/* Move on to the next value */
if (user != NULL)
{
- uschar *s;
uschar *t = user;
- for (s = user; *s != 0; s++)
+ for (uschar * s = user; *s != 0; s++)
{
int c, d;
if (*s == '%' && isxdigit(c=s[1]) && isxdigit(d=s[2]))
lf_check_file(int fd, uschar *filename, int s_type, int modemask, uid_t *owners,
gid_t *owngroups, const char *type, uschar **errmsg)
{
-int i;
struct stat statbuf;
if ((fd >= 0 && fstat(fd, &statbuf) != 0) ||
if (owners != NULL)
{
BOOL uid_ok = FALSE;
- for (i = 1; i <= (int)owners[0]; i++)
+ for (int i = 1; i <= (int)owners[0]; i++)
if (owners[i] == statbuf.st_uid) { uid_ok = TRUE; break; }
if (!uid_ok)
{
if (owngroups != NULL)
{
BOOL gid_ok = FALSE;
- for (i = 1; i <= (int)owngroups[0]; i++)
+ for (int i = 1; i <= (int)owngroups[0]; i++)
if (owngroups[i] == statbuf.st_gid) { gid_ok = TRUE; break; }
if (!gid_ok)
{
if (value[0] == 0 || Ustrpbrk(value, " \t\n\r") != NULL || value[0] == '\"')
{
- int j;
result = string_catn(result, US"\"", 1);
- for (j = 0; j < vlength; j++)
+ for (int j = 0; j < vlength; j++)
{
if (value[j] == '\"' || value[j] == '\\')
result = string_catn(result, US"\\", 1);
nextinlist temporary buffer. The copy of the string that is used for caching
has the password removed. This copy is also used for debugging output. */
-for (i = 3; i > 0; i--)
+for (int i = 3; i > 0; i--)
{
uschar *pp = Ustrrchr(server, '/');
if (pp == NULL)
result = string_catn(result, US"\n", 1);
if (num_fields != 1)
- for (i = 0; i < num_fields; i++)
+ for (int i = 0; i < num_fields; i++)
result = lf_quote(US fields[i].name, US mysql_row_data[i], lengths[i],
result);
nisplus_find(void *handle, uschar *filename, const uschar *query, int length,
uschar **result, uschar **errmsg, uint *do_cache)
{
-int i;
int error_error = FAIL;
const uschar * field_name = NULL;
nis_result *nrt = NULL;
with their names. */
eo = &(eno->zo_data.objdata_u.en_data);
-for (i = 0; i < eo->en_cols.en_cols_len; i++)
+for (int i = 0; i < eo->en_cols.en_cols_len; i++)
{
table_col *tc = ta->ta_cols.ta_cols_val + i;
entry_col *ec = eo->en_cols.en_cols_val + i;
if (value[0] == 0 || Ustrchr(value, ' ') != NULL)
{
- int j;
yield = string_catn(yield, US"\"", 1);
- for (j = 0; j < len; j++)
+ for (int j = 0; j < len; j++)
{
if (value[j] == '\"' || value[j] == '\\')
yield = string_catn(yield, US"\\", 1);
Ora_Define *def = NULL;
void *hda = NULL;
-int i;
int yield = DEFER;
unsigned int num_fields = 0;
gstring * result = NULL;
nextinlist temporary buffer. The copy of the string that is used for caching
has the password removed. This copy is also used for debugging output. */
-for (i = 3; i > 0; i--)
+for (int i = 3; i > 0; i--)
{
uschar *pp = Ustrrchr(server, '/');
if (pp == NULL)
/* Multiple fields - precede by file name, removing {lead,trail}ing WS */
- else for (i = 0; i < num_fields; i++)
+ else for (int i = 0; i < num_fields; i++)
{
int slen;
uschar *s = US desc[i].buf;
if (desc[i].dbtype != INT_TYPE && desc[i].dbtype != FLOAT_TYPE &&
(def[i].buf[0] == 0 || strchr(def[i].buf, ' ') != NULL))
{
- int j;
result = string_catn(result, "\"", 1);
- for (j = 0; j < def[i].col_retlen; j++)
+ for (int j = 0; j < def[i].col_retlen; j++)
{
if (def[i].buf[j] == '\"' || def[i].buf[j] == '\\')
result = string_catn(result, "\\", 1);
PGconn *pg_conn = NULL;
PGresult *pg_result = NULL;
-int i;
gstring * result = NULL;
int yield = DEFER;
unsigned int num_fields, num_tuples;
nextinlist temporary buffer. The copy of the string that is used for caching
has the password removed. This copy is also used for debugging output. */
-for (i = 2; i >= 0; i--)
+for (int i = 2; i >= 0; i--)
{
uschar *pp = Ustrrchr(server, '/');
if (!pp)
/* Get the fields and construct the result string. If there is more than one
row, we insert '\n' between them. */
-for (i = 0; i < num_tuples; i++)
+for (int i = 0; i < num_tuples; i++)
{
if (result)
result = string_catn(result, US"\n", 1);
result = string_catn(result,
US PQgetvalue(pg_result, i, 0), PQgetlength(pg_result, i, 0));
else
- {
- int j;
- for (j = 0; j < num_fields; j++)
+ for (int j = 0; j < num_fields; j++)
{
uschar *tmp = US PQgetvalue(pg_result, i, j);
result = lf_quote(US PQfname(pg_result, j), tmp, Ustrlen(tmp), result);
}
- }
}
/* If result is NULL then no data has been found and so we return FAIL. */
This copy is also used for debugging output. */
memset(sdata, 0, sizeof(sdata)) /* Set all to NULL */;
-for (i = 2; i > 0; i--)
+for (int i = 2; i > 0; i--)
{
uschar *pp = Ustrrchr(server, '/');
/* split string on whitespace into argv */
{
uschar * argv[32];
- int i;
const uschar * s = command;
- int siz, ptr;
+ int siz, ptr, i;
uschar c;
while (isspace(*s)) s++;
/* NOTE: For now support 1 nested array result. If needed a limitless
result can be parsed */
- for (i = 0; i < redis_reply->elements; i++)
+ for (int i = 0; i < redis_reply->elements; i++)
{
entry = redis_reply->element[i];
result = string_catn(result, US entry->str, entry->len);
break;
case REDIS_REPLY_ARRAY:
- for (j = 0; j < entry->elements; j++)
+ for (int j = 0; j < entry->elements; j++)
{
tentry = entry->element[j];
sqlite_callback(void *arg, int argc, char **argv, char **azColName)
{
gstring * res = *(gstring **)arg;
-int i;
/* For second and subsequent results, insert \n */
if (argc > 1)
{
/* For multiple fields, include the field name too */
- for (i = 0; i < argc; i++)
+ for (int i = 0; i < argc; i++)
{
uschar *value = US((argv[i] != NULL)? argv[i]:"<NULL>");
res = lf_quote(US azColName[i], value, Ustrlen(value), res);
options_from_list(optionlist * opts, unsigned nopt,
const uschar * section, uschar * group)
{
-int i;
const uschar * s;
uschar buf[64];
macros that have substrings are always discovered first during
expansion. */
-for (i = 0; i < nopt; i++) if (*(s = US opts[i].name) && *s != '*')
+for (int i = 0; i < nopt; i++) if (*(s = US opts[i].name) && *s != '*')
{
if (group)
spf(buf, sizeof(buf), CUS"_OPT_%T_%T_%T", section, group, s);
void
features_malware(void)
{
-const struct scan * sc;
const uschar * s;
uschar * t;
uschar buf[64];
spf(buf, sizeof(buf), US"_HAVE_MALWARE_");
-for (sc = m_scans; sc->scancode != -1; sc++)
+for (const struct scan * sc = m_scans; sc->scancode != -1; sc++)
{
- for(s = sc->name, t = buf+14; *s; s++) if (*s != '-') *t++ = toupper(*s);
+ for (s = sc->name, t = buf+14; *s; s++) if (*s != '-')
+ *t++ = toupper(*s);
*t = '\0';
builtin_macro_create(buf);
}
/* "virus(es) found" if virus number is > 0 */
if (drweb_vnum)
{
- int i;
gstring * g = NULL;
/* setup default virus name */
drweb_re = m_pcre_compile(drweb_re_str, &errstr);
/* read and concatenate virus names into one string */
- for (i = 0; i < drweb_vnum; i++)
+ for (int i = 0; i < drweb_vnum; i++)
{
int ovector[10*3];
#ifndef DISABLE_MAL_FSECURE
case M_FSEC: /* "fsecure" scanner type ---------------------------------- */
{
- int i, j, bread = 0;
+ int i, bread = 0;
uschar * file_name;
uschar av_buffer[1024];
static uschar *cmdopt[] = { US"CONFIGURE\tARCHIVE\t1\n",
return m_panic_defer_3(scanent, CUS callout_address,
string_sprintf("unable to read answer %d (%s)", i, strerror(errno)),
malware_daemon_ctx.sock);
- for (j = 0; j < bread; j++)
+ for (int j = 0; j < bread; j++)
if (av_buffer[j] == '\r' || av_buffer[j] == '\n')
av_buffer[j] ='@';
}
void
malware_show_supported(FILE * f)
{
-struct scan * sc;
fprintf(f, "Malware:");
-for (sc = m_scans; sc->scancode != (scanner_t)-1; sc++) fprintf(f, " %s", sc->name);
+for (struct scan * sc = m_scans; sc->scancode != (scanner_t)-1; sc++) fprintf(f, " %s", sc->name);
fprintf(f, "\n");
}
if (Ustrcmp(pattern, "@[]") == 0)
{
- ip_address_item *ip;
int slen = Ustrlen(s);
if (s[0] != '[' && s[slen-1] != ']') return FAIL;
- for (ip = host_find_interfaces(); ip != NULL; ip = ip->next)
+ for (ip_address_item * ip = host_find_interfaces(); ip; ip = ip->next)
if (Ustrncmp(ip->address, s+1, slen - 2) == 0
&& ip->address[slen - 2] == 0)
return OK;
if (valueptr)
{
const uschar *key = get_check_key(arg, type);
- namedlist_cacheblock *p;
- for (p = nb->cache_data; p; p = p->next)
+
+ for (namedlist_cacheblock * p = nb->cache_data; p; p = p->next)
if (Ustrcmp(key, p->key) == 0)
{
*valueptr = p->data;
if (pattern[0] == '@' && pattern[1] == '@')
{
int watchdog = 50;
- const uschar *key;
uschar *list, *ss;
uschar buffer[1024];
/* Loop for handling chains. The last item in any list may be of the form
">name" in order to chain on to another list. */
- for (key = sdomain + 1; key != NULL && watchdog-- > 0; )
+ for (const uschar * key = sdomain + 1; key && watchdog-- > 0; )
{
int sep = 0;
const uschar **listptr, unsigned int *cache_bits, int expand_setup, int sep,
const uschar **valueptr)
{
-uschar *p;
check_address_block ab;
unsigned int *local_cache_bits = cache_bits;
original address. */
sprintf(CS big_buffer, "%.*s", big_buffer_size - 1, address);
-for (p = big_buffer + Ustrlen(big_buffer) - 1; p >= big_buffer; p--)
+for (uschar * p = big_buffer + Ustrlen(big_buffer) - 1; p >= big_buffer; p--)
{
if (!caseless && *p == '@') break;
*p = tolower(*p);
header[num_copied] = '\0';
/* return 0 for EOF or empty line */
-if ((c == EOF) || (num_copied == 1))
- return 0;
-else
- return 1;
+return c == EOF || num_copied == 1 ? 0 : 1;
}
/* parse headers, set up expansion variables */
while (mime_get_header(f, header))
- {
- struct mime_header * mh;
/* look for interesting headers */
- for (mh = mime_header_list;
+ for (struct mime_header * mh = mime_header_list;
mh < mime_header_list + mime_header_list_size;
mh++) if (strncmpic(mh->name, header, mh->namelen) == 0)
{
while (*p)
{
- mime_parameter * mp;
-
DEBUG(D_acl) debug_printf_indent("MIME: considering paramlist '%s'\n", p);
if ( !mime_filename
else
/* look for interesting parameters */
- for (mp = mime_parameter_list;
+ for (mime_parameter * mp = mime_parameter_list;
mp < mime_parameter_list + nelem(mime_parameter_list);
mp++
) if (strncmpic(mp->name, p, mp->namelen) == 0)
}
}
}
- }
/* set additional flag variables (easier access) */
if ( mime_content_type
vfprintf(f, format, ap);
va_end(ap);
-if (addr != NULL)
+if (addr)
{
fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
- for (; addr != NULL; addr = addr->next)
+ for (; addr; addr = addr->next)
{
- uschar *parent = (addr->parent == NULL)? NULL : addr->parent->address;
+ uschar * parent = addr->parent ? addr->parent->address : NULL;
fprintf(f, " %s", addr->address);
- if (parent != NULL) fprintf(f, " <%s>", parent);
+ if (parent) fprintf(f, " <%s>", parent);
if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
- if (addr->message != NULL) fprintf(f, ": %s", addr->message);
+ if (addr->message) fprintf(f, ": %s", addr->message);
fprintf(f, "\n");
}
}
int pid, fd;
uschar *s, *t;
FILE *f;
-error_block *e;
-for (e = eblock; e != NULL; e = e->next)
- {
+for (error_block * e = eblock; e; e = e->next)
if (e->text2 != NULL)
log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
rname, e->text1, e->text2);
else
log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
e->text1);
- }
-if (syntax_errors_to == NULL) return TRUE;
+if (!syntax_errors_to) return TRUE;
-s = expand_string(syntax_errors_to);
-if (s == NULL)
+if (!(s = expand_string(syntax_errors_to)))
{
log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
syntax_errors_to, expand_string_message);
fprintf(f, "To: %s\n", s);
fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
-if (custom != NULL)
+if (custom)
{
- t = expand_string(custom);
- if (t == NULL)
+ if (!(t = expand_string(custom)))
{
log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
custom, expand_string_message);
fprintf(f, "The %s router encountered the following error(s):\n\n",
rname);
-for (e = eblock; e != NULL; e = e->next)
+for (error_block * e = eblock; e; e = e->next)
{
fprintf(f, " %s", e->text1);
if (e->text2 != NULL)
log_write(0, LOG_PANIC_DIE, "Unable to call getifaddrs: %d %s",
errno, strerror(errno));
-struct ifaddrs *ifa;
-for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next)
+for (struct ifaddrs * ifa = ifalist; ifa; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr->sa_family != AF_INET
#if HAVE_IPV6
ip_address_item *yield = NULL;
ip_address_item *last = NULL;
ip_address_item *next;
-char *cp;
char buf[MAX_INTERFACES*sizeof(struct V_ifreq)];
struct sockaddr *addrp;
size_t len = 0;
struct to some aligned memory before looking at the field in the fixed part to
find its length, and then recopy the correct length. */
-for (cp = buf; cp < buf + ifc.V_ifc_len; cp += len)
+for (char * cp = buf; cp < buf + ifc.V_ifc_len; cp += len)
{
memcpy(CS &ifreq, cp, sizeof(ifreq));
int
pdkim_hashname_to_hashtype(const uschar * s, unsigned len)
{
-int i;
if (!len) len = Ustrlen(s);
-for (i = 0; i < nelem(pdkim_hashes); i++)
+for (int i = 0; i < nelem(pdkim_hashes); i++)
if (Ustrncmp(s, pdkim_hashes[i].dkim_hashname, len) == 0)
return i;
return -1;
pdkim_cstring_to_canons(const uschar * s, unsigned len,
int * canon_head, int * canon_body)
{
-int i;
if (!len) len = Ustrlen(s);
-for (i = 0; pdkim_combined_canons[i].str; i++)
+for (int i = 0; pdkim_combined_canons[i].str; i++)
if ( Ustrncmp(s, pdkim_combined_canons[i].str, len) == 0
&& len == Ustrlen(pdkim_combined_canons[i].str))
{
void
pdkim_quoteprint(const uschar *data, int len)
{
-int i;
-for (i = 0; i < len; i++)
+for (int i = 0; i < len; i++)
{
const int c = data[i];
switch (c)
void
pdkim_hexprint(const uschar *data, int len)
{
-int i;
-if (data) for (i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
+if (data) for (int i = 0 ; i < len; i++) debug_printf("%02x", data[i]);
else debug_printf("<NULL>");
debug_printf("\n");
}
{
BOOL past_field_name = FALSE;
BOOL seen_wsp = FALSE;
-const uschar * p;
uschar * relaxed = store_get(len+3);
uschar * q = relaxed;
-for (p = header; p - header < len; p++)
+for (const uschar * p = header; p - header < len; p++)
{
uschar c = *p;
pdkim_parse_sig_header(pdkim_ctx * ctx, uschar * raw_hdr)
{
pdkim_signature * sig;
-uschar *p, *q;
+uschar *q;
gstring * cur_tag = NULL;
gstring * cur_val = NULL;
BOOL past_hname = FALSE;
BOOL in_b_val = FALSE;
int where = PDKIM_HDR_LIMBO;
-int i;
sig = store_get(sizeof(pdkim_signature));
memset(sig, 0, sizeof(pdkim_signature));
q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1);
-for (p = raw_hdr; ; p++)
+for (uschar * p = raw_hdr; ; p++)
{
char c = *p;
uschar * elem;
if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
- for(i = 0; i < nelem(pdkim_keytypes); i++)
+ for (int i = 0; i < nelem(pdkim_keytypes); i++)
if (Ustrcmp(elem, pdkim_keytypes[i]) == 0)
{ sig->keytype = i; break; }
if ((elem = string_nextinlist(&list, &sep, NULL, 0)))
- for (i = 0; i < nelem(pdkim_hashes); i++)
+ for (int i = 0; i < nelem(pdkim_hashes); i++)
if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0)
{ sig->hashtype = i; break; }
}
&sig->canon_headers, &sig->canon_body);
break;
case 'q': /* Query method (for pubkey)*/
- for (i = 0; pdkim_querymethods[i]; i++)
+ for (int i = 0; pdkim_querymethods[i]; i++)
if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0)
{
sig->querymethod = i; /* we never actually use this */
if (!relaxed_data)
{
BOOL seen_wsp = FALSE;
- const uschar * p, * r;
int q = 0;
/* We want to be able to free this else we allocate
relaxed_data = store_malloc(sizeof(blob) + orig_data->len+1);
relaxed_data->data = US (relaxed_data+1);
- for (p = orig_data->data, r = p + orig_data->len; p < r; p++)
+ for (const uschar * p = orig_data->data, * r = p + orig_data->len; p < r; p++)
{
char c = *p;
if (c == '\r')
static void
pdkim_finish_bodyhash(pdkim_ctx * ctx)
{
-pdkim_bodyhash * b;
-pdkim_signature * sig;
-
-for (b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
+for (pdkim_bodyhash * b = ctx->bodyhash; b; b = b->next) /* Finish hashes */
{
DEBUG(D_acl) debug_printf("PDKIM: finish bodyhash %d/%d/%ld len %ld\n",
b->hashtype, b->canon_method, b->bodylength, b->signed_body_bytes);
}
/* Traverse all signatures */
-for (sig = ctx->sig; sig; sig = sig->next)
+for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
{
- b = sig->calc_body_hash;
+ pdkim_bodyhash * b = sig->calc_body_hash;
DEBUG(D_acl)
{
static void
pdkim_body_complete(pdkim_ctx * ctx)
{
-pdkim_bodyhash * b;
-
/* In simple body mode, if any empty lines were buffered,
replace with one. rfc 4871 3.4.3 */
/*XXX checking the signed-body-bytes is a gross hack; I think
it indicates that all linebreaks should be buffered, including
the one terminating a text line */
-for (b = ctx->bodyhash; b; b = b->next)
+for (pdkim_bodyhash * b = ctx->bodyh