1 /* $Cambridge: exim/src/src/dkim.c,v 1.1.2.1 2009/02/24 15:57:55 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"
19 uschar *dkim_exim_sign(int dkim_fd,
20 uschar *dkim_private_key,
22 uschar *dkim_selector,
24 uschar *dkim_sign_headers) {
25 pdkim_ctx *ctx = NULL;
33 dkim_domain = expand_string(dkim_domain);
34 if (dkim_domain == NULL) {
35 /* expansion error, do not send message. */
36 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
37 "dkim_domain: %s", expand_string_message);
41 /* Set up $dkim_domain expansion variable. */
42 dkim_signing_domain = dkim_domain;
44 /* Get selector to use. */
45 dkim_selector = expand_string(dkim_selector);
46 if (dkim_selector == NULL) {
47 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
48 "dkim_selector: %s", expand_string_message);
52 /* Set up $dkim_selector expansion variable. */
53 dkim_signing_selector = dkim_selector;
55 /* Get canonicalization to use */
56 dkim_canon = expand_string(dkim_canon?dkim_canon:US"relaxed");
57 if (dkim_canon == NULL) {
58 /* expansion error, do not send message. */
59 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
60 "dkim_canon: %s", expand_string_message);
64 if (Ustrcmp(dkim_canon, "relaxed") == 0)
65 pdkim_canon = PDKIM_CANON_RELAXED;
66 else if (Ustrcmp(dkim_canon, "simple") == 0)
67 pdkim_canon = PDKIM_CANON_RELAXED;
69 log_write(0, LOG_MAIN, "DKIM: unknown canonicalization method '%s', defaulting to 'relaxed'.\n",dkim_canon);
70 pdkim_canon = PDKIM_CANON_RELAXED;
73 /* Expand signing headers once */
74 if (dkim_sign_headers != NULL) {
75 dkim_sign_headers = expand_string(dkim_sign_headers);
76 if (dkim_sign_headers == NULL) {
77 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
78 "dkim_sign_headers: %s", expand_string_message);
83 dkim_exim_sign_headers = dkim_sign_headers;
85 /* Get private key to use. */
86 dkim_private_key = expand_string(dkim_private_key);
87 if (dkim_private_key == NULL) {
88 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
89 "dkim_private_key: %s", expand_string_message);
93 if ( (Ustrlen(dkim_private_key) == 0) ||
94 (Ustrcmp(dkim_private_key,"0") == 0) ||
95 (Ustrcmp(dkim_private_key,"false") == 0) ) {
96 /* don't sign, but no error */
101 if (dkim_private_key[0] == '/') {
103 /* Looks like a filename, load the private key. */
104 memset(big_buffer,0,big_buffer_size);
105 privkey_fd = open(CS dkim_private_key,O_RDONLY);
106 (void)read(privkey_fd,big_buffer,16383);
107 (void)close(privkey_fd);
108 dkim_private_key = big_buffer;
111 ctx = pdkim_init_sign((char *)dkim_signing_domain,
112 (char *)dkim_signing_selector,
116 pdkim_set_debug_stream(ctx,debug_file);
118 pdkim_set_optional(ctx,
120 (char *)dkim_exim_sign_headers,
129 while((sread = read(dkim_fd,&buf,4096)) > 0) {
130 if (pdkim_feed(ctx,buf,sread) != PDKIM_OK) {
135 /* Handle failed read above. */
137 debug_printf("DKIM: Error reading -K file.\n");
143 if (pdkim_feed_finish(ctx,&signature) != PDKIM_OK)
146 rc = store_get(strlen(signature)+3);
147 Ustrcpy(rc,US signature);
148 Ustrcat(rc,US"\r\n");
154 store_pool = old_pool;