-/* $Cambridge: exim/src/src/dk.c,v 1.4 2005/06/24 08:23:21 tom Exp $ */
+/* $Cambridge: exim/src/src/dk.c,v 1.12 2007/01/08 10:50:18 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2007 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for DomainKeys support. Other DK relevant code is in
/* Flag end-of-message. */
dk_internal_status = dk_end(dk_context, &dk_flags);
+ /* dk_flags now has the selector flags (if there was one).
+ It seems that currently only the "t=" flag is supported
+ in selectors. */
+ if (dk_flags & DK_FLAG_SET)
+ if (dk_flags & DK_FLAG_TESTING)
+ dk_verify_block->testing = TRUE;
+
/* Grab address/domain information. */
p = dk_address(dk_context);
if (p != NULL) {
}
}
- /* TODO: This call should be removed with lib version >= 0.67 */
+ /* Now grab the domain-wide DK policy */
dk_flags = dk_policy(dk_context);
- /* Grab domain policy */
if (dk_flags & DK_FLAG_SET) {
- if (dk_flags & DK_FLAG_TESTING)
+ /* Selector "t=" flag has precedence, don't overwrite it if
+ the selector has set it above. */
+ if ((dk_flags & DK_FLAG_TESTING) && !dk_verify_block->testing)
dk_verify_block->testing = TRUE;
if (dk_flags & DK_FLAG_SIGNSALL)
dk_verify_block->signsall = TRUE;
dk_verify_block->result_string = string_copy((uschar *)DK_STAT_to_string(dk_internal_status));
/* All done, reset dk_context. */
- dk_free(dk_context);
+ dk_free(dk_context,1);
dk_context = NULL;
store_pool = old_pool;
uschar *dk_selector,
uschar *dk_canon) {
uschar *rc = NULL;
+ uschar *headers = NULL;
+ int headers_len;
int dk_canon_int = DK_CANON_SIMPLE;
- char c;
+ char buf[4096];
int seen_lf = 0;
int seen_lfdot = 0;
uschar sig[1024];
goto CLEANUP;
}
- while((sread = read(dk_fd,&c,1)) > 0) {
+ while((sread = read(dk_fd,&buf,4096)) > 0) {
+ int pos = 0;
+ char c;
- if ((c == '.') && seen_lfdot) {
- /* escaped dot, write "\n.", continue */
- dk_message(dk_context, CUS "\n.", 2);
- seen_lf = 0;
- seen_lfdot = 0;
- continue;
- }
+ while (pos < sread) {
+ c = buf[pos++];
- if (seen_lfdot) {
- /* EOM, write "\n" and break */
- dk_message(dk_context, CUS "\n", 1);
- break;
- }
+ if ((c == '.') && seen_lfdot) {
+ /* escaped dot, write "\n.", continue */
+ dk_message(dk_context, CUS "\n.", 2);
+ seen_lf = 0;
+ seen_lfdot = 0;
+ continue;
+ }
- if ((c == '.') && seen_lf) {
- seen_lfdot = 1;
- continue;
- }
+ if (seen_lfdot) {
+ /* EOM, write "\n" and break */
+ dk_message(dk_context, CUS "\n", 1);
+ break;
+ }
- if (seen_lf) {
- /* normal lf, just send it */
- dk_message(dk_context, CUS "\n", 1);
- seen_lf = 0;
- }
+ if ((c == '.') && seen_lf) {
+ seen_lfdot = 1;
+ continue;
+ }
- if (c == '\n') {
- seen_lf = 1;
- continue;
- }
+ if (seen_lf) {
+ /* normal lf, just send it */
+ dk_message(dk_context, CUS "\n", 1);
+ seen_lf = 0;
+ }
+
+ if (c == '\n') {
+ seen_lf = 1;
+ continue;
+ }
- /* write the char */
- dk_message(dk_context, CUS &c, 1);
+ /* write the char */
+ dk_message(dk_context, CUS &c, 1);
+ }
}
/* Handle failed read above. */
/* Looks like a filename, load the private key. */
memset(big_buffer,0,big_buffer_size);
privkey_fd = open(CS dk_private_key,O_RDONLY);
- read(privkey_fd,big_buffer,16383);
- close(privkey_fd);
+ (void)read(privkey_fd,big_buffer,16383);
+ (void)close(privkey_fd);
dk_private_key = big_buffer;
}
/* Get the signature. */
- dk_internal_status = dk_getsig(dk_context, dk_private_key, sig, 8192);
+ dk_internal_status = dk_getsig(dk_context, dk_private_key, sig, 1024);
/* Check for unuseable key */
if (dk_internal_status != DK_STAT_OK) {
goto CLEANUP;
}
- rc = store_get(1024);
+ headers_len = dk_headers(dk_context, NULL);
+ rc = store_get(1024+256+headers_len);
+ headers = store_malloc(headers_len);
+ dk_headers(dk_context, CS headers);
/* Build DomainKey-Signature header to return. */
- snprintf(CS rc, 1024, "DomainKey-Signature: a=rsa-sha1; q=dns; c=%s;\r\n"
- "\ts=%s; d=%s;\r\n"
- "\tb=%s;\r\n", dk_canon, dk_selector, dk_domain, sig);
+ (void)string_format(rc, 1024+256+headers_len, "DomainKey-Signature: a=rsa-sha1; q=dns; c=%s; s=%s; d=%s;\r\n"
+ "\th=%s;\r\n"
+ "\tb=%s;\r\n", dk_canon, dk_selector, dk_domain, headers, sig);
- log_write(0, LOG_MAIN, "DK: message signed using a=rsa-sha1; q=dns; c=%s; s=%s; d=%s;", dk_canon, dk_selector, dk_domain);
+ log_write(0, LOG_MAIN, "DK: message signed using a=rsa-sha1; q=dns; c=%s; s=%s; d=%s; h=%s;", dk_canon, dk_selector, dk_domain, headers);
+ store_free(headers);
CLEANUP:
if (dk_context != NULL) {
- dk_free(dk_context);
+ dk_free(dk_context,1);
dk_context = NULL;
}
store_pool = old_pool;