-/* $Cambridge: exim/src/src/auths/cram_md5.c,v 1.2 2005/01/04 10:00:43 ph10 Exp $ */
-
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */
int auth_cram_md5_options_count =
sizeof(auth_cram_md5_options)/sizeof(optionlist);
-/* Default private options block for the contidion authentication method. */
+/* Default private options block for the condition authentication method. */
auth_cram_md5_options_block auth_cram_md5_option_defaults = {
NULL, /* server_secret */
};
+#ifdef MACRO_PREDEF
+
+/* Dummy values */
+void auth_cram_md5_init(auth_instance *ablock) {}
+int auth_cram_md5_server(auth_instance *ablock, uschar *data) {return 0;}
+int auth_cram_md5_client(auth_instance *ablock, void *sx, int timeout,
+ uschar *buffer, int buffsize) {return 0;}
+
+#else /*!MACRO_PREDEF*/
+
+
/*************************************************
* Initialization entry point *
*************************************************/
}
}
+#endif /*!MACRO_PREDEF*/
#endif /* STAND_ALONE */
+#ifndef MACRO_PREDEF
/*************************************************
-* Peform the CRAM-MD5 algorithm *
+* Perform the CRAM-MD5 algorithm *
*************************************************/
/* The CRAM-MD5 algorithm is described in RFC 2195. It computes
compute_cram_md5(uschar *secret, uschar *challenge, uschar *digestptr)
{
md5 base;
-int i;
int len = Ustrlen(secret);
uschar isecret[64];
uschar osecret[64];
if (len > 64)
{
md5_start(&base);
- md5_end(&base, (uschar *)secret, len, md5secret);
- secret = (uschar *)md5secret;
+ md5_end(&base, US secret, len, md5secret);
+ secret = US md5secret;
len = 16;
}
memset(isecret+len, 0, 64-len);
memcpy(osecret, isecret, 64);
-for (i = 0; i < 64; i++)
+for (int i = 0; i < 64; i++)
{
isecret[i] ^= 0x36;
osecret[i] ^= 0x5c;
md5_start(&base);
md5_mid(&base, isecret);
-md5_end(&base, (uschar *)challenge, Ustrlen(challenge), md5secret);
+md5_end(&base, US challenge, Ustrlen(challenge), md5secret);
/* Compute the outer MD5 digest */
{
auth_cram_md5_options_block *ob =
(auth_cram_md5_options_block *)(ablock->options_block);
-uschar *challenge = string_sprintf("<%d.%d@%s>", getpid(), time(NULL),
- primary_hostname);
+uschar *challenge = string_sprintf("<%d.%ld@%s>", getpid(),
+ (long int) time(NULL), primary_hostname);
uschar *clear, *secret;
uschar digest[16];
int i, rc, len;
/* If we are running in the test harness, always send the same challenge,
an example string taken from the RFC. */
-if (running_in_test_harness)
+if (f.running_in_test_harness)
challenge = US"<1896.697170952@postoffice.reston.mci.net>";
/* No data should have been sent with the AUTH command */
/* Send the challenge, read the return */
if ((rc = auth_get_data(&data, challenge, Ustrlen(challenge))) != OK) return rc;
-if ((len = auth_b64decode(data, &clear)) < 0) return BAD64;
+if ((len = b64decode(data, &clear)) < 0) return BAD64;
/* The return consists of a user name, space-separated from the CRAM-MD5
-digest, expressed in hex. Extract the user name and put it in $1. Then check
-that the remaining length is 32. */
+digest, expressed in hex. Extract the user name and put it in $auth1 and $1.
+The former is now the preferred variable; the latter is the original one. Then
+check that the remaining length is 32. */
-expand_nstring[1] = clear;
+auth_vars[0] = expand_nstring[1] = clear;
while (*clear != 0 && !isspace(*clear)) clear++;
if (!isspace(*clear)) return FAIL;
*clear++ = 0;
if (secret == NULL)
{
- if (expand_string_forcedfail) return FAIL;
+ if (f.expand_string_forcedfail) return FAIL;
auth_defer_msg = expand_string_message;
return DEFER;
}
HDEBUG(D_auth)
{
uschar buff[64];
- debug_printf("CRAM-MD5: user name = %s\n", expand_nstring[1]);
+ debug_printf("CRAM-MD5: user name = %s\n", auth_vars[0]);
debug_printf(" challenge = %s\n", challenge);
debug_printf(" received = %s\n", clear);
- Ustrcpy(buff," digest = ");
+ Ustrcpy(buff, US" digest = ");
for (i = 0; i < 16; i++) sprintf(CS buff+22+2*i, "%02x", digest[i]);
debug_printf("%.54s\n", buff);
}
((b >= 'a')? b - 'a' + 10 : b - '0')) != digest[i]) return FAIL;
}
-return OK;
+/* Expand server_condition as an authorization check */
+return auth_check_serv_cond(ablock);
}
int
auth_cram_md5_client(
auth_instance *ablock, /* authenticator block */
- smtp_inblock *inblock, /* input connection */
- smtp_outblock *outblock, /* output connection */
+ void * sx, /* smtp connextion */
int timeout, /* command timeout */
- uschar *buffer, /* for reading response */
+ uschar *buffer, /* for reading response */
int buffsize) /* size of buffer */
{
auth_cram_md5_options_block *ob =
uschar digest[16];
/* If expansion of either the secret or the user name failed, return CANCELLED
-or ERROR, as approriate. */
+or ERROR, as appropriate. */
-if (secret == NULL || name == NULL)
+if (!secret || !name)
{
- if (expand_string_forcedfail) return CANCELLED;
+ if (f.expand_string_forcedfail)
+ {
+ *buffer = 0; /* No message */
+ return CANCELLED;
+ }
string_format(buffer, buffsize, "expansion of \"%s\" failed in "
"%s authenticator: %s",
- (secret == NULL)? ob->client_secret : ob->client_name,
+ !secret ? ob->client_secret : ob->client_name,
ablock->name, expand_string_message);
return ERROR;
}
/* Initiate the authentication exchange and read the challenge, which arrives
in base 64. */
-if (smtp_write_command(outblock, FALSE, "AUTH %s\r\n", ablock->public_name) < 0)
+if (smtp_write_command(sx, SCMD_FLUSH, "AUTH %s\r\n", ablock->public_name) < 0)
return FAIL_SEND;
-if (smtp_read_response(inblock, (uschar *)buffer, buffsize, '3', timeout) < 0)
+if (!smtp_read_response(sx, buffer, buffsize, '3', timeout))
return FAIL;
-if (auth_b64decode(buffer + 4, &challenge) < 0)
+if (b64decode(buffer + 4, &challenge) < 0)
{
string_format(buffer, buffsize, "bad base 64 string in challenge: %s",
big_buffer + 4);
/* Create the response from the user name plus the CRAM-MD5 digest */
string_format(big_buffer, big_buffer_size - 36, "%s", name);
-p = big_buffer;
-while (*p != 0) p++;
+for (p = big_buffer; *p; ) p++;
*p++ = ' ';
for (i = 0; i < 16; i++)
- {
- sprintf(CS p, "%02x", digest[i]);
- p += 2;
- }
+ p += sprintf(CS p, "%02x", digest[i]);
/* Send the response, in base 64, and check the result. The response is
-in big_buffer, but auth_b64encode() returns its result in working store,
+in big_buffer, but b64encode() returns its result in working store,
so calling smtp_write_command(), which uses big_buffer, is OK. */
buffer[0] = 0;
-if (smtp_write_command(outblock, FALSE, "%s\r\n", auth_b64encode(big_buffer,
+if (smtp_write_command(sx, SCMD_FLUSH, "%s\r\n", b64encode(CUS big_buffer,
p - big_buffer)) < 0) return FAIL_SEND;
-return smtp_read_response(inblock, (uschar *)buffer, buffsize, '2', timeout)?
- OK : FAIL;
+return smtp_read_response(sx, US buffer, buffsize, '2', timeout)
+ ? OK : FAIL;
}
#endif /* STAND_ALONE */
#endif
+#endif /*!MACRO_PREDEF*/
/* End of cram_md5.c */