#include "socket.h"
#include "i18n.h"
-#include "md5.h"
+#include "fm_md5.h"
-static void hmac_md5 (unsigned char *password, size_t pass_len,
- unsigned char *challenge, size_t chal_len,
- unsigned char *response, size_t resp_len)
+void hmac_md5 (const unsigned char *password, size_t pass_len,
+ const unsigned char *challenge, size_t chal_len,
+ unsigned char *response, size_t resp_len)
{
int i;
unsigned char ipad[64];
MD5Final (response, &ctx);
}
-int do_cram_md5 (int sock, struct query *ctl)
+int do_cram_md5 (int sock, const char *command, struct query *ctl, const char *strip)
/* authenticate as per RFC2195 */
{
int result;
int len;
- unsigned char buf1[1024];
- unsigned char msg_id[768];
+ char buf1[1024];
+ char msg_id[768];
unsigned char response[16];
- unsigned char reply[1024];
+ char reply[1024];
+ char *respdata;
- gen_send (sock, "AUTHENTICATE CRAM-MD5");
+ gen_send (sock, "%s CRAM-MD5", command);
/* From RFC2195:
* The data encoded in the first ready response contains an
return result;
}
- len = from64tobits (msg_id, buf1);
+ /* caller may specify a response prefix we should strip if present */
+ respdata = buf1;
+ if (strip && strncmp(buf1, strip, strlen(strip)) == 0)
+ respdata += strlen(strip);
+ len = from64tobits (msg_id, respdata, sizeof(msg_id));
+
if (len < 0) {
- report (stderr, _("could not decode BASE64 challenge\n"));
+ report (stderr, GT_("could not decode BASE64 challenge\n"));
return PS_AUTHFAIL;
- } else if (len < sizeof (msg_id)) {
+ } else if ((size_t)len < sizeof (msg_id)) {
msg_id[len] = 0;
} else {
msg_id[sizeof (msg_id)-1] = 0;
}
if (outlevel >= O_DEBUG) {
- report (stdout, _("decoded as %s\n"), msg_id);
+ report (stdout, GT_("decoded as %s\n"), msg_id);
}
/* The client makes note of the data and then responds with a string
* (including angle-brackets).
*/
- hmac_md5(ctl->password, strlen(ctl->password),
- msg_id, strlen (msg_id),
+ hmac_md5((unsigned char *)ctl->password, strlen(ctl->password),
+ (unsigned char *)msg_id, strlen (msg_id),
response, sizeof (response));
-#ifdef HAVE_SNPRINTF
- snprintf (reply, sizeof (reply),
-#else
- sprintf(reply,
-#endif
+ snprintf (reply, sizeof(reply),
"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
ctl->remotename,
response[0], response[1], response[2], response[3],
response[8], response[9], response[10], response[11],
response[12], response[13], response[14], response[15]);
- if (outlevel >= O_DEBUG) {
- report (stdout, _("replying with %s\n"), reply);
- }
-
to64frombits (buf1, reply, strlen(reply));
- if (outlevel >= O_MONITOR) {
- report (stdout, "CRAM> %s\n", buf1);
- }
+ /* ship the authentication back, accept the server's responses */
/* PMDF5.2 IMAP has a bug that requires this to be a single write */
- strcat (buf1, "\r\n");
- SockWrite (sock, buf1, strlen (buf1));
-
- if ((result = gen_recv (sock, buf1, sizeof (buf1))))
- return result;
-
- /*
- * Ugh. This has to recognize all kinds of success lines.
- * These two tests will catch IMAP and POP OK or SMTP-like
- * protocols that use 2xx as a success indication.
- */
- if (buf1[0] = '2' || strstr(buf1, "OK"))
+ suppress_tags = TRUE;
+ result = gen_transact(sock, "%s", buf1);
+ suppress_tags = FALSE;
+ if (result)
+ return(result);
+ else
return(PS_SUCCESS);
- else
- return(PS_AUTHFAIL);
}
/* cram.c ends here */