1 /* $Cambridge: exim/src/src/dkim.c,v 1.1.2.2 2009/02/24 18:43:59 tom Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 2009 */
8 /* See the file NOTICE for conditions of use and distribution. */
10 /* Code for DKIM support. Other DKIM relevant code is in
11 receive.c, transport.c and transports/smtp.c */
17 #include "pdkim/pdkim.h"
20 void dkim_exim_verify_init(void) {
23 void dkim_exim_verify_finish(void) {
26 int dkim_exim_verify_result(uschar *domain, uschar **result, uschar **error) {
30 uschar *dkim_exim_sign(int dkim_fd,
31 uschar *dkim_private_key,
33 uschar *dkim_selector,
35 uschar *dkim_sign_headers) {
36 pdkim_ctx *ctx = NULL;
43 int old_pool = store_pool;
45 dkim_domain = expand_string(dkim_domain);
46 if (dkim_domain == NULL) {
47 /* expansion error, do not send message. */
48 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
49 "dkim_domain: %s", expand_string_message);
53 /* Set up $dkim_domain expansion variable. */
54 dkim_signing_domain = dkim_domain;
56 /* Get selector to use. */
57 dkim_selector = expand_string(dkim_selector);
58 if (dkim_selector == NULL) {
59 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
60 "dkim_selector: %s", expand_string_message);
64 /* Set up $dkim_selector expansion variable. */
65 dkim_signing_selector = dkim_selector;
67 /* Get canonicalization to use */
68 dkim_canon = expand_string(dkim_canon?dkim_canon:US"relaxed");
69 if (dkim_canon == NULL) {
70 /* expansion error, do not send message. */
71 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
72 "dkim_canon: %s", expand_string_message);
76 if (Ustrcmp(dkim_canon, "relaxed") == 0)
77 pdkim_canon = PDKIM_CANON_RELAXED;
78 else if (Ustrcmp(dkim_canon, "simple") == 0)
79 pdkim_canon = PDKIM_CANON_RELAXED;
81 log_write(0, LOG_MAIN, "DKIM: unknown canonicalization method '%s', defaulting to 'relaxed'.\n",dkim_canon);
82 pdkim_canon = PDKIM_CANON_RELAXED;
85 /* Expand signing headers once */
86 if (dkim_sign_headers != NULL) {
87 dkim_sign_headers = expand_string(dkim_sign_headers);
88 if (dkim_sign_headers == NULL) {
89 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
90 "dkim_sign_headers: %s", expand_string_message);
96 /* Get private key to use. */
97 dkim_private_key = expand_string(dkim_private_key);
98 if (dkim_private_key == NULL) {
99 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
100 "dkim_private_key: %s", expand_string_message);
104 if ( (Ustrlen(dkim_private_key) == 0) ||
105 (Ustrcmp(dkim_private_key,"0") == 0) ||
106 (Ustrcmp(dkim_private_key,"false") == 0) ) {
107 /* don't sign, but no error */
112 if (dkim_private_key[0] == '/') {
114 /* Looks like a filename, load the private key. */
115 memset(big_buffer,0,big_buffer_size);
116 privkey_fd = open(CS dkim_private_key,O_RDONLY);
117 (void)read(privkey_fd,big_buffer,16383);
118 (void)close(privkey_fd);
119 dkim_private_key = big_buffer;
122 ctx = pdkim_init_sign((char *)dkim_signing_domain,
123 (char *)dkim_signing_selector,
127 pdkim_set_debug_stream(ctx,debug_file);
129 pdkim_set_optional(ctx,
131 (char *)dkim_sign_headers,
140 while((sread = read(dkim_fd,&buf,4096)) > 0) {
141 if (pdkim_feed(ctx,buf,sread) != PDKIM_OK) {
146 /* Handle failed read above. */
148 debug_printf("DKIM: Error reading -K file.\n");
154 if (pdkim_feed_finish(ctx,&signature) != PDKIM_OK)
157 rc = store_get(strlen(signature)+3);
158 Ustrcpy(rc,US signature);
159 Ustrcat(rc,US"\r\n");
165 store_pool = old_pool;