initial message templates support
[claws.git] / src / esmtp.c
blob529bef2f1b182678ea366f0372ffd5a08383b3b2
1 /*
2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999,2000 Hiroyuki Yamamoto
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include <glib.h>
21 #include <stdio.h>
22 #include <string.h>
24 #include "esmtp.h"
25 #include "smtp.h"
26 #include "socket.h"
27 #include "utils.h"
28 #include "md5.h"
29 #include "base64.h"
31 #define MSGBUFSIZE 8192
33 static gint verbose = 1;
34 static gchar esmtp_response[MSGBUFSIZE];
36 gint esmtp_auth_cram_md5(SockInfo *sock)
38 gchar buf[MSGBUFSIZE];
40 g_snprintf(buf, sizeof(buf), "AUTH CRAM-MD5");
41 sock_printf(sock, "%s\r\n", buf);
43 if (verbose)
44 log_print("ESMTP> %s\n", buf);
46 return esmtp_ok(sock);
49 gint esmtp_auth_login(SockInfo *sock)
51 gchar buf[MSGBUFSIZE];
53 g_snprintf(buf, sizeof(buf), "AUTH LOGIN");
54 sock_printf(sock, "%s\r\n", buf);
56 if (verbose)
57 log_print("ESMTP> %s\n", buf);
59 return esmtp_ok(sock);
62 gint esmtp_auth(SockInfo *sock, SMTPAuthType authtype,
63 const gchar *userid, const gchar *passwd,
64 gboolean use_smtp_auth)
66 gchar buf[MSGBUFSIZE];
67 guchar hexdigest[33];
68 gchar *challenge, *response, *response64;
69 gint challengelen;
70 /* const gchar delimiters[]=" "; */
71 gchar *token;
73 switch (authtype) {
74 case SMTPAUTH_LOGIN:
75 if (!strncmp(esmtp_response, "334 ", 4))
76 to64frombits(buf, userid, strlen(userid));
77 else
78 /* Server rejects AUTH */
79 g_snprintf(buf, sizeof(buf), "*");
81 sock_printf(sock, "%s\r\n", buf);
82 if (verbose) log_print("ESMTP> USERID\n");
84 esmtp_ok(sock); /* to read the answer from the server */
86 if (!strncmp(esmtp_response, "334 ", 4))
87 to64frombits(buf, passwd, strlen(passwd));
88 else
89 /* Server rejects AUTH */
90 g_snprintf(buf, sizeof(buf), "*");
92 sock_printf(sock, "%s\r\n", buf);
93 if (verbose) log_print("ESMTP> PASSWORD\n");
94 break;
95 case SMTPAUTH_CRAM_MD5:
96 if (!strncmp(esmtp_response, "334 ", 4)) {
97 /* remove 334 from esmtp_response */
98 g_snprintf(buf, sizeof(buf), "%s",esmtp_response);
99 token = strtok(buf, " ");
100 token = strtok(NULL, " ");
101 challenge = g_malloc(strlen(token)+1);
102 challengelen = from64tobits(challenge,token);
103 if (verbose)
104 log_print("ESMTP< Decoded: %s\n", challenge);
106 g_snprintf(buf, sizeof(buf), "%s", passwd);
107 md5_hex_hmac(hexdigest, challenge, challengelen,
108 buf, strlen(passwd));
110 response = g_strdup_printf("%s %s", userid, hexdigest);
111 if (verbose)
112 log_print("ESMTP> Encoded %s\n",response);
114 response64 = g_malloc((strlen(response) + 3) * 2 + 1);
115 to64frombits(response64, response, strlen(response));
116 g_free(response);
118 sock_printf(sock, "%s\r\n", response64);
119 if (verbose) log_print("ESMTP> %s\n", response64);
120 g_free(response64);
121 } else {
122 /* Server rejects AUTH */
123 g_snprintf(buf, sizeof(buf), "*");
124 sock_printf(sock, "%s\r\n", buf);
125 if (verbose)
126 log_print("ESMTP> %s\n",buf);
128 break;
129 case SMTPAUTH_DIGEST_MD5:
130 default:
131 /* stop esmtp_auth when no correct authtype */
132 g_snprintf(buf, sizeof(buf), "*");
133 sock_printf(sock, "%s\r\n", buf);
134 if (verbose) log_print("ESMTP> %s\n", buf);
135 break;
138 return esmtp_ok(sock);
141 gint esmtp_ok(SockInfo *sock)
143 while (sock_gets(sock, esmtp_response, sizeof(esmtp_response) - 1)
144 != -1) {
145 if (strlen(esmtp_response) < 4)
146 return SM_ERROR;
147 strretchomp(esmtp_response);
149 if (verbose)
150 log_print("ESMTP< %s\n", esmtp_response);
152 if ((esmtp_response[0] == '1' || esmtp_response[0] == '2' ||
153 esmtp_response[0] == '3') && esmtp_response[3] == ' ')
154 return SM_OK;
155 else if (esmtp_response[3] != '-')
156 return SM_ERROR;
157 else if (esmtp_response[0] == '5' &&
158 esmtp_response[1] == '0' &&
159 (esmtp_response[2] == '4' ||
160 esmtp_response[2] == '3' ||
161 esmtp_response[2] == '1'))
162 return SM_ERROR;
165 return SM_UNRECOVERABLE;