Merge tag 'exim-4_82_1' exim-4_83_RC1
authorTodd Lyons <tlyons@exim.org>
Wed, 28 May 2014 12:12:00 +0000 (05:12 -0700)
committerTodd Lyons <tlyons@exim.org>
Wed, 28 May 2014 12:12:00 +0000 (05:12 -0700)
Fix Conflicts:
src/src/dmarc.c

1  2 
src/src/dmarc.c

diff --combined src/src/dmarc.c
index b2336b388c9817df3e178ee8cc2bff7090628ef3,c6190613e928d7a9882636a3a07e320f80f65e96..ca1c29bbb5bfdaf34cc2092e44c147116620aaaf
@@@ -2,7 -2,7 +2,7 @@@
  *     Exim - an Internet mail transport agent    *
  *************************************************/
  /* Experimental DMARC support.
 -   Copyright (c) Todd Lyons <tlyons@exim.org> 2012, 2013
 +   Copyright (c) Todd Lyons <tlyons@exim.org> 2012 - 2014
     License: GPL */
  
  /* Portions Copyright (c) 2012, 2013, The Trusted Domain Project;
@@@ -38,18 -38,6 +38,18 @@@ u_char *header_from_sender = NULL
  int history_file_status    = DMARC_HIST_OK;
  uschar *dkim_history_buffer= NULL;
  
 +typedef struct dmarc_exim_p {
 +  uschar *name;
 +  int    value;
 +} dmarc_exim_p;
 +
 +static dmarc_exim_p dmarc_policy_description[] = {
 +  { US"",           DMARC_RECORD_P_UNSPECIFIED },
 +  { US"none",       DMARC_RECORD_P_NONE },
 +  { US"quarantine", DMARC_RECORD_P_QUARANTINE },
 +  { US"reject",     DMARC_RECORD_P_REJECT },
 +  { NULL,           0 }
 +};
  /* Accept an error_block struct, initialize if empty, parse to the
   * end, and append the two strings passed to it.  Used for adding
   * variable amounts of value:pair data to the forensic emails. */
