Example #1
0
File: dns.c Project: loganaden/exim
dns_address *
dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
{
dns_address * yield = NULL;
uschar * dnsa_lim = dnsa->answer + dnsa->answerlen;

if (rr->type == T_A)
  {
  uschar *p = US rr->data;
  if (p + 4 <= dnsa_lim)
    {
    yield = store_get(sizeof(dns_address) + 20);
    (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    yield->next = NULL;
    }
  }

#if HAVE_IPV6

else
  {
  if (rr->data + 16 <= dnsa_lim)
    {
    yield = store_get(sizeof(dns_address) + 50);
    inet_ntop(AF_INET6, US rr->data, CS yield->address, 50);
    yield->next = NULL;
    }
  }
#endif  /* HAVE_IPV6 */

return yield;
}
Example #2
0
File: dns.c Project: Chaohua/exim
dns_address *
dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
{
dns_address *yield = NULL;

dnsa = dnsa;    /* Stop picky compilers warning */

if (rr->type == T_A)
  {
  uschar *p = (uschar *)(rr->data);
  yield = store_get(sizeof(dns_address) + 20);
  (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  yield->next = NULL;
  }

#if HAVE_IPV6

else
  {
  yield = store_get(sizeof(dns_address) + 50);
  inet_ntop(AF_INET6, (uschar *)(rr->data), CS yield->address, 50);
  yield->next = NULL;
  }
#endif  /* HAVE_IPV6 */

return yield;
}
Example #3
0
int
tls_import_cert(const uschar * buf, void ** cert)
{
    void * reset_point = store_get(0);
    gnutls_datum_t datum;
    gnutls_x509_crt_t crt = *(gnutls_x509_crt_t *)cert;
    int fail = 0;

    if (crt)
        gnutls_x509_crt_deinit(crt);
    else
        gnutls_global_init();

    gnutls_x509_crt_init(&crt);

    datum.data = string_unprinting(US buf);
    datum.size = Ustrlen(datum.data);
    if ((fail = gnutls_x509_crt_import(crt, &datum, GNUTLS_X509_FMT_PEM)))
    {
        log_write(0, LOG_MAIN, "TLS error in certificate import: %s",
                  gnutls_strerror(fail));
        fail = 1;
    }
    else
        *cert = (void *)crt;

    store_reset(reset_point);
    return fail;
}
Example #4
0
File: json.c Project: Exim/exim
static void *
json_malloc(size_t nbytes)
{
void * p = store_get((int)nbytes);
/* debug_printf("%s %d: %p\n", __FUNCTION__, (int)nbytes, p); */
return p;
}
Example #5
0
static pcre_list *
compile(const uschar * list)
{
int sep = 0;
uschar *regex_string;
const char *pcre_error;
int pcre_erroffset;
pcre_list *re_list_head = NULL;
pcre_list *ri;

/* precompile our regexes */
while ((regex_string = string_nextinlist(&list, &sep, NULL, 0)))
  if (strcmpic(regex_string, US"false") != 0 && Ustrcmp(regex_string, "0") != 0)
    {
    pcre *re;

    /* compile our regular expression */
    if (!(re = pcre_compile( CS regex_string,
		       0, &pcre_error, &pcre_erroffset, NULL )))
      {
      log_write(0, LOG_MAIN,
	   "regex acl condition warning - error in regex '%s': %s at offset %d, skipped.",
	   regex_string, pcre_error, pcre_erroffset);
      continue;
      }

    ri = store_get(sizeof(pcre_list));
    ri->re = re;
    ri->pcre_text = regex_string;
    ri->next = re_list_head;
    re_list_head = ri;
    }
return re_list_head;
}
Example #6
0
LONG_DOUBLE eval_expr_binop(eval_context *ctx, ast_node *tree) {
    expr_binop_data *binop_data = (expr_binop_data*)tree->data;
    switch (binop_data->op) {
    case OP_ADD:
        return eval_expr(ctx, binop_data->lhs) + eval_expr(ctx, binop_data->rhs);
    case OP_SUB:
        return eval_expr(ctx, binop_data->lhs) - eval_expr(ctx, binop_data->rhs);
    case OP_MUL:
        return eval_expr(ctx, binop_data->lhs) * eval_expr(ctx, binop_data->rhs);
    case OP_DIV:
        return eval_expr(ctx, binop_data->lhs) / eval_expr(ctx, binop_data->rhs);
    case OP_MOD: {
        // Knuthsche "floored division"
        LONG_DOUBLE a = eval_expr(ctx, binop_data->lhs);
        LONG_DOUBLE n = eval_expr(ctx, binop_data->rhs);
        return a-n*floor(a/n);
    }
    case OP_EXP:
        return pow(eval_expr(ctx, binop_data->lhs), eval_expr(ctx, binop_data->rhs));
    case OP_ASS: {
        if (binop_data->lhs->type != EXPR_VAR) return eval_emit_error(ctx, "Cannot assign to a non-variable.");
        else {
            expr_var_data *var_data = (expr_var_data*)binop_data->lhs->data;
            LONG_DOUBLE rhs_res = eval_expr(ctx, binop_data->rhs);
            store_var(store_get(), var_data->name, rhs_res);
            return rhs_res;
        }
    }
    default: return eval_emit_error(ctx, "Operator not implemented.");
    }
}
Example #7
0
File: pdkim.c Project: ytrezq/exim
static uschar *
pdkim_decode_qp(uschar * str)
{
int nchar = 0;
uschar * q;
uschar * p = str;
uschar * n = store_get(Ustrlen(str)+1);

*n = '\0';
q = n;
while (*p)
  {
  if (*p == '=')
    {
    p = pdkim_decode_qp_char(p, &nchar);
    if (nchar >= 0)
      {
      *q++ = nchar;
      continue;
      }
    }
  else
    *q++ = *p;
  p++;
  }
*q = '\0';
return n;
}
Example #8
0
static BOOL
read_nonrecipients_tree(tree_node **connect, FILE *f, uschar *buffer,
  int buffer_size)
{
tree_node *node;
int n = Ustrlen(buffer);
BOOL right = buffer[1] == 'Y';

if (n < 5) return FALSE;    /* malformed line */
buffer[n-1] = 0;            /* Remove \n */
node = store_get(sizeof(tree_node) + n - 3);
*connect = node;
Ustrcpy(node->name, buffer + 3);
node->data.ptr = NULL;

if (buffer[0] == 'Y')
  {
  if (Ufgets(buffer, buffer_size, f) == NULL ||
    !read_nonrecipients_tree(&node->left, f, buffer, buffer_size))
      return FALSE;
  }
else node->left = NULL;

if (right)
  {
  if (Ufgets(buffer, buffer_size, f) == NULL ||
    !read_nonrecipients_tree(&node->right, f, buffer, buffer_size))
      return FALSE;
  }
else node->right = NULL;

(void) count_below(*connect);
return TRUE;
}
uschar *
string_localpart_alabel_to_utf8(const uschar * alabel, uschar ** err)
{
size_t p_len = Ustrlen(alabel);
punycode_uint * p;
uschar * s;
uschar * res;
int rc;

if (alabel[0] != 'x' || alabel[1] != 'n' || alabel[2] != '-' || alabel[3] != '-')
  {
  if (err) *err = US"bad alabel prefix";
  return NULL;
  }

p_len -= 4;
p = (punycode_uint *) store_get((p_len+1) * sizeof(*p));

if ((rc = punycode_decode(p_len, CCS alabel+4, &p_len, p, NULL)) != PUNYCODE_SUCCESS)
  {
  if (err) *err = US punycode_strerror(rc);
  return NULL;
  }

s = US stringprep_ucs4_to_utf8(p, p_len, NULL, &p_len);
res = string_copyn(s, p_len);
free(s);
return res;
}
Example #10
0
uschar *
auth_xtextencode(uschar *clear, int len)
{
uschar *code;
uschar *p = (uschar *)clear;
uschar *pp;
int c = len;
int count = 1;
register int x;

/* We have to do a prepass to find out how many specials there are,
in order to get the right amount of store. */

while (c -- > 0)
  count += ((x = *p++) < 33 || x > 127 || x == '+' || x == '=')? 3 : 1;

pp = code = store_get(count);

p = (uschar *)clear;
c = len;
while (c-- > 0)
  {
  if ((x = *p++) < 33 || x > 127 || x == '+' || x == '=')
    {
    sprintf(CS pp, "+%.02x", x);   /* There's always room */
    pp += 3;
    }
  else *pp++ = x;
  }

*pp = 0;
return code;
}
Example #11
0
uschar *
tls_cert_ext_by_oid(void * cert, uschar * oid, int idx)
{
    uschar * cp1 = NULL;
    uschar * cp2;
    uschar * cp3;
    size_t siz = 0;
    unsigned int crit;
    int ret;

    ret = gnutls_x509_crt_get_extension_by_oid ((gnutls_x509_crt_t)cert,
            oid, idx, cp1, &siz, &crit);
    if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
        return g_err("ge0", __FUNCTION__, ret);

    cp1 = store_get(siz*4 + 1);

    ret = gnutls_x509_crt_get_extension_by_oid ((gnutls_x509_crt_t)cert,
            oid, idx, cp1, &siz, &crit);
    if (ret < 0)
        return g_err("ge1", __FUNCTION__, ret);

    /* binary data, DER encoded */

    /* just dump for now */
    for(cp3 = cp2 = cp1+siz; cp1 < cp2; cp3 += 3, cp1++)
        sprintf(cp3, "%.2x ", *cp1);
    cp3[-1]= '\0';

    return cp2;
}
Example #12
0
File: string.c Project: Exim/exim
uschar *
string_copy_dnsdomain(uschar *s)
{
    uschar *yield;
    uschar *ss = yield = store_get(Ustrlen(s) + 1);

    while (*s != 0)
    {
        if (*s != '\\')
        {
            *ss++ = *s++;
        }
        else if (isdigit(s[1]))
        {
            *ss++ = (s[1] - '0')*100 + (s[2] - '0')*10 + s[3] - '0';
            s += 4;
        }
        else if (*(++s) != 0)
        {
            *ss++ = *s++;
        }
    }

    *ss = 0;
    return yield;
}
Example #13
0
File: em_menu.c Project: Exim/exim
static void headersAction(Widget w, XtPointer client_data, XtPointer call_data)
{
uschar buffer[256];
header_line *h, *next;
Widget text = text_create(US client_data, text_depth);
void *reset_point;

w = w;      /* Keep picky compilers happy */
call_data = call_data;

/* Remember the point in the dynamic store so we can recover to it afterwards.
Then use Exim's function to read the header. */

reset_point = store_get(0);

sprintf(CS buffer, "%s-H", US client_data);
if (spool_read_header(buffer, TRUE, FALSE) != spool_read_OK)
  {
  if (errno == ERRNO_SPOOLFORMAT)
    {
    struct stat statbuf;
    sprintf(CS big_buffer, "%s/input/%s", spool_directory, buffer);
    if (Ustat(big_buffer, &statbuf) == 0)
      text_showf(text, "Format error in spool file %s: size=%d\n", buffer,
        statbuf.st_size);
    else text_showf(text, "Format error in spool file %s\n", buffer);
    }
  else text_showf(text, "Read error for spool file %s\n", buffer);
  store_reset(reset_point);
  return;
  }

if (sender_address != NULL)
  {
  text_showf(text, "%s sender: <%s>\n", f.sender_local ? "Local" : "Remote",
    sender_address);
  }

if (recipients_list != NULL)
  {
  int i;
  text_show(text, US"Recipients:\n");
  for (i = 0; i < recipients_count; i++)
    {
    text_showf(text, "  %s %s\n",
      (tree_search(tree_nonrecipients, recipients_list[i].address) == NULL)?
        " ":"*", recipients_list[i].address);
    }
  text_show(text, US"\n");
  }

for (h = header_list; h != NULL; h = next)
  {
  next = h->next;
  text_showf(text, "%c ", h->type);   /* Don't push h->text through a %s */
  text_show(text, h->text);           /* expansion as it may be v large */
  }

store_reset(reset_point);
}
Example #14
0
File: rfc2047.c Project: Exim/exim
static int
rfc2047_qpdecode(uschar *string, uschar **ptrptr)
{
int len = 0;
uschar *ptr;

ptr = *ptrptr = store_get(Ustrlen(string) + 1);  /* No longer than this */

while (*string != 0)
  {
  int ch = *string++;

  if (ch == '_') *ptr++ = ' ';
  else if (ch == '=')
    {
    int a = *string;
    int b = (a == 0)? 0 : string[1];
    if (!isxdigit(a) || !isxdigit(b)) return -1;  /* Bad QP string */
    *ptr++ = ((Ustrchr(hex_digits, tolower(a)) - hex_digits) << 4) +
               Ustrchr(hex_digits, tolower(b)) - hex_digits;
    string += 2;
    }
  else if (ch == ' ' || ch == '\t') return -1;    /* Whitespace is illegal */
  else *ptr++ = ch;

  len++;
  }

*ptr = 0;
return len;
}
Example #15
0
File: utf8.c Project: Exim/exim
uschar *
string_localpart_utf8_to_alabel(const uschar * utf8, uschar ** err)
{
size_t ucs4_len;
punycode_uint * p;
size_t p_len;
uschar * res;
int rc;

if (!string_is_utf8(utf8)) return string_copy(utf8);

p = (punycode_uint *) stringprep_utf8_to_ucs4(CCS utf8, -1, &ucs4_len);
p_len = ucs4_len*4;	/* this multiplier is pure guesswork */
res = store_get(p_len+5);

res[0] = 'x'; res[1] = 'n'; res[2] = res[3] = '-';

if ((rc = punycode_encode(ucs4_len, p, NULL, &p_len, CS res+4)) != PUNYCODE_SUCCESS)
  {
  DEBUG(D_expand) debug_printf("l_u2a: bad '%s'\n", punycode_strerror(rc));
  free(p);
  if (err) *err = US punycode_strerror(rc);
  return NULL;
  }
p_len += 4;
free(p);
res[p_len] = '\0';
return res;
}
Example #16
0
File: string.c Project: Exim/exim
uschar *
string_copyn(const uschar *s, int n)
{
    uschar *ss = store_get(n + 1);
    Ustrncpy(ss, s, n);
    ss[n] = 0;
    return ss;
}
Example #17
0
File: tree.c Project: fanf2/exim
void
tree_add_nonrecipient(uschar *s)
{
tree_node *node = store_get(sizeof(tree_node) + Ustrlen(s));
Ustrcpy(node->name, s);
node->data.ptr = NULL;
if (!tree_insertnode(&tree_nonrecipients, node)) store_reset(node);
}
Example #18
0
File: string.c Project: Exim/exim
uschar *
string_copy(const uschar *s)
{
    int len = Ustrlen(s) + 1;
    uschar *ss = store_get(len);
    memcpy(ss, s, len);
    return ss;
}
Example #19
0
File: tree.c Project: fanf2/exim
void
tree_add_duplicate(uschar *s, address_item *addr)
{
tree_node *node = store_get(sizeof(tree_node) + Ustrlen(s));
Ustrcpy(node->name, s);
node->data.ptr = addr;
if (!tree_insertnode(&tree_duplicates, node)) store_reset(node);
}
Example #20
0
File: string.c Project: Exim/exim
uschar *
string_copylc(const uschar *s)
{
    uschar *ss = store_get(Ustrlen(s) + 1);
    uschar *p = ss;
    while (*s != 0) *p++ = tolower(*s++);
    *p = 0;
    return ss;
}
Example #21
0
File: string.c Project: Exim/exim
uschar *
string_copynlc(uschar *s, int n)
{
    uschar *ss = store_get(n + 1);
    uschar *p = ss;
    while (n-- > 0) *p++ = tolower(*s++);
    *p = 0;
    return ss;
}
Example #22
0
ip_address_item *
os_common_find_running_interfaces(void)
{
ip_address_item *yield = store_get(sizeof(address_item));
yield->address = US"127.0.0.1";
yield->port = 0;
yield->next = NULL;

#if HAVE_IPV6
yield->next = store_get(sizeof(address_item));
yield->next->address = US"::1";
yield->next->port = 0;
yield->next->next = NULL;
#endif

DEBUG(D_interface) debug_printf("Unable to find local interface addresses "
  "on this OS: returning loopback address(es)\n");
return yield;
}
Example #23
0
File: pdkim.c Project: ytrezq/exim
static pdkim_stringlist *
pdkim_prepend_stringlist(pdkim_stringlist * base, const uschar * str)
{
pdkim_stringlist * new_entry = store_get(sizeof(pdkim_stringlist));

memset(new_entry, 0, sizeof(pdkim_stringlist));
new_entry->value = string_copy(str);
if (base) new_entry->next = base;
return new_entry;
}
Example #24
0
File: tree.c Project: fanf2/exim
void
tree_add_unusable(host_item *h)
{
tree_node *node;
uschar s[256];
sprintf(CS s, "T:%.200s:%s", h->name, h->address);
node = store_get(sizeof(tree_node) + Ustrlen(s));
Ustrcpy(node->name, s);
node->data.val = h->why;
if (h->status == hstatus_unusable_expired) node->data.val += 256;
if (!tree_insertnode(&tree_unusable, node)) store_reset(node);
}
Example #25
0
File: string.c Project: Exim/exim
uschar *
string_dequote(const uschar **sptr)
{
    const uschar *s = *sptr;
    uschar *t, *yield;

    /* First find the end of the string */

    if (*s != '\"')
    {
        while (*s != 0 && !isspace(*s)) s++;
    }
    else
    {
        s++;
        while (*s != 0 && *s != '\"')
        {
            if (*s == '\\') (void)string_interpret_escape(&s);
            s++;
        }
        if (*s != 0) s++;
    }

    /* Get enough store to copy into */

    t = yield = store_get(s - *sptr + 1);
    s = *sptr;

    /* Do the copy */

    if (*s != '\"')
    {
        while (*s != 0 && !isspace(*s)) *t++ = *s++;
    }
    else
    {
        s++;
        while (*s != 0 && *s != '\"')
        {
            if (*s == '\\') *t++ = string_interpret_escape(&s);
            else *t++ = *s;
            s++;
        }
        if (*s != 0) s++;
    }

    /* Update the pointer and return the terminated copy */

    *sptr = s;
    *t = 0;
    return yield;
}
Example #26
0
File: rda.c Project: toddr/exim
static BOOL
rda_read_string(int fd, uschar **sp)
{
int len;

if (read(fd, &len, sizeof(int)) != sizeof(int)) return FALSE;
if (len == 0) *sp = NULL; else
  {
  *sp = store_get(len);
  if (read(fd, *sp, len) != len) return FALSE;
  }
return TRUE;
}
Example #27
0
File: string.c Project: Exim/exim
uschar *
string_unprinting(uschar *s)
{
    uschar *p, *q, *r, *ss;
    int len, off;

    p = Ustrchr(s, '\\');
    if (!p) return s;

    len = Ustrlen(s) + 1;
    ss = store_get(len);

    q = ss;
    off = p - s;
    if (off)
    {
        memcpy(q, s, off);
        q += off;
    }

    while (*p)
    {
        if (*p == '\\')
        {
            *q++ = string_interpret_escape((const uschar **)&p);
            p++;
        }
        else
        {
            r = Ustrchr(p, '\\');
            if (!r)
            {
                off = Ustrlen(p);
                memcpy(q, p, off);
                p += off;
                q += off;
                break;
            }
            else
            {
                off = r - p;
                memcpy(q, p, off);
                q += off;
                p = r;
            }
        }
    }
    *q = '\0';

    return ss;
}
/*
 * Given a C string, make sure it's safe to pass to a 
 * printf-style function ('%' chars are escaped by doubling 
 * them up.  Optionally, also make sure the string ends with a '\n'
 */
static char *get_format_string(char *str, int need_newline)
    {
    char *p;
    char *q;
    char *newstr;
    int percent_count;
    int len;

    /* Count number of '%' characters in string, and get the total length while at it */ 
    for (p = str, percent_count = 0; *p; p++)
        if (*p == '%')
            percent_count++;
    len = p - str;

    /* Decide if we need a newline added */
    if (need_newline)
        {
        if (len && (*(p-1) == '\n'))
            need_newline = 0;
        else
            need_newline = 1; /* paranoia - just in case something other than 1 was used to indicate truth */
        }

    /* If it's all good, just return the string we were passed */
    if ((!percent_count) && (!need_newline))
        return str;

    /* Gotta make a new string, with '%'s and/or '\n' added */
    newstr = store_get(len + percent_count + need_newline + 1);

    for (p = str, q = newstr; *p; p++, q++)
        {
        *q = *p;
        if (*q == '%')
            {
            q++;   
            *q = '%';
            }
        }

    if (need_newline)
        {
        *q = '\n';
        q++;
        }

    *q = 0;

    return newstr;
    }
Example #29
0
ip_address_item *
os_common_find_running_interfaces(void)
{
struct ifaddrs *ifalist = NULL;
ip_address_item *yield = NULL;
ip_address_item *last = NULL;
ip_address_item  *next;

if (getifaddrs(&ifalist) != 0)
  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)
  {
  if (ifa->ifa_addr->sa_family != AF_INET
#if HAVE_IPV6
    && ifa->ifa_addr->sa_family != AF_INET6
#endif /* HAVE_IPV6 */
    )
    continue;

  if ( !(ifa->ifa_flags & IFF_UP) ) /* Only want 'UP' interfaces */
    continue;

  /* Create a data block for the address, fill in the data, and put it on the
  chain. */

  next = store_get(sizeof(ip_address_item));
  next->next = NULL;
  next->port = 0;
  (void)host_ntoa(-1, ifa->ifa_addr, next->address, NULL);

  if (yield == NULL)
    yield = last = next;
  else
    {
    last->next = next;
    last = next;
    }

  DEBUG(D_interface) debug_printf("Actual local interface address is %s (%s)\n",
    last->address, ifa->ifa_name);
  }

/* free the list of addresses, and return the chain of data blocks. */

freeifaddrs (ifalist);
return yield;
}
Example #30
0
void
rf_change_domain(address_item *addr, uschar *domain, BOOL rewrite,
  address_item **addr_new)
{
address_item *parent = store_get(sizeof(address_item));
uschar *at = Ustrrchr(addr->address, '@');
uschar *address = string_sprintf("%.*s@%s", at - addr->address, addr->address,
  domain);

DEBUG(D_route) debug_printf("domain changed to %s\n", domain);

/* The current address item is made into the parent, and a new address is set
up in the old space. */

*parent = *addr;

/* First copy in initializing values, to wipe out stuff such as the named
domain cache. Then copy over the propagating fields from the parent. Then set
up the new fields. */

*addr = address_defaults;
addr->p = parent->p;

addr->address = address;
addr->unique = string_copy(address);
addr->parent = parent;

addr->next = *addr_new;
*addr_new = addr;

/* Rewrite header lines if requested */

if (rewrite)
  {
  header_line *h;
  DEBUG(D_route|D_rewrite) debug_printf("rewriting header lines\n");
  for (h = header_list; h != NULL; h = h->next)
    {
    header_line *newh =
      rewrite_header(h, parent->domain, domain,
        global_rewrite_rules, rewrite_existflags, TRUE);
    if (newh != NULL)
      {
      h = newh;
      header_rewritten = TRUE;
      }
    }
  }
}