[exim-cvs] cvs commit: exim/exim-src/src dkim.c dkim.h expan…

Top Page
Delete this message
Reply to this message
Author: Tom Kistner
Date:  
To: exim-cvs
Subject: [exim-cvs] cvs commit: exim/exim-src/src dkim.c dkim.h expand.c receive.c
tom 2009/06/08 22:06:32 BST

  Modified files:        (Branch: DEVEL_PDKIM)
    exim-src/src         dkim.c dkim.h expand.c receive.c 
  Log:
  Add a bunch of expandables and some DKIM ACL red tape


  Revision  Changes    Path
  1.1.2.15  +176 -22   exim/exim-src/src/dkim.c
  1.1.2.5   +23 -12    exim/exim-src/src/dkim.h
  1.97.2.3  +24 -0     exim/exim-src/src/expand.c
  1.45.2.5  +19 -4     exim/exim-src/src/receive.c


  Index: dkim.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/Attic/dkim.c,v
  retrieving revision 1.1.2.14
  retrieving revision 1.1.2.15
  diff -u -r1.1.2.14 -r1.1.2.15
  --- dkim.c    27 May 2009 17:29:35 -0000    1.1.2.14
  +++ dkim.c    8 Jun 2009 21:06:31 -0000    1.1.2.15
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/dkim.c,v 1.1.2.14 2009/05/27 17:29:35 tom Exp $ */
  +/* $Cambridge: exim/exim-src/src/dkim.c,v 1.1.2.15 2009/06/08 21:06:31 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -18,6 +18,7 @@


   pdkim_ctx       *dkim_verify_ctx = NULL;
   pdkim_signature *dkim_signatures = NULL;
  +pdkim_signature *dkim_cur_sig    = NULL;


   int dkim_exim_query_dns_txt(char *name, char *answer) {
     dns_answer dnsa;
  @@ -79,6 +80,7 @@



   void dkim_exim_verify_finish(void) {
  +  pdkim_signature *sig = NULL;
     int dkim_signing_domains_size = 0;
     int dkim_signing_domains_ptr = 0;
     dkim_signing_domains = NULL;
  @@ -99,49 +101,49 @@
     /* Finish DKIM operation and fetch link to signatures chain */
     if (pdkim_feed_finish(dkim_verify_ctx,&dkim_signatures) != PDKIM_OK) return;


  -
  -  while (dkim_signatures != NULL) {
  +  sig = dkim_signatures;
  +  while (sig != NULL) {
       int size = 0;
       int ptr = 0;
       /* Log a line for each signature */
       uschar *logmsg = string_append(NULL, &size, &ptr, 5,


         string_sprintf( "DKIM: d=%s s=%s c=%s/%s a=%s ",
  -                      dkim_signatures->domain,
  -                      dkim_signatures->selector,
  -                      (dkim_signatures->canon_headers == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
  -                      (dkim_signatures->canon_body    == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
  -                      (dkim_signatures->algo          == PDKIM_ALGO_RSA_SHA256)?"rsa-sha256":"rsa-sha1"
  +                      sig->domain,
  +                      sig->selector,
  +                      (sig->canon_headers == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
  +                      (sig->canon_body    == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
  +                      (sig->algo          == PDKIM_ALGO_RSA_SHA256)?"rsa-sha256":"rsa-sha1"
                       ),
  -      ((dkim_signatures->identity != NULL)?
  -        string_sprintf("i=%s ", dkim_signatures->identity)
  +      ((sig->identity != NULL)?
  +        string_sprintf("i=%s ", sig->identity)
           :
           US""
         ),
  -      ((dkim_signatures->created > 0)?
  -        string_sprintf("t=%lu ", dkim_signatures->created)
  +      ((sig->created > 0)?
  +        string_sprintf("t=%lu ", sig->created)
           :
           US""
         ),
  -      ((dkim_signatures->expires > 0)?
  -        string_sprintf("x=%lu ", dkim_signatures->expires)
  +      ((sig->expires > 0)?
  +        string_sprintf("x=%lu ", sig->expires)
           :
           US""
         ),
  -      ((dkim_signatures->bodylength > -1)?
  -        string_sprintf("l=%lu ", dkim_signatures->bodylength)
  +      ((sig->bodylength > -1)?
  +        string_sprintf("l=%lu ", sig->bodylength)
           :
           US""
         )
       );


  -    switch(dkim_signatures->verify_status) {
  +    switch(sig->verify_status) {
         case PDKIM_VERIFY_NONE:
           logmsg = string_append(logmsg, &size, &ptr, 1, "[not verified]");
         break;
         case PDKIM_VERIFY_INVALID:
           logmsg = string_append(logmsg, &size, &ptr, 1, "[invalid - ");
  -        switch (dkim_signatures->verify_ext_status) {
  +        switch (sig->verify_ext_status) {
             case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
               logmsg = string_append(logmsg, &size, &ptr, 1, "public key record (currently?) unavailable]");
             break;
  @@ -157,7 +159,7 @@
         break;
         case PDKIM_VERIFY_FAIL:
           logmsg = string_append(logmsg, &size, &ptr, 1, "[verification failed - ");
  -        switch (dkim_signatures->verify_ext_status) {
  +        switch (sig->verify_ext_status) {
             case PDKIM_VERIFY_FAIL_BODY:
               logmsg = string_append(logmsg, &size, &ptr, 1, "body hash mismatch (body probably modified in transit)]");
             break;
  @@ -181,12 +183,12 @@
                                            &dkim_signing_domains_size,
                                            &dkim_signing_domains_ptr,
                                            2,
  -                                         dkim_signatures->domain,
  +                                         sig->domain,
                                            ":"
                                           );


       /* Process next signature */
  -    dkim_signatures = dkim_signatures->next;
  +    sig = sig->next;
     }


     /* Chop the last colon from the domain list */
  @@ -196,9 +198,161 @@
   }



  -void dkim_exim_verify_result(uschar *domain, uschar **result, uschar **error) {
  -  if (dkim_verify_ctx) {
  +void dkim_exim_acl_setup(uschar *id) {
  +  pdkim_signature *sig = dkim_signatures;
  +  dkim_cur_sig = NULL;
  +  if (dkim_disable_verify ||
  +      !id || !sig ||
  +      !dkim_verify_ctx) return;
  +  /* Find signature to run ACL on */
  +  while (sig != NULL) {
  +    uschar *cmp_val = NULL;
  +    if (Ustrchr(id,'@') != NULL) cmp_val = (uschar *)sig->identity;
  +                            else cmp_val = (uschar *)sig->domain;
  +    if (cmp_val && (strcmpic(cmp_val,id) == 0)) {
  +      dkim_cur_sig = sig;
  +      /* The "dkim_domain" and "dkim_selector" expansion variables have
  +         related globals, since they are used in the signing code too.
  +         Instead of inventing separate names for verification, we set
  +         them here. This is easy since a domain and selector is guaranteed
  +         to be in a signature. The other dkim_* expansion items are
  +         dynamically fetched from dkim_cur_sig at expansion time (see
  +         function below). */
  +      dkim_signing_domain   = (uschar *)sig->domain;
  +      dkim_signing_selector = (uschar *)sig->selector;
  +      return;
  +    }
  +    sig = sig->next;
  +  }
  +}
  +
  +
  +uschar *dkim_exim_expand_query(int what) {
  +
  +  if (!dkim_verify_ctx ||
  +      dkim_disable_verify ||
  +      !dkim_cur_sig) return dkim_exim_expand_defaults(what);
  +
  +  switch(what) {
  +    case DKIM_ALGO:
  +      return dkim_cur_sig->algo?
  +              (uschar *)(dkim_cur_sig->algo)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_BODYLENGTH:
  +      return (dkim_cur_sig->bodylength >= 0)?
  +              (uschar *)string_sprintf(OFF_T_FMT,(LONGLONG_T)dkim_cur_sig->bodylength)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_CANON_BODY:
  +      return dkim_cur_sig->canon_body?
  +              (uschar *)(dkim_cur_sig->canon_body)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_CANON_HEADERS:
  +      return dkim_cur_sig->canon_headers?
  +              (uschar *)(dkim_cur_sig->canon_headers)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_COPIEDHEADERS:
  +      return dkim_cur_sig->copiedheaders?
  +              (uschar *)(dkim_cur_sig->copiedheaders)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_CREATED:
  +      return (dkim_cur_sig->created > 0)?
  +              (uschar *)string_sprintf("%llu",dkim_cur_sig->created)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_EXPIRES:
  +      return (dkim_cur_sig->expires > 0)?
  +              (uschar *)string_sprintf("%llu",dkim_cur_sig->expires)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_HEADERNAMES:
  +      return dkim_cur_sig->headernames?
  +              (uschar *)(dkim_cur_sig->headernames)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_IDENTITY:
  +      return dkim_cur_sig->identity?
  +              (uschar *)(dkim_cur_sig->identity)
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_KEY_GRANULARITY:
  +      return dkim_cur_sig->pubkey?
  +              (dkim_cur_sig->pubkey->granularity?
  +                (uschar *)(dkim_cur_sig->pubkey->granularity)
  +                :dkim_exim_expand_defaults(what)
  +              )
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_KEY_SRVTYPE:
  +      return dkim_cur_sig->pubkey?
  +              (dkim_cur_sig->pubkey->srvtype?
  +                (uschar *)(dkim_cur_sig->pubkey->srvtype)
  +                :dkim_exim_expand_defaults(what)
  +              )
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_KEY_NOTES:
  +      return dkim_cur_sig->pubkey?
  +              (dkim_cur_sig->pubkey->notes?
  +                (uschar *)(dkim_cur_sig->pubkey->notes)
  +                :dkim_exim_expand_defaults(what)
  +              )
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_KEY_TESTING:
  +      return dkim_cur_sig->pubkey?
  +              (dkim_cur_sig->pubkey->testing?
  +                US"1"
  +                :dkim_exim_expand_defaults(what)
  +              )
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_NOSUBDOMAINS:
  +      return dkim_cur_sig->pubkey?
  +              (dkim_cur_sig->pubkey->no_subdomaining?
  +                US"1"
  +                :dkim_exim_expand_defaults(what)
  +              )
  +              :dkim_exim_expand_defaults(what);
  +    case DKIM_VERIFY_STATUS:
  +      switch(dkim_cur_sig->verify_status) {
  +        case PDKIM_VERIFY_INVALID:
  +          return US"invalid";
  +        case PDKIM_VERIFY_FAIL:
  +          return US"fail";
  +        case PDKIM_VERIFY_PASS:
  +          return US"pass";
  +        case PDKIM_VERIFY_NONE:
  +        default:
  +          return US"none";
  +      }
  +    case DKIM_VERIFY_REASON:
  +      switch (dkim_cur_sig->verify_ext_status) {
  +        case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
  +          return US"pubkey_unavailable";
  +        case PDKIM_VERIFY_INVALID_PUBKEY_PARSING:
  +          return US"pubkey_syntax";
  +        case PDKIM_VERIFY_FAIL_BODY:
  +          return US"bodyhash_mismatch";
  +        case PDKIM_VERIFY_FAIL_MESSAGE:
  +          return US"signature_incorrect";
  +      }
  +    default:
  +      return US"";
  +  }
  +}
  +


  +uschar *dkim_exim_expand_defaults(int what) {
  +  switch(what) {
  +    case DKIM_ALGO:               return US"";
  +    case DKIM_BODYLENGTH:         return US"9999999999999";
  +    case DKIM_CANON_BODY:         return US"";
  +    case DKIM_CANON_HEADERS:      return US"";
  +    case DKIM_COPIEDHEADERS:      return US"";
  +    case DKIM_CREATED:            return US"0";
  +    case DKIM_EXPIRES:            return US"9999999999999";
  +    case DKIM_HEADERNAMES:        return US"";
  +    case DKIM_IDENTITY:           return US"";
  +    case DKIM_KEY_GRANULARITY:    return US"*";
  +    case DKIM_KEY_SRVTYPE:        return US"*";
  +    case DKIM_KEY_NOTES:          return US"";
  +    case DKIM_KEY_TESTING:        return US"0";
  +    case DKIM_NOSUBDOMAINS:       return US"0";
  +    case DKIM_VERIFY_STATUS:      return US"none";
  +    case DKIM_VERIFY_REASON:      return US"";
  +    default:                      return US"";
     }
   }



  Index: dkim.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/Attic/dkim.h,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- dkim.h    20 May 2009 14:30:14 -0000    1.1.2.4
  +++ dkim.h    8 Jun 2009 21:06:31 -0000    1.1.2.5
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/dkim.h,v 1.1.2.4 2009/05/20 14:30:14 tom Exp $ */
  +/* $Cambridge: exim/exim-src/src/dkim.h,v 1.1.2.5 2009/06/08 21:06:31 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -7,16 +7,27 @@
   /* Copyright (c) University of Cambridge 2009 */
   /* See the file NOTICE for conditions of use and distribution. */


  -uschar *dkim_exim_sign(int,
  -                       uschar *,
  -                       uschar *,
  -                       uschar *,
  -                       uschar *,
  -                       uschar *);
  +uschar *dkim_exim_sign(int,uschar *,uschar *,uschar *,uschar *,uschar *);
  +void    dkim_exim_verify_init(void);
  +void    dkim_exim_verify_feed(uschar *, int);
  +void    dkim_exim_verify_finish(void);
  +void    dkim_exim_acl_setup(uschar *);
  +uschar *dkim_exim_expand_query(int);
  +uschar *dkim_exim_expand_defaults(int);


  -void dkim_exim_verify_init(void);
  -void dkim_exim_verify_feed(uschar *, int);
  -void dkim_exim_verify_finish(void);
  -void dkim_exim_verify_result(uschar *,
  -                             uschar **,
  -                             uschar **);
  +#define DKIM_ALGO               1
  +#define DKIM_BODYLENGTH         2
  +#define DKIM_CANON_BODY         3
  +#define DKIM_CANON_HEADERS      4
  +#define DKIM_COPIEDHEADERS      5
  +#define DKIM_CREATED            6
  +#define DKIM_EXPIRES            7
  +#define DKIM_HEADERNAMES        8
  +#define DKIM_IDENTITY           9
  +#define DKIM_KEY_GRANULARITY   10
  +#define DKIM_KEY_SRVTYPE       11
  +#define DKIM_KEY_NOTES         12
  +#define DKIM_KEY_TESTING       13
  +#define DKIM_NOSUBDOMAINS      14
  +#define DKIM_VERIFY_STATUS     15
  +#define DKIM_VERIFY_REASON     16


  Index: expand.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/expand.c,v
  retrieving revision 1.97.2.2
  retrieving revision 1.97.2.3
  diff -u -r1.97.2.2 -r1.97.2.3
  --- expand.c    27 May 2009 17:26:54 -0000    1.97.2.2
  +++ expand.c    8 Jun 2009 21:06:31 -0000    1.97.2.3
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/expand.c,v 1.97.2.2 2009/05/27 17:26:54 tom Exp $ */
  +/* $Cambridge: exim/exim-src/src/expand.c,v 1.97.2.3 2009/06/08 21:06:31 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -364,6 +364,9 @@
     vtype_load_avg,       /* value not used; result is int from os_getloadavg */
     vtype_pspace,         /* partition space; value is T/F for spool/log */
     vtype_pinodes         /* partition inodes; value is T/F for spool/log */
  +  #ifndef DISABLE_DKIM
  +  ,vtype_dkim           /* Lookup of value in DKIM signature */
  +  #endif
     };


   /* This table must be kept in alphabetical order. */
  @@ -402,9 +405,25 @@
     { "demime_reason",       vtype_stringptr,   &demime_reason },
   #endif
   #ifndef DISABLE_DKIM
  +  { "dkim_algo",           vtype_dkim,        (void *)DKIM_ALGO },
  +  { "dkim_bodylength",     vtype_dkim,        (void *)DKIM_BODYLENGTH },
  +  { "dkim_canon_body",     vtype_dkim,        (void *)DKIM_CANON_BODY },
  +  { "dkim_canon_headers",  vtype_dkim,        (void *)DKIM_CANON_HEADERS },
  +  { "dkim_copiedheaders",  vtype_dkim,        (void *)DKIM_COPIEDHEADERS },
  +  { "dkim_created",        vtype_dkim,        (void *)DKIM_CREATED },
     { "dkim_domain",         vtype_stringptr,   &dkim_signing_domain },
  +  { "dkim_expires",        vtype_dkim,        (void *)DKIM_EXPIRES },
  +  { "dkim_headernames",    vtype_dkim,        (void *)DKIM_HEADERNAMES },
  +  { "dkim_identity",       vtype_dkim,        (void *)DKIM_IDENTITY },
  +  { "dkim_key_granularity",vtype_dkim,        (void *)DKIM_KEY_GRANULARITY },
  +  { "dkim_key_nosubdomains",vtype_dkim,       (void *)DKIM_NOSUBDOMAINS },
  +  { "dkim_key_notes",      vtype_dkim,        (void *)DKIM_KEY_NOTES },
  +  { "dkim_key_srvtype",    vtype_dkim,        (void *)DKIM_KEY_SRVTYPE },
  +  { "dkim_key_testing",    vtype_dkim,        (void *)DKIM_KEY_TESTING },
     { "dkim_selector",       vtype_stringptr,   &dkim_signing_selector },
     { "dkim_signing_domains",vtype_stringptr,   &dkim_signing_domains },
  +  { "dkim_verify_reason",  vtype_dkim,        (void *)DKIM_VERIFY_REASON },
  +  { "dkim_verify_status",  vtype_dkim,        (void *)DKIM_VERIFY_STATUS},
   #endif
     { "dnslist_domain",      vtype_stringptr,   &dnslist_domain },
     { "dnslist_matched",     vtype_stringptr,   &dnslist_matched },
  @@ -1546,6 +1565,11 @@
         }
       return var_buffer;


  +    #ifndef DKIM_DISABLE
  +    case vtype_dkim:
  +    return dkim_exim_expand_query((int)var_table[middle].value);
  +    #endif
  +
       }
     }



  Index: receive.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/receive.c,v
  retrieving revision 1.45.2.4
  retrieving revision 1.45.2.5
  diff -u -r1.45.2.4 -r1.45.2.5
  --- receive.c    27 May 2009 17:26:55 -0000    1.45.2.4
  +++ receive.c    8 Jun 2009 21:06:32 -0000    1.45.2.5
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/receive.c,v 1.45.2.4 2009/05/27 17:26:55 tom Exp $ */
  +/* $Cambridge: exim/exim-src/src/receive.c,v 1.45.2.5 2009/06/08 21:06:32 tom Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -2998,20 +2998,35 @@
                                              itembuf,
                                              sizeof(itembuf))) != NULL)
               {
  -
  -
  +            dkim_exim_acl_setup(item);
               rc = acl_check(ACL_WHERE_DKIM, NULL, acl_smtp_dkim, &user_msg, &log_msg);
               if (rc != OK) break;
               }
  -
             add_acl_headers(US"DKIM");
  +          if (rc == DISCARD)
  +            {
  +            recipients_count = 0;
  +            blackholed_by = US"DKIM ACL";
  +            if (log_msg != NULL)
  +              blackhole_log_msg = string_sprintf(": %s", log_msg);
  +            }
  +          else if (rc != OK)
  +            {
  +            Uunlink(spool_name);
  +            if (smtp_handle_acl_fail(ACL_WHERE_DKIM, rc, user_msg, log_msg) != 0)
  +              smtp_yield = FALSE;    /* No more messsages after dropped connection */
  +            smtp_reply = US"";       /* Indicate reply already sent */
  +            message_id[0] = 0;       /* Indicate no message accepted */
  +            goto TIDYUP;             /* Skip to end of function */
  +            }
             }
           }
         }
   #endif /* DISABLE_DKIM */


   #ifdef WITH_CONTENT_SCAN
  -    if (acl_smtp_mime != NULL &&
  +    if (recipients_count > 0 &&
  +        acl_smtp_mime != NULL &&
           !run_mime_acl(acl_smtp_mime, &smtp_yield, &smtp_reply, &blackholed_by))
         goto TIDYUP;
   #endif /* WITH_CONTENT_SCAN */