@@@ -159,7 -147,6 +159,7 @@@ int dmarc_store_data(header_line *hdr) 
  int dmarc_process() {
      int sr, origin;             /* used in SPF section */
      int dmarc_spf_result  = 0;  /* stores spf into dmarc conn ctx */
 +    int tmp_ans, c;
      pdkim_signature *sig  = NULL;
      BOOL has_dmarc_record = TRUE;
      u_char **ruf; /* forensic report addressees, if called for */
      dmarc_abort = TRUE;
    else
    {
-     /* I strongly encourage anybody who can make this better to contact me directly!
-      * <cannonball> Is this an insane way to extract the email address from the From: header?
-      * <jgh_hm> it's sure a horrid layer-crossing....
-      * <cannonball> I'm not denying that :-/
-      * <jgh_hm> there may well be no better though
-      */
-     header_from_sender = expand_string(
-            string_sprintf("${domain:${extract{1}{:}{${addresses:\\N%s\\N}}}}",
-                           from_header->text) );
 -  uschar * errormsg;
 -  int dummy, domain;
 -  uschar * p;
 -  uschar saveend;
 -
 -  parse_allow_group = TRUE;
 -  p = parse_find_address_end(from_header->text, FALSE);
 -  saveend = *p; *p = '\0';
 -  if ((header_from_sender = parse_extract_address(from_header->text, &errormsg,
 -                              &dummy, &dummy, &domain, FALSE)))
 -    header_from_sender += domain;
 -  *p = saveend;
 -
 -  /* The opendmarc library extracts the domain from the email address, but
 -   * only try to store it if it's not empty.  Otherwise, skip out of DMARC. */
 -  if (!header_from_sender || (strcmp( CCS header_from_sender, "") == 0))
 -    dmarc_abort = TRUE;
 -  libdm_status = dmarc_abort ?
 -    DMARC_PARSE_OKAY :
 -    opendmarc_policy_store_from_domain(dmarc_pctx, header_from_sender);
 -  if (libdm_status != DMARC_PARSE_OKAY)
++    uschar * errormsg;
++    int dummy, domain;
++    uschar * p;
++    uschar saveend;
++
++    parse_allow_group = TRUE;
++    p = parse_find_address_end(from_header->text, FALSE);
++    saveend = *p; *p = '\0';
++    if ((header_from_sender = parse_extract_address(from_header->text, &errormsg,
++                                &dummy, &dummy, &domain, FALSE)))
++      header_from_sender += domain;
++    *p = saveend;
++
 +    /* The opendmarc library extracts the domain from the email address, but
 +     * only try to store it if it's not empty.  Otherwise, skip out of DMARC. */
-     if ((header_from_sender == NULL) || (strcmp( CCS header_from_sender, "") == 0))
++    if (!header_from_sender || (strcmp( CCS header_from_sender, "") == 0))
 +      dmarc_abort = TRUE;
-     libdm_status = (dmarc_abort == TRUE) ?
++    libdm_status = dmarc_abort ?
 +      DMARC_PARSE_OKAY :
 +      opendmarc_policy_store_from_domain(dmarc_pctx, header_from_sender);
 +    if (libdm_status != DMARC_PARSE_OKAY)
      {
        log_write(0, LOG_MAIN|LOG_PANIC,
                  "failure to store header From: in DMARC: %s, header was '%s'",
                      ( vs == PDKIM_VERIFY_INVALID ) ? DMARC_POLICY_DKIM_OUTCOME_TMPFAIL :
                      DMARC_POLICY_DKIM_OUTCOME_NONE;
        libdm_status = opendmarc_policy_store_dkim(dmarc_pctx, (uschar *)sig->domain,
 -                                               dkim_result, US"");
 +                                                 dkim_result, US"");
        DEBUG(D_receive)
          debug_printf("DMARC adding DKIM sender domain = %s\n", sig->domain);
        if (libdm_status != DMARC_PARSE_OKAY)
          log_write(0, LOG_MAIN|LOG_PANIC, "failure to store dkim (%s) for DMARC: %s",
 -                           sig->domain, opendmarc_policy_status_to_str(libdm_status));
 +                  sig->domain, opendmarc_policy_status_to_str(libdm_status));
  
        dkim_ares_result = ( vs == PDKIM_VERIFY_PASS )    ? ARES_RESULT_PASS :
 -                            ( vs == PDKIM_VERIFY_FAIL )    ? ARES_RESULT_FAIL :
 -                            ( vs == PDKIM_VERIFY_NONE )    ? ARES_RESULT_NONE :
 -                            ( vs == PDKIM_VERIFY_INVALID ) ?
 +                         ( vs == PDKIM_VERIFY_FAIL )    ? ARES_RESULT_FAIL :
 +                         ( vs == PDKIM_VERIFY_NONE )    ? ARES_RESULT_NONE :
 +                         ( vs == PDKIM_VERIFY_INVALID ) ?
                             ( ves == PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE ? ARES_RESULT_PERMERROR :
                               ves == PDKIM_VERIFY_INVALID_BUFFER_SIZE        ? ARES_RESULT_PERMERROR :
                               ves == PDKIM_VERIFY_INVALID_PUBKEY_PARSING     ? ARES_RESULT_PERMERROR :
                               ARES_RESULT_UNKNOWN ) :
                            ARES_RESULT_UNKNOWN;
        dkim_history_buffer = string_sprintf("%sdkim %s %d\n", dkim_history_buffer,
 -                                                             sig->domain, dkim_ares_result);
 +                                           sig->domain, dkim_ares_result);
        sig = sig->next;
      }
      libdm_status = opendmarc_policy_query_dmarc(dmarc_pctx, US"");
          has_dmarc_record = FALSE;
          break;
      }
 +
 +  /* Store the policy string in an expandable variable. */
 +    libdm_status = opendmarc_policy_fetch_p(dmarc_pctx, &tmp_ans);
 +    for (c=0; dmarc_policy_description[c].name != NULL; c++) {
 +      if (tmp_ans == dmarc_policy_description[c].value) {
 +        dmarc_domain_policy = string_sprintf("%s",dmarc_policy_description[c].name);
 +        break;
 +      }
 +    }
 +
      /* Can't use exim's string manipulation functions so allocate memory
       * for libopendmarc using its max hostname length definition. */
      uschar *dmarc_domain = (uschar *)calloc(DMARC_MAXHOSTNAMELEN, sizeof(uschar));
      libdm_status = opendmarc_policy_fetch_utilized_domain(dmarc_pctx, dmarc_domain,
 -                                                        DMARC_MAXHOSTNAMELEN-1);
 +                                                  DMARC_MAXHOSTNAMELEN-1);
      dmarc_used_domain = string_copy(dmarc_domain);
      free(dmarc_domain);
      if (libdm_status != DMARC_PARSE_OKAY)
@@@ -455,7 -436,7 +459,7 @@@ int dmarc_write_history_file(
  
    if (spf_response != NULL)
      history_buffer = string_sprintf("%sspf %d\n", history_buffer, dmarc_spf_ares_result);
 -    // history_buffer = string_sprintf("%sspf -1\n", history_buffer);
 +    /* history_buffer = string_sprintf("%sspf -1\n", history_buffer); */
  
    history_buffer = string_sprintf("%s%s", history_buffer, dkim_history_buffer);
    history_buffer = string_sprintf("%spdomain %s\n", history_buffer, dmarc_used_domain);
@@@ -633,3 -614,5 +637,3 @@@ uschar *dmarc_auth_results_header(heade
  
  #endif /* EXPERIMENTAL_SPF */
  #endif /* EXPERIMENTAL_DMARC */
 -
 -// vim:sw=2 expandtab