try to authenticate with CRAM-MD5
[claws.git] / src / smtp.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2001 Hiroyuki Yamamoto
4  *
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.
9  *
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.
14  *
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.
18  */
19
20 #include <glib.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "smtp.h"
25 #include "esmtp.h"
26 #include "socket.h"
27 #include "utils.h"
28
29 #define MSGBUFSIZE      8192
30
31 static gint verbose = 1;
32 static gchar smtp_response[MSGBUFSIZE];
33
34 gint smtp_helo(SockInfo *sock, const gchar *hostname, gboolean esmtp)
35 {
36         if (esmtp)
37                 return esmtp_ehlo(sock, hostname);
38         else {
39                 sock_printf(sock, "HELO %s\r\n", hostname);
40                 if (verbose)
41                         log_print("SMTP> HELO %s\n", hostname);
42
43                 return smtp_ok(sock);
44         }
45 }
46
47 gint smtp_from(SockInfo *sock, const gchar *from,
48                const gchar *userid, const gchar *passwd,
49                gboolean use_smtp_auth)
50 {
51         gchar buf[MSGBUFSIZE];
52         SMTPAuthType authtype;
53
54         if (use_smtp_auth) {
55                 /* exist AUTH-Type CRAM_MD5 */
56                 if (!smtp_auth_methods[SMTPAUTH_CRAM_MD5]
57                     || esmtp_auth_cram_md5(sock) == SM_ERROR) {
58                         /* exist AUTH-Type LOGIN */
59                         if (!smtp_auth_methods[SMTPAUTH_LOGIN]
60                             || esmtp_auth_login(sock) == SM_ERROR)
61                                 return SM_ERROR;
62                         else
63                                 authtype = SMTPAUTH_LOGIN;
64                 } else
65                         authtype = SMTPAUTH_CRAM_MD5;
66
67                 if (esmtp_auth(sock, authtype, userid, passwd) != SM_OK)
68                         return SM_AUTHFAIL;
69         }
70
71         if (strchr(from, '<'))
72                 g_snprintf(buf, sizeof(buf), "MAIL FROM: %s", from);
73         else
74                 g_snprintf(buf, sizeof(buf), "MAIL FROM: <%s>", from);
75
76         sock_printf(sock, "%s\r\n", buf);
77         if (verbose)
78                 log_print("SMTP> %s\n", buf);
79
80         return smtp_ok(sock);
81 }
82
83 gint smtp_rcpt(SockInfo *sock, const gchar *to)
84 {
85         gchar buf[MSGBUFSIZE];
86
87         if (strchr(to, '<'))
88                 g_snprintf(buf, sizeof(buf), "RCPT TO: %s", to);
89         else
90                 g_snprintf(buf, sizeof(buf), "RCPT TO: <%s>", to);
91
92         sock_printf(sock, "%s\r\n", buf);
93         if (verbose)
94                 log_print("SMTP> %s\n", buf);
95
96         return smtp_ok(sock);
97 }
98
99 gint smtp_data(SockInfo *sock)
100 {
101         sock_printf(sock, "DATA\r\n");
102         if (verbose)
103                 log_print("SMTP> DATA\n");
104
105         return smtp_ok(sock);
106 }
107
108 gint smtp_rset(SockInfo *sock)
109 {
110         sock_printf(sock, "RSET\r\n");
111         if (verbose)
112                 log_print("SMTP> RSET\n");
113
114         return smtp_ok(sock);
115 }
116
117 gint smtp_quit(SockInfo *sock)
118 {
119         sock_printf(sock, "QUIT\r\n");
120         if (verbose)
121                 log_print("SMTP> QUIT\n");
122
123         return smtp_ok(sock);
124 }
125
126 gint smtp_eom(SockInfo *sock)
127 {
128         sock_printf(sock, ".\r\n");
129         if (verbose)
130                 log_print("SMTP> . (EOM)\n");
131
132         return smtp_ok(sock);
133 }
134
135 gint smtp_ok(SockInfo *sock)
136 {
137         while ((sock_gets(sock, smtp_response, sizeof(smtp_response) - 1))
138                != -1) {
139                 if (strlen(smtp_response) < 4)
140                         return SM_ERROR;
141                 strretchomp(smtp_response);
142
143                 if (verbose)
144                         log_print("SMTP< %s\n", smtp_response);
145
146                 if ((smtp_response[0] == '1' || smtp_response[0] == '2' ||
147                      smtp_response[0] == '3') &&
148                      (smtp_response[3] == ' ' || smtp_response[3] == '\0'))
149                         return SM_OK;
150                 else if (smtp_response[3] != '-')
151                         return SM_ERROR;
152                 else if (smtp_response[0] == '5' &&
153                          smtp_response[1] == '0' &&
154                          (smtp_response[2] == '4' ||
155                           smtp_response[2] == '3' ||
156                           smtp_response[2] == '1'))
157                         return SM_ERROR;
158         }
159
160         return SM_UNRECOVERABLE;
161 }