Statistics
| Revision:

root / src / smtp.c @ 133

History | View | Annotate | Download (13.6 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 1 hiro
 * Copyright (C) 1999-2004 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#ifdef HAVE_CONFIG_H
21 1 hiro
#  include "config.h"
22 1 hiro
#endif
23 1 hiro
24 1 hiro
#include <glib.h>
25 92 hiro
#include <glib/gi18n.h>
26 1 hiro
#include <stdio.h>
27 1 hiro
#include <string.h>
28 1 hiro
29 1 hiro
#include "smtp.h"
30 1 hiro
#include "md5.h"
31 1 hiro
#include "base64.h"
32 1 hiro
#include "utils.h"
33 1 hiro
34 1 hiro
static void smtp_session_destroy(Session *session);
35 1 hiro
36 1 hiro
static gint smtp_from(SMTPSession *session);
37 1 hiro
38 1 hiro
static gint smtp_auth(SMTPSession *session);
39 1 hiro
static gint smtp_starttls(SMTPSession *session);
40 1 hiro
static gint smtp_auth_cram_md5(SMTPSession *session);
41 1 hiro
static gint smtp_auth_login(SMTPSession *session);
42 1 hiro
43 1 hiro
static gint smtp_ehlo(SMTPSession *session);
44 1 hiro
static gint smtp_ehlo_recv(SMTPSession *session, const gchar *msg);
45 1 hiro
46 1 hiro
static gint smtp_helo(SMTPSession *session);
47 1 hiro
static gint smtp_rcpt(SMTPSession *session);
48 1 hiro
static gint smtp_data(SMTPSession *session);
49 1 hiro
static gint smtp_send_data(SMTPSession *session);
50 1 hiro
/* static gint smtp_rset(SMTPSession *session); */
51 1 hiro
static gint smtp_quit(SMTPSession *session);
52 1 hiro
static gint smtp_eom(SMTPSession *session);
53 1 hiro
54 1 hiro
static gint smtp_session_recv_msg(Session *session, const gchar *msg);
55 1 hiro
static gint smtp_session_send_data_finished(Session *session, guint len);
56 1 hiro
57 1 hiro
58 1 hiro
Session *smtp_session_new(void)
59 1 hiro
{
60 1 hiro
        SMTPSession *session;
61 1 hiro
62 1 hiro
        session = g_new0(SMTPSession, 1);
63 1 hiro
64 1 hiro
        session_init(SESSION(session));
65 1 hiro
66 1 hiro
        SESSION(session)->type             = SESSION_SMTP;
67 1 hiro
68 1 hiro
        SESSION(session)->recv_msg         = smtp_session_recv_msg;
69 1 hiro
70 1 hiro
        SESSION(session)->recv_data_finished = NULL;
71 1 hiro
        SESSION(session)->send_data_finished = smtp_session_send_data_finished;
72 1 hiro
73 1 hiro
        SESSION(session)->destroy          = smtp_session_destroy;
74 1 hiro
75 1 hiro
        session->state                     = SMTP_READY;
76 1 hiro
77 1 hiro
#if USE_SSL
78 1 hiro
        session->tls_init_done             = FALSE;
79 1 hiro
#endif
80 1 hiro
81 1 hiro
        session->hostname                  = NULL;
82 1 hiro
        session->user                      = NULL;
83 1 hiro
        session->pass                      = NULL;
84 1 hiro
85 1 hiro
        session->from                      = NULL;
86 1 hiro
        session->to_list                   = NULL;
87 1 hiro
        session->cur_to                    = NULL;
88 1 hiro
89 1 hiro
        session->send_data                 = NULL;
90 1 hiro
        session->send_data_len             = 0;
91 1 hiro
92 1 hiro
        session->avail_auth_type           = 0;
93 1 hiro
        session->forced_auth_type          = 0;
94 1 hiro
        session->auth_type                 = 0;
95 1 hiro
96 1 hiro
        session->error_val                 = SM_OK;
97 1 hiro
        session->error_msg                 = NULL;
98 1 hiro
99 1 hiro
        return SESSION(session);
100 1 hiro
}
101 1 hiro
102 1 hiro
static void smtp_session_destroy(Session *session)
103 1 hiro
{
104 1 hiro
        SMTPSession *smtp_session = SMTP_SESSION(session);
105 1 hiro
106 1 hiro
        g_free(smtp_session->hostname);
107 1 hiro
        g_free(smtp_session->user);
108 1 hiro
        g_free(smtp_session->pass);
109 1 hiro
        g_free(smtp_session->from);
110 1 hiro
111 1 hiro
        g_free(smtp_session->send_data);
112 1 hiro
113 1 hiro
        g_free(smtp_session->error_msg);
114 1 hiro
}
115 1 hiro
116 1 hiro
static gint smtp_from(SMTPSession *session)
117 1 hiro
{
118 1 hiro
        gchar buf[MSGBUFSIZE];
119 1 hiro
120 1 hiro
        g_return_val_if_fail(session->from != NULL, SM_ERROR);
121 1 hiro
122 1 hiro
        session->state = SMTP_FROM;
123 1 hiro
124 1 hiro
        if (strchr(session->from, '<'))
125 1 hiro
                g_snprintf(buf, sizeof(buf), "MAIL FROM:%s", session->from);
126 1 hiro
        else
127 1 hiro
                g_snprintf(buf, sizeof(buf), "MAIL FROM:<%s>", session->from);
128 1 hiro
129 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
130 1 hiro
        log_print("SMTP> %s\n", buf);
131 1 hiro
132 1 hiro
        return SM_OK;
133 1 hiro
}
134 1 hiro
135 1 hiro
static gint smtp_auth(SMTPSession *session)
136 1 hiro
{
137 1 hiro
138 1 hiro
        g_return_val_if_fail(session->user != NULL, SM_ERROR);
139 1 hiro
140 1 hiro
        session->state = SMTP_AUTH;
141 1 hiro
142 1 hiro
        if (session->forced_auth_type == SMTPAUTH_CRAM_MD5 ||
143 1 hiro
            (session->forced_auth_type == 0 &&
144 1 hiro
             (session->avail_auth_type & SMTPAUTH_CRAM_MD5) != 0))
145 1 hiro
                smtp_auth_cram_md5(session);
146 1 hiro
        else if (session->forced_auth_type == SMTPAUTH_LOGIN ||
147 1 hiro
                 (session->forced_auth_type == 0 &&
148 1 hiro
                  (session->avail_auth_type & SMTPAUTH_LOGIN) != 0))
149 1 hiro
                smtp_auth_login(session);
150 1 hiro
        else {
151 1 hiro
                log_warning(_("SMTP AUTH not available\n"));
152 1 hiro
                return SM_AUTHFAIL;
153 1 hiro
        }
154 1 hiro
155 1 hiro
        return SM_OK;
156 1 hiro
}
157 1 hiro
158 1 hiro
static gint smtp_auth_recv(SMTPSession *session, const gchar *msg)
159 1 hiro
{
160 1 hiro
        gchar buf[MSGBUFSIZE];
161 1 hiro
162 1 hiro
        switch (session->auth_type) {
163 1 hiro
        case SMTPAUTH_LOGIN:
164 1 hiro
                session->state = SMTP_AUTH_LOGIN_USER;
165 1 hiro
166 1 hiro
                if (!strncmp(msg, "334 ", 4)) {
167 1 hiro
                        base64_encode(buf, session->user, strlen(session->user));
168 1 hiro
169 1 hiro
                        session_send_msg(SESSION(session), SESSION_MSG_NORMAL,
170 1 hiro
                                         buf);
171 1 hiro
                        log_print("ESMTP> [USERID]\n");
172 1 hiro
                } else {
173 1 hiro
                        /* Server rejects AUTH */
174 1 hiro
                        session_send_msg(SESSION(session), SESSION_MSG_NORMAL,
175 1 hiro
                                         "*");
176 1 hiro
                        log_print("ESMTP> *\n");
177 1 hiro
                }
178 1 hiro
                break;
179 1 hiro
        case SMTPAUTH_CRAM_MD5:
180 1 hiro
                session->state = SMTP_AUTH_CRAM_MD5;
181 1 hiro
182 1 hiro
                if (!strncmp(msg, "334 ", 4)) {
183 1 hiro
                        gchar *response;
184 1 hiro
                        gchar *response64;
185 1 hiro
                        gchar *challenge;
186 1 hiro
                        gint challengelen;
187 1 hiro
                        guchar hexdigest[33];
188 1 hiro
189 1 hiro
                        challenge = g_malloc(strlen(msg + 4) + 1);
190 1 hiro
                        challengelen = base64_decode(challenge, msg + 4, -1);
191 1 hiro
                        challenge[challengelen] = '\0';
192 1 hiro
                        log_print("ESMTP< [Decoded: %s]\n", challenge);
193 1 hiro
194 1 hiro
                        g_snprintf(buf, sizeof(buf), "%s", session->pass);
195 1 hiro
                        md5_hex_hmac(hexdigest, challenge, challengelen,
196 1 hiro
                                     buf, strlen(session->pass));
197 1 hiro
                        g_free(challenge);
198 1 hiro
199 1 hiro
                        response = g_strdup_printf
200 1 hiro
                                ("%s %s", session->user, hexdigest);
201 1 hiro
                        log_print("ESMTP> [Encoded: %s]\n", response);
202 1 hiro
203 1 hiro
                        response64 = g_malloc((strlen(response) + 3) * 2 + 1);
204 1 hiro
                        base64_encode(response64, response, strlen(response));
205 1 hiro
                        g_free(response);
206 1 hiro
207 1 hiro
                        session_send_msg(SESSION(session), SESSION_MSG_NORMAL,
208 1 hiro
                                         response64);
209 1 hiro
                        log_print("ESMTP> %s\n", response64);
210 1 hiro
                        g_free(response64);
211 1 hiro
                } else {
212 1 hiro
                        /* Server rejects AUTH */
213 1 hiro
                        session_send_msg(SESSION(session), SESSION_MSG_NORMAL,
214 1 hiro
                                         "*");
215 1 hiro
                        log_print("ESMTP> *\n");
216 1 hiro
                }
217 1 hiro
                break;
218 1 hiro
        case SMTPAUTH_DIGEST_MD5:
219 1 hiro
        default:
220 1 hiro
                /* stop smtp_auth when no correct authtype */
221 1 hiro
                session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*");
222 1 hiro
                log_print("ESMTP> *\n");
223 1 hiro
                break;
224 1 hiro
        }
225 1 hiro
226 1 hiro
        return SM_OK;
227 1 hiro
}
228 1 hiro
229 1 hiro
static gint smtp_auth_login_user_recv(SMTPSession *session, const gchar *msg)
230 1 hiro
{
231 1 hiro
        gchar buf[MSGBUFSIZE];
232 1 hiro
233 1 hiro
        session->state = SMTP_AUTH_LOGIN_PASS;
234 1 hiro
235 1 hiro
        if (!strncmp(msg, "334 ", 4))
236 1 hiro
                base64_encode(buf, session->pass, strlen(session->pass));
237 1 hiro
        else
238 1 hiro
                /* Server rejects AUTH */
239 1 hiro
                g_snprintf(buf, sizeof(buf), "*");
240 1 hiro
241 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
242 1 hiro
        log_print("ESMTP> [PASSWORD]\n");
243 1 hiro
244 1 hiro
        return SM_OK;
245 1 hiro
}
246 1 hiro
247 1 hiro
static gint smtp_ehlo(SMTPSession *session)
248 1 hiro
{
249 1 hiro
        gchar buf[MSGBUFSIZE];
250 1 hiro
251 1 hiro
        session->state = SMTP_EHLO;
252 1 hiro
253 1 hiro
        session->avail_auth_type = 0;
254 1 hiro
255 1 hiro
        g_snprintf(buf, sizeof(buf), "EHLO %s",
256 1 hiro
                   session->hostname ? session->hostname : get_domain_name());
257 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
258 1 hiro
        log_print("ESMTP> %s\n", buf);
259 1 hiro
260 1 hiro
        return SM_OK;
261 1 hiro
}
262 1 hiro
263 1 hiro
static gint smtp_ehlo_recv(SMTPSession *session, const gchar *msg)
264 1 hiro
{
265 1 hiro
        if (strncmp(msg, "250", 3) == 0) {
266 1 hiro
                const gchar *p = msg;
267 1 hiro
                p += 3;
268 1 hiro
                if (*p == '-' || *p == ' ') p++;
269 1 hiro
                if (g_strncasecmp(p, "AUTH", 4) == 0) {
270 1 hiro
                        p += 5;
271 1 hiro
                        if (strcasestr(p, "LOGIN"))
272 1 hiro
                                session->avail_auth_type |= SMTPAUTH_LOGIN;
273 1 hiro
                        if (strcasestr(p, "CRAM-MD5"))
274 1 hiro
                                session->avail_auth_type |= SMTPAUTH_CRAM_MD5;
275 1 hiro
                        if (strcasestr(p, "DIGEST-MD5"))
276 1 hiro
                                session->avail_auth_type |= SMTPAUTH_DIGEST_MD5;
277 1 hiro
                }
278 1 hiro
                return SM_OK;
279 1 hiro
        } else if ((msg[0] == '1' || msg[0] == '2' || msg[0] == '3') &&
280 1 hiro
            (msg[3] == ' ' || msg[3] == '\0'))
281 1 hiro
                return SM_OK;
282 1 hiro
        else if (msg[0] == '5' && msg[1] == '0' &&
283 1 hiro
                 (msg[2] == '4' || msg[2] == '3' || msg[2] == '1'))
284 1 hiro
                return SM_ERROR;
285 1 hiro
286 1 hiro
        return SM_ERROR;
287 1 hiro
}
288 1 hiro
289 1 hiro
static gint smtp_starttls(SMTPSession *session)
290 1 hiro
{
291 1 hiro
        session->state = SMTP_STARTTLS;
292 1 hiro
293 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "STARTTLS");
294 1 hiro
        log_print("ESMTP> STARTTLS\n");
295 1 hiro
296 1 hiro
        return SM_OK;
297 1 hiro
}
298 1 hiro
299 1 hiro
static gint smtp_auth_cram_md5(SMTPSession *session)
300 1 hiro
{
301 1 hiro
        session->state = SMTP_AUTH;
302 1 hiro
        session->auth_type = SMTPAUTH_CRAM_MD5;
303 1 hiro
304 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "AUTH CRAM-MD5");
305 1 hiro
        log_print("ESMTP> AUTH CRAM-MD5\n");
306 1 hiro
307 1 hiro
        return SM_OK;
308 1 hiro
}
309 1 hiro
310 1 hiro
static gint smtp_auth_login(SMTPSession *session)
311 1 hiro
{
312 1 hiro
        session->state = SMTP_AUTH;
313 1 hiro
        session->auth_type = SMTPAUTH_LOGIN;
314 1 hiro
315 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "AUTH LOGIN");
316 1 hiro
        log_print("ESMTP> AUTH LOGIN\n");
317 1 hiro
318 1 hiro
        return SM_OK;
319 1 hiro
}
320 1 hiro
321 1 hiro
static gint smtp_helo(SMTPSession *session)
322 1 hiro
{
323 1 hiro
        gchar buf[MSGBUFSIZE];
324 1 hiro
325 1 hiro
        session->state = SMTP_HELO;
326 1 hiro
327 1 hiro
        g_snprintf(buf, sizeof(buf), "HELO %s",
328 1 hiro
                   session->hostname ? session->hostname : get_domain_name());
329 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
330 1 hiro
        log_print("SMTP> %s\n", buf);
331 1 hiro
332 1 hiro
        return SM_OK;
333 1 hiro
}
334 1 hiro
335 1 hiro
static gint smtp_rcpt(SMTPSession *session)
336 1 hiro
{
337 1 hiro
        gchar buf[MSGBUFSIZE];
338 1 hiro
        gchar *to;
339 1 hiro
340 1 hiro
        g_return_val_if_fail(session->cur_to != NULL, SM_ERROR);
341 1 hiro
342 1 hiro
        session->state = SMTP_RCPT;
343 1 hiro
344 1 hiro
        to = (gchar *)session->cur_to->data;
345 1 hiro
346 1 hiro
        if (strchr(to, '<'))
347 1 hiro
                g_snprintf(buf, sizeof(buf), "RCPT TO:%s", to);
348 1 hiro
        else
349 1 hiro
                g_snprintf(buf, sizeof(buf), "RCPT TO:<%s>", to);
350 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
351 1 hiro
        log_print("SMTP> %s\n", buf);
352 1 hiro
353 1 hiro
        session->cur_to = session->cur_to->next;
354 1 hiro
355 1 hiro
        return SM_OK;
356 1 hiro
}
357 1 hiro
358 1 hiro
static gint smtp_data(SMTPSession *session)
359 1 hiro
{
360 1 hiro
        session->state = SMTP_DATA;
361 1 hiro
362 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "DATA");
363 1 hiro
        log_print("SMTP> DATA\n");
364 1 hiro
365 1 hiro
        return SM_OK;
366 1 hiro
}
367 1 hiro
368 1 hiro
static gint smtp_send_data(SMTPSession *session)
369 1 hiro
{
370 1 hiro
        session->state = SMTP_SEND_DATA;
371 1 hiro
372 1 hiro
        session_send_data(SESSION(session), session->send_data,
373 1 hiro
                          session->send_data_len);
374 1 hiro
375 1 hiro
        return SM_OK;
376 1 hiro
}
377 1 hiro
378 1 hiro
#if 0
379 1 hiro
static gint smtp_rset(SMTPSession *session)
380 1 hiro
{
381 1 hiro
        session->state = SMTP_RSET;
382 1 hiro
383 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "RSET");
384 1 hiro
        log_print("SMTP> RSET\n");
385 1 hiro
386 1 hiro
        return SM_OK;
387 1 hiro
}
388 1 hiro
#endif
389 1 hiro
390 1 hiro
static gint smtp_quit(SMTPSession *session)
391 1 hiro
{
392 1 hiro
        session->state = SMTP_QUIT;
393 1 hiro
394 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "QUIT");
395 1 hiro
        log_print("SMTP> QUIT\n");
396 1 hiro
397 1 hiro
        return SM_OK;
398 1 hiro
}
399 1 hiro
400 1 hiro
static gint smtp_eom(SMTPSession *session)
401 1 hiro
{
402 1 hiro
        session->state = SMTP_EOM;
403 1 hiro
404 1 hiro
        session_send_msg(SESSION(session), SESSION_MSG_NORMAL, ".");
405 1 hiro
        log_print("SMTP> . (EOM)\n");
406 1 hiro
407 1 hiro
        return SM_OK;
408 1 hiro
}
409 1 hiro
410 1 hiro
static gint smtp_session_recv_msg(Session *session, const gchar *msg)
411 1 hiro
{
412 1 hiro
        SMTPSession *smtp_session = SMTP_SESSION(session);
413 1 hiro
        gboolean cont = FALSE;
414 1 hiro
415 1 hiro
        if (strlen(msg) < 4) {
416 1 hiro
                log_warning(_("bad SMTP response\n"));
417 1 hiro
                return -1;
418 1 hiro
        }
419 1 hiro
420 1 hiro
        switch (smtp_session->state) {
421 1 hiro
        case SMTP_EHLO:
422 1 hiro
        case SMTP_STARTTLS:
423 1 hiro
        case SMTP_AUTH:
424 1 hiro
        case SMTP_AUTH_LOGIN_USER:
425 1 hiro
        case SMTP_AUTH_LOGIN_PASS:
426 1 hiro
        case SMTP_AUTH_CRAM_MD5:
427 1 hiro
                log_print("ESMTP< %s\n", msg);
428 1 hiro
                break;
429 1 hiro
        default:
430 1 hiro
                log_print("SMTP< %s\n", msg);
431 1 hiro
                break;
432 1 hiro
        }
433 1 hiro
434 1 hiro
        if (msg[0] == '5' && msg[1] == '0' &&
435 1 hiro
            (msg[2] == '4' || msg[2] == '3' || msg[2] == '1')) {
436 1 hiro
                log_warning(_("error occurred on SMTP session\n"));
437 1 hiro
                smtp_session->state = SMTP_ERROR;
438 1 hiro
                smtp_session->error_val = SM_ERROR;
439 1 hiro
                g_free(smtp_session->error_msg);
440 1 hiro
                smtp_session->error_msg = g_strdup(msg);
441 1 hiro
                return -1;
442 1 hiro
        }
443 1 hiro
444 1 hiro
        if (!strncmp(msg, "535", 3)) {
445 1 hiro
                log_warning(_("error occurred on authentication\n"));
446 1 hiro
                smtp_session->state = SMTP_ERROR;
447 1 hiro
                smtp_session->error_val = SM_AUTHFAIL;
448 1 hiro
                g_free(smtp_session->error_msg);
449 1 hiro
                smtp_session->error_msg = g_strdup(msg);
450 1 hiro
                return -1;
451 1 hiro
        }
452 1 hiro
453 1 hiro
        if (msg[0] != '1' && msg[0] != '2' && msg[0] != '3') {
454 1 hiro
                log_warning(_("error occurred on SMTP session\n"));
455 1 hiro
                smtp_session->state = SMTP_ERROR;
456 1 hiro
                smtp_session->error_val = SM_ERROR;
457 1 hiro
                g_free(smtp_session->error_msg);
458 1 hiro
                smtp_session->error_msg = g_strdup(msg);
459 1 hiro
                return -1;
460 1 hiro
        }
461 1 hiro
462 1 hiro
        if (msg[3] == '-')
463 1 hiro
                cont = TRUE;
464 1 hiro
        else if (msg[3] != ' ' && msg[3] != '\0') {
465 1 hiro
                log_warning(_("bad SMTP response\n"));
466 1 hiro
                smtp_session->state = SMTP_ERROR;
467 1 hiro
                smtp_session->error_val = SM_UNRECOVERABLE;
468 1 hiro
                return -1;
469 1 hiro
        }
470 1 hiro
471 1 hiro
        /* ignore all multiline responses except for EHLO */
472 1 hiro
        if (cont && smtp_session->state != SMTP_EHLO)
473 1 hiro
                return session_recv_msg(session);
474 1 hiro
475 1 hiro
        switch (smtp_session->state) {
476 1 hiro
        case SMTP_READY:
477 1 hiro
        case SMTP_CONNECTED:
478 1 hiro
#if USE_SSL
479 1 hiro
                if (smtp_session->user || session->ssl_type != SSL_NONE)
480 1 hiro
#else
481 1 hiro
                if (smtp_session->user)
482 1 hiro
#endif
483 1 hiro
                        smtp_ehlo(smtp_session);
484 1 hiro
                else
485 1 hiro
                        smtp_helo(smtp_session);
486 1 hiro
                break;
487 1 hiro
        case SMTP_HELO:
488 1 hiro
                smtp_from(smtp_session);
489 1 hiro
                break;
490 1 hiro
        case SMTP_EHLO:
491 1 hiro
                smtp_ehlo_recv(smtp_session, msg);
492 1 hiro
                if (cont == TRUE)
493 1 hiro
                        break;
494 1 hiro
#if USE_SSL
495 1 hiro
                if (session->ssl_type == SSL_STARTTLS &&
496 1 hiro
                    smtp_session->tls_init_done == FALSE) {
497 1 hiro
                        smtp_starttls(smtp_session);
498 1 hiro
                        break;
499 1 hiro
                }
500 1 hiro
#endif
501 1 hiro
                if (smtp_session->user) {
502 1 hiro
                        if (smtp_auth(smtp_session) != SM_OK)
503 1 hiro
                                smtp_from(smtp_session);
504 1 hiro
                } else
505 1 hiro
                        smtp_from(smtp_session);
506 1 hiro
                break;
507 1 hiro
        case SMTP_STARTTLS:
508 1 hiro
#if USE_SSL
509 1 hiro
                if (session_start_tls(session) < 0) {
510 1 hiro
                        log_warning(_("can't start TLS session\n"));
511 1 hiro
                        smtp_session->state = SMTP_ERROR;
512 1 hiro
                        smtp_session->error_val = SM_ERROR;
513 1 hiro
                        return -1;
514 1 hiro
                }
515 1 hiro
                smtp_session->tls_init_done = TRUE;
516 1 hiro
                smtp_ehlo(smtp_session);
517 1 hiro
#endif
518 1 hiro
                break;
519 1 hiro
        case SMTP_AUTH:
520 1 hiro
                smtp_auth_recv(smtp_session, msg);
521 1 hiro
                break;
522 1 hiro
        case SMTP_AUTH_LOGIN_USER:
523 1 hiro
                smtp_auth_login_user_recv(smtp_session, msg);
524 1 hiro
                break;
525 1 hiro
        case SMTP_AUTH_LOGIN_PASS:
526 1 hiro
        case SMTP_AUTH_CRAM_MD5:
527 1 hiro
                smtp_from(smtp_session);
528 1 hiro
                break;
529 1 hiro
        case SMTP_FROM:
530 1 hiro
                if (smtp_session->cur_to)
531 1 hiro
                        smtp_rcpt(smtp_session);
532 1 hiro
                break;
533 1 hiro
        case SMTP_RCPT:
534 1 hiro
                if (smtp_session->cur_to)
535 1 hiro
                        smtp_rcpt(smtp_session);
536 1 hiro
                else
537 1 hiro
                        smtp_data(smtp_session);
538 1 hiro
                break;
539 1 hiro
        case SMTP_DATA:
540 1 hiro
                smtp_send_data(smtp_session);
541 1 hiro
                break;
542 1 hiro
        case SMTP_EOM:
543 1 hiro
                smtp_quit(smtp_session);
544 1 hiro
                break;
545 1 hiro
        case SMTP_QUIT:
546 1 hiro
                session_disconnect(session);
547 1 hiro
                break;
548 1 hiro
        case SMTP_ERROR:
549 1 hiro
        default:
550 1 hiro
                log_warning(_("error occurred on SMTP session\n"));
551 1 hiro
                smtp_session->error_val = SM_ERROR;
552 1 hiro
                return -1;
553 1 hiro
        }
554 1 hiro
555 1 hiro
        if (cont)
556 1 hiro
                return session_recv_msg(session);
557 1 hiro
558 1 hiro
        return 0;
559 1 hiro
}
560 1 hiro
561 1 hiro
static gint smtp_session_send_data_finished(Session *session, guint len)
562 1 hiro
{
563 1 hiro
        smtp_eom(SMTP_SESSION(session));
564 1 hiro
        return 0;
565 1 hiro
}