Commit 0b1e16be 0b1e16bea8f32524dd123cc267fe1839f9bc3b0f by Sergey Poznyakoff

pop3d: make tls more configurable

The "tls" statement can be used both within a server declaration
and in the global scope, the former overriding the latter.  Its
argument can be one of the following:

  no          TLS is not used.  The STLS command won't be available even
              if the tls configuration is otherwise complete.
  ondemand    TLS is initiated when the user issues the STLS command.
              This is the default when TLS is configured.
  required    Same as above, but the use of STLS is mandatory.  The
              authentication state is entered only after TLS negotiation
              has succeeded.
  connection  TLS is always forced when the connection is established (pops).

For compatibility with prior versions the tls-required statement is retained,
but is considered deprecated.  It is synonymous with "tls required".  The
"tls" statement allows for the following alias values:

  false, off, 0           same as  no
  stls                    same as  ondemand
  yes, true, on, 1        same as  connection

Internally, all handler functions receive a pointer to the POP session
structure, which configures the current session.  In particular, it
contains the TLS mode and capability list.

* pop3d/capa.c (pop3d_capa): Traverse the capability list,
outputting each of its elements.
(pop3d_session_init)
(pop3d_session_free): New functions.
* pop3d/logindelay.c (login_delay_capa): Change signature.
* pop3d/pop3d.c (tls_required): Remove.
(tls_mode): New variable.
(pop3d_srv_config) <tls>: Remove.
(pop3d_srv_config) <tls_mode>: New member.
(pop3d_srv_param): Change definition of the "tls" statement.
(pop3d_cfg_param): New statement "tls". Mark "tls-required"
as deprecated.
(pop3d_mainloop): Change type of the tls argument.
Initialize session and pass it to each handler.
(pop3d_connection): Decide whether and how to use TLS
using global and per-session settings, the latter
overriding the former.
* pop3d/pop3d.h (login_delay_capa): Change signature.
(tls_mode): New enum.
(pop3d_capa_type): New enum.
(pop3d_capa, pop3d_session): New structs.
(pop3d_session_init)
(pop3d_session_free): New protos.
(pop3d_command_handler_t): Change signature. All handlers and their
uses are changed accordingly.
* pop3d/stls.c (pop3d_stls): Return error if session does not
allow tls.
1 parent 98f7cc4c
...@@ -164,7 +164,7 @@ pop3d_apopuser (const char *user) ...@@ -164,7 +164,7 @@ pop3d_apopuser (const char *user)
164 } 164 }
165 165
166 int 166 int
167 pop3d_apop (char *arg) 167 pop3d_apop (char *arg, struct pop3d_session *sess)
168 { 168 {
169 char *p, *password, *user_digest, *user; 169 char *p, *password, *user_digest, *user;
170 struct mu_md5_ctx md5context; 170 struct mu_md5_ctx md5context;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 /* AUTH is not yet implemented */ 19 /* AUTH is not yet implemented */
20 20
21 int 21 int
22 pop3d_auth (char *arg MU_ARG_UNUSED) 22 pop3d_auth (char *arg MU_ARG_UNUSED, struct pop3d_session *sess MU_ARG_UNUSED)
23 { 23 {
24 if (state != AUTHORIZATION) 24 if (state != AUTHORIZATION)
25 return ERR_WRONG_STATE; 25 return ERR_WRONG_STATE;
......
...@@ -26,38 +26,134 @@ ...@@ -26,38 +26,134 @@
26 26
27 Capabilities available in the AUTHORIZATION state MUST be announced 27 Capabilities available in the AUTHORIZATION state MUST be announced
28 in both states. */ 28 in both states. */
29
30 static int
31 print_capa (void *item, void *data)
32 {
33 struct pop3d_capa *cp = item;
34 struct pop3d_session *session = data;
35 if (cp->type == capa_func)
36 {
37 cp->value.func (cp->name, session);
38 }
39 else
40 {
41 pop3d_outf ("%s", cp->name);
42 if (cp->value.string)
43 pop3d_outf ("%s", cp->value.string);
44 pop3d_outf ("\n");
45 }
46 return 0;
47 }
48
29 int 49 int
30 pop3d_capa (char *arg) 50 pop3d_capa (char *arg, struct pop3d_session *sess)
31 { 51 {
32 if (strlen (arg) != 0) 52 if (strlen (arg) != 0)
33 return ERR_BAD_ARGS; 53 return ERR_BAD_ARGS;
34 54
35 pop3d_outf ("+OK Capability list follows\n"); 55 pop3d_outf ("+OK Capability list follows\n");
36 pop3d_outf ("TOP\n"); 56 mu_list_foreach (sess->capa, print_capa, sess);
37 pop3d_outf ("USER\n"); 57 pop3d_outf (".\n");
38 pop3d_outf ("UIDL\n"); 58 return OK;
39 pop3d_outf ("RESP-CODES\n"); 59 }
40 pop3d_outf ("PIPELINING\n"); 60
41 if (pop3d_xlines) 61 static void
42 pop3d_outf ("XLINES\n"); 62 pop3d_append_capa_string (struct pop3d_session *sess, const char *name,
63 const char *value)
64 {
65 struct pop3d_capa *cp;
66
67 cp = mu_alloc (sizeof (*cp));
68 cp->type = capa_string;
69 cp->name = name;
70 cp->value.string = value ? mu_strdup (value) : NULL;
71 if (mu_list_append (sess->capa, cp))
72 mu_alloc_die ();
73 }
74
75 static void
76 pop3d_append_capa_func (struct pop3d_session *sess, const char *name,
77 void (*func) (const char *, struct pop3d_session *))
78 {
79 struct pop3d_capa *cp;
80
81 if (!func)
82 return;
83 cp = mu_alloc (sizeof (*cp));
84 cp->type = capa_func;
85 cp->name = name;
86 cp->value.func = func;
87 if (mu_list_append (sess->capa, cp))
88 mu_alloc_die ();
89 }
90
91 static void
92 capa_free (void *p)
93 {
94 struct pop3d_capa *cp = p;
95 if (cp->type == capa_string && cp->value.string)
96 free (cp->value.string);
97 free (cp);
98 }
99
100 static void
101 capa_implementation (const char *name, struct pop3d_session *session)
102 {
103 if (state == TRANSACTION) /* let's not advertise to just anyone */
104 pop3d_outf ("%s %s\n", name, PACKAGE_STRING);
105 }
43 106
44 #ifdef WITH_TLS 107 #ifdef WITH_TLS
45 if (tls_available && tls_done == 0) 108 static void
46 pop3d_outf ("STLS\n"); 109 capa_stls (const char *name, struct pop3d_session *session)
110 {
111 if ((session->tls == tls_ondemand || session->tls == tls_required)
112 && tls_available && tls_done == 0)
113 pop3d_outf ("%s\n", name);
114 }
115 #else
116 # define capa_stls NULL
47 #endif /* WITH_TLS */ 117 #endif /* WITH_TLS */
48 118
49 login_delay_capa (); 119 static void
50 /* This can be implemented by setting an header field on the message. */ 120 capa_user (const char *name, struct pop3d_session *session)
51 if (expire == EXPIRE_NEVER) 121 {
52 pop3d_outf ("EXPIRE NEVER\n");
53 else
54 pop3d_outf ("EXPIRE %s\n", mu_umaxtostr (0, expire));
55
56 if (state == INITIAL) 122 if (state == INITIAL)
57 pop3d_outf ("XTLSREQUIRED\n"); 123 pop3d_outf ("XTLSREQUIRED\n");
124 else
125 pop3d_outf ("USER\n");
126 }
58 127
59 if (state == TRANSACTION) /* let's not advertise to just anyone */ 128 void
60 pop3d_outf ("IMPLEMENTATION %s\n", PACKAGE_STRING); 129 pop3d_session_init (struct pop3d_session *session)
61 pop3d_outf (".\n"); 130 {
62 return OK; 131 if (mu_list_create (&session->capa))
132 mu_alloc_die ();
133 mu_list_set_destroy_item (session->capa, capa_free);
134
135 /* Initialize the capability list */
136 pop3d_append_capa_string (session, "TOP", NULL);
137 pop3d_append_capa_string (session, "UIDL", NULL);
138 pop3d_append_capa_string (session, "RESP-CODES", NULL);
139 pop3d_append_capa_string (session, "PIPELINING", NULL);
140 if (pop3d_xlines)
141 pop3d_append_capa_string (session, "XLINES", NULL);
142
143 pop3d_append_capa_func (session, "LOGIN-DELAY", login_delay_capa);
144
145 /* This can be implemented by setting an header field on the message. */
146 pop3d_append_capa_string (session, "EXPIRE",
147 (expire == EXPIRE_NEVER) ?
148 "NEVER" : mu_umaxtostr (0, expire));
149
150 pop3d_append_capa_func (session, NULL, capa_user);
151 pop3d_append_capa_func (session, "STLS", capa_stls);
152 pop3d_append_capa_func (session, "IMPLEMENTATION", capa_implementation);
153 }
154
155 void
156 pop3d_session_free (struct pop3d_session *session)
157 {
158 mu_list_destroy (&session->capa);
63 } 159 }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 /* DELE adds a message number to the list of messages to be deleted on QUIT */ 20 /* DELE adds a message number to the list of messages to be deleted on QUIT */
21 21
22 int 22 int
23 pop3d_dele (char *arg) 23 pop3d_dele (char *arg, struct pop3d_session *sess)
24 { 24 {
25 size_t num; 25 size_t num;
26 mu_message_t msg; 26 mu_message_t msg;
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
39 XLINES capability. 39 XLINES capability.
40 */ 40 */
41 int 41 int
42 pop3d_list (char *arg) 42 pop3d_list (char *arg, struct pop3d_session *sess)
43 { 43 {
44 size_t mesgno; 44 size_t mesgno;
45 mu_message_t msg = NULL; 45 mu_message_t msg = NULL;
......
...@@ -141,13 +141,13 @@ update_login_delay (char *username) ...@@ -141,13 +141,13 @@ update_login_delay (char *username)
141 } 141 }
142 142
143 void 143 void
144 login_delay_capa () 144 login_delay_capa (const char *name, struct pop3d_session *session)
145 { 145 {
146 mu_dbm_file_t db; 146 mu_dbm_file_t db;
147 147
148 if (login_delay && (db = open_stat_db (MU_STREAM_RDWR)) != NULL) 148 if (login_delay && (db = open_stat_db (MU_STREAM_RDWR)) != NULL)
149 { 149 {
150 pop3d_outf ("LOGIN-DELAY %s\n", mu_umaxtostr (0, login_delay)); 150 pop3d_outf ("%lu\n", (unsigned long) login_delay);
151 mu_dbm_destroy (&db); 151 mu_dbm_destroy (&db);
152 } 152 }
153 } 153 }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 /* Does nothing */ 20 /* Does nothing */
21 21
22 int 22 int
23 pop3d_noop (char *arg) 23 pop3d_noop (char *arg, struct pop3d_session *sess)
24 { 24 {
25 if (strlen (arg) != 0) 25 if (strlen (arg) != 0)
26 return ERR_BAD_ARGS; 26 return ERR_BAD_ARGS;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
18 #include "mailutils/pam.h" 18 #include "mailutils/pam.h"
19 #include "mailutils/libargp.h" 19 #include "mailutils/libargp.h"
20 #include "mailutils/pop3.h" 20 #include "mailutils/pop3.h"
21 #include "mailutils/kwd.h"
21 #include "tcpwrap.h" 22 #include "tcpwrap.h"
22 23
23 mu_mailbox_t mbox; 24 mu_mailbox_t mbox;
...@@ -29,13 +30,14 @@ mu_m_server_t server; ...@@ -29,13 +30,14 @@ mu_m_server_t server;
29 unsigned int idle_timeout; 30 unsigned int idle_timeout;
30 int pop3d_transcript; 31 int pop3d_transcript;
31 int debug_mode; 32 int debug_mode;
32 int tls_required;
33 int pop3d_xlines; 33 int pop3d_xlines;
34 char *apop_database_name = APOP_PASSFILE; 34 char *apop_database_name = APOP_PASSFILE;
35 int apop_database_safety = MU_FILE_SAFETY_ALL; 35 int apop_database_safety = MU_FILE_SAFETY_ALL;
36 uid_t apop_database_owner; 36 uid_t apop_database_owner;
37 int apop_database_owner_set; 37 int apop_database_owner_set;
38 38
39 enum tls_mode tls_mode;
40
39 #ifdef WITH_TLS 41 #ifdef WITH_TLS
40 int tls_available; 42 int tls_available;
41 int tls_done; 43 int tls_done;
...@@ -137,13 +139,61 @@ cb_bulletin_db (void *data, mu_config_value_t *val) ...@@ -137,13 +139,61 @@ cb_bulletin_db (void *data, mu_config_value_t *val)
137 struct pop3d_srv_config 139 struct pop3d_srv_config
138 { 140 {
139 struct mu_srv_config m_cfg; 141 struct mu_srv_config m_cfg;
140 int tls; 142 enum tls_mode tls_mode;
141 }; 143 };
142 144
145 #ifdef WITH_TLS
146 static int
147 cb_tls (void *data, mu_config_value_t *val)
148 {
149 int *res = data;
150 static struct mu_kwd tls_kwd[] = {
151 { "no", tls_no },
152 { "false", tls_no },
153 { "off", tls_no },
154 { "0", tls_no },
155 { "ondemand", tls_ondemand },
156 { "stls", tls_ondemand },
157 { "required", tls_required },
158 { "connection", tls_connection },
159 /* For compatibility with prior versions: */
160 { "yes", tls_connection },
161 { "true", tls_connection },
162 { "on", tls_connection },
163 { "1", tls_connection },
164 { NULL }
165 };
166
167 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
168 return 1;
169
170 if (mu_kwd_xlat_name (tls_kwd, val->v.string, res))
171 mu_error (_("not a valid tls keyword: %s"), val->v.string);
172 return 0;
173 }
174 #endif
175
176 static int
177 cb_tls_required (void *data, mu_config_value_t *val)
178 {
179 int *res = data;
180 int bv;
181
182 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
183 return 1;
184 if (mu_cfg_parse_boolean (val->v.string, &bv))
185 mu_error (_("Not a boolean value"));
186 else
187 *res = tls_required;
188 return 0;
189 }
190
143 static struct mu_cfg_param pop3d_srv_param[] = { 191 static struct mu_cfg_param pop3d_srv_param[] = {
144 { "tls", mu_cfg_bool, NULL, mu_offsetof (struct pop3d_srv_config, tls), NULL, 192 #ifdef WITH_TLS
145 N_("Use TLS encryption for this server") 193 { "tls", mu_cfg_callback,
146 }, 194 NULL, mu_offsetof (struct pop3d_srv_config, tls_mode), cb_tls,
195 N_("Kind of TLS encryption to use for this server") },
196 #endif
147 { NULL } 197 { NULL }
148 }; 198 };
149 199
...@@ -178,8 +228,11 @@ static struct mu_cfg_param pop3d_cfg_param[] = { ...@@ -178,8 +228,11 @@ static struct mu_cfg_param pop3d_cfg_param[] = {
178 N_("arg: list") }, 228 N_("arg: list") },
179 229
180 #ifdef WITH_TLS 230 #ifdef WITH_TLS
181 { "tls-required", mu_cfg_bool, &tls_required, 0, NULL, 231 { "tls", mu_cfg_callback, &tls_mode, 0, cb_tls,
182 N_("Always require STLS before entering authentication phase.") }, 232 N_("Kind of TLS encryption to use") },
233 { "tls-required", mu_cfg_callback, &tls_mode, 0, cb_tls_required,
234 N_("Always require STLS before entering authentication phase.\n"
235 "Deprecated, use \"tls required\" instead.") },
183 #endif 236 #endif
184 #ifdef ENABLE_LOGIN_DELAY 237 #ifdef ENABLE_LOGIN_DELAY
185 { "login-delay", mu_cfg_time, &login_delay, 0, NULL, 238 { "login-delay", mu_cfg_time, &login_delay, 0, NULL,
...@@ -292,18 +345,35 @@ pop3d_get_client_address (int fd, struct sockaddr_in *pcs) ...@@ -292,18 +345,35 @@ pop3d_get_client_address (int fd, struct sockaddr_in *pcs)
292 ofd -- output descriptor 345 ofd -- output descriptor
293 tls -- initiate encrypted connection */ 346 tls -- initiate encrypted connection */
294 int 347 int
295 pop3d_mainloop (int ifd, int ofd, int tls) 348 pop3d_mainloop (int ifd, int ofd, enum tls_mode tls)
296 { 349 {
297 int status = OK; 350 int status = OK;
298 char buffer[512]; 351 char buffer[512];
299 static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE, 352 static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
300 SIGABRT, SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGALRM }; 353 SIGABRT, SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGALRM };
354 struct pop3d_session session;
301 355
302 mu_set_signals (pop3d_child_signal, sigtab, MU_ARRAY_SIZE (sigtab)); 356 mu_set_signals (pop3d_child_signal, sigtab, MU_ARRAY_SIZE (sigtab));
303 357
304 pop3d_setio (ifd, ofd, tls); 358 if (tls == tls_unspecified)
359 tls = tls_available ? tls_ondemand : tls_no;
360 else if (tls != tls_no && !tls_available)
361 {
362 mu_error (_("TLS is not configured, but requested in the "
363 "configuration"));
364 tls = tls_no;
365 }
366
367 pop3d_setio (ifd, ofd, tls == tls_connection);
368
369 if (tls == tls_required)
370 initial_state = INITIAL;
371
372 state = tls == tls_connection ? AUTHORIZATION : initial_state;
305 373
306 state = tls ? AUTHORIZATION : initial_state; 374 pop3d_session_init (&session);
375 session.tls = tls;
376 /* FIXME: state should also be in the session? */
307 377
308 /* Prepare the shared secret for APOP. */ 378 /* Prepare the shared secret for APOP. */
309 { 379 {
...@@ -353,7 +423,7 @@ pop3d_mainloop (int ifd, int ofd, int tls) ...@@ -353,7 +423,7 @@ pop3d_mainloop (int ifd, int ofd, int tls)
353 manlock_touchlock (mbox); 423 manlock_touchlock (mbox);
354 424
355 if ((handler = pop3d_find_command (cmd)) != NULL) 425 if ((handler = pop3d_find_command (cmd)) != NULL)
356 status = handler (arg); 426 status = handler (arg, &session);
357 else 427 else
358 status = ERR_BAD_CMD; 428 status = ERR_BAD_CMD;
359 429
...@@ -361,6 +431,8 @@ pop3d_mainloop (int ifd, int ofd, int tls) ...@@ -361,6 +431,8 @@ pop3d_mainloop (int ifd, int ofd, int tls)
361 pop3d_outf ("-ERR %s\n", pop3d_error_string (status)); 431 pop3d_outf ("-ERR %s\n", pop3d_error_string (status));
362 } 432 }
363 433
434 pop3d_session_free (&session);
435
364 pop3d_bye (); 436 pop3d_bye ();
365 437
366 return status; 438 return status;
...@@ -446,7 +518,8 @@ pop3d_connection (int fd, struct sockaddr *sa, int salen, ...@@ -446,7 +518,8 @@ pop3d_connection (int fd, struct sockaddr *sa, int salen,
446 else 518 else
447 rc = 1; 519 rc = 1;
448 520
449 pop3d_mainloop (fd, fd, cfg->tls); 521 pop3d_mainloop (fd, fd,
522 cfg->tls_mode == tls_unspecified ? tls_mode : cfg->tls_mode);
450 523
451 if (rc == 0) 524 if (rc == 0)
452 clr_strerr_flt (); 525 clr_strerr_flt ();
...@@ -517,9 +590,6 @@ main (int argc, char **argv) ...@@ -517,9 +590,6 @@ main (int argc, char **argv)
517 argc, argv, 0, NULL, server)) 590 argc, argv, 0, NULL, server))
518 exit (EX_CONFIG); /* FIXME: No way to discern from EX_USAGE? */ 591 exit (EX_CONFIG); /* FIXME: No way to discern from EX_USAGE? */
519 592
520 if (tls_required)
521 initial_state = INITIAL;
522
523 if (expire == 0) 593 if (expire == 0)
524 expire_on_exit = 1; 594 expire_on_exit = 1;
525 595
...@@ -589,7 +659,7 @@ main (int argc, char **argv) ...@@ -589,7 +659,7 @@ main (int argc, char **argv)
589 { 659 {
590 /* Make sure we are in the root directory. */ 660 /* Make sure we are in the root directory. */
591 chdir ("/"); 661 chdir ("/");
592 status = pop3d_mainloop (MU_STDIN_FD, MU_STDOUT_FD, 0); 662 status = pop3d_mainloop (MU_STDIN_FD, MU_STDOUT_FD, tls_no);
593 } 663 }
594 664
595 if (status) 665 if (status)
......
...@@ -42,17 +42,19 @@ ...@@ -42,17 +42,19 @@
42 # undef ENABLE_LOGIN_DELAY 42 # undef ENABLE_LOGIN_DELAY
43 #endif 43 #endif
44 44
45 struct pop3d_session;
46
45 #ifdef ENABLE_LOGIN_DELAY 47 #ifdef ENABLE_LOGIN_DELAY
46 # define LOGIN_STAT_FILE "/var/run/pop3-login" 48 # define LOGIN_STAT_FILE "/var/run/pop3-login"
47 extern time_t login_delay; 49 extern time_t login_delay;
48 extern char *login_stat_file; 50 extern char *login_stat_file;
49 extern int check_login_delay (char *username); 51 extern int check_login_delay (char *username);
50 extern void update_login_delay (char *username); 52 extern void update_login_delay (char *username);
51 extern void login_delay_capa (void); 53 extern void login_delay_capa (const char *, struct pop3d_session *);
52 #else 54 #else
53 # define check_login_delay(u) 0 55 # define check_login_delay(u) 0
54 # define update_login_delay(u) 56 # define update_login_delay(u)
55 # define login_delay_capa() 57 # define login_delay_capa NULL
56 #endif 58 #endif
57 59
58 /* Minimum advertise retention time for messages. */ 60 /* Minimum advertise retention time for messages. */
...@@ -166,8 +168,44 @@ extern int expire_on_exit; ...@@ -166,8 +168,44 @@ extern int expire_on_exit;
166 #define ERR_LOGIN_DELAY 22 168 #define ERR_LOGIN_DELAY 22
167 #define ERR_TERMINATE 23 169 #define ERR_TERMINATE 23
168 170
171 enum tls_mode
172 {
173 tls_unspecified,
174 tls_no,
175 tls_ondemand,
176 tls_required,
177 tls_connection
178 };
179
180 enum pop3d_capa_type
181 {
182 capa_string,
183 capa_func
184 };
185
186 struct pop3d_capa
187 {
188 enum pop3d_capa_type type;
189 const char *name;
190 union
191 {
192 char *string;
193 void (*func) (const char *, struct pop3d_session *);
194 } value;
195 };
196
197 struct pop3d_session
198 {
199 mu_list_t capa;
200 enum tls_mode tls;
201 };
202
203 void pop3d_session_init (struct pop3d_session *session);
204 void pop3d_session_free (struct pop3d_session *session);
205
206
169 typedef struct mu_pop_server *mu_pop_server_t; 207 typedef struct mu_pop_server *mu_pop_server_t;
170 typedef int (*pop3d_command_handler_t) (char *); 208 typedef int (*pop3d_command_handler_t) (char *, struct pop3d_session *sess);
171 209
172 struct pop3d_command 210 struct pop3d_command
173 { 211 {
...@@ -214,19 +252,19 @@ extern int apop_database_owner_set; ...@@ -214,19 +252,19 @@ extern int apop_database_owner_set;
214 252
215 extern pop3d_command_handler_t pop3d_find_command (const char *name); 253 extern pop3d_command_handler_t pop3d_find_command (const char *name);
216 254
217 extern int pop3d_stat (char *); 255 extern int pop3d_stat (char *, struct pop3d_session *);
218 extern int pop3d_top (char *); 256 extern int pop3d_top (char *, struct pop3d_session *);
219 extern int pop3d_uidl (char *); 257 extern int pop3d_uidl (char *, struct pop3d_session *);
220 extern int pop3d_user (char *); 258 extern int pop3d_user (char *, struct pop3d_session *);
221 extern int pop3d_apop (char *); 259 extern int pop3d_apop (char *, struct pop3d_session *);
222 extern int pop3d_auth (char *); 260 extern int pop3d_auth (char *, struct pop3d_session *);
223 extern int pop3d_capa (char *); 261 extern int pop3d_capa (char *, struct pop3d_session *);
224 extern int pop3d_dele (char *); 262 extern int pop3d_dele (char *, struct pop3d_session *);
225 extern int pop3d_list (char *); 263 extern int pop3d_list (char *, struct pop3d_session *);
226 extern int pop3d_noop (char *); 264 extern int pop3d_noop (char *, struct pop3d_session *);
227 extern int pop3d_quit (char *); 265 extern int pop3d_quit (char *, struct pop3d_session *);
228 extern int pop3d_retr (char *); 266 extern int pop3d_retr (char *, struct pop3d_session *);
229 extern int pop3d_rset (char *); 267 extern int pop3d_rset (char *, struct pop3d_session *);
230 268
231 void pop3d_send_payload (mu_stream_t stream, mu_stream_t linestr, 269 void pop3d_send_payload (mu_stream_t stream, mu_stream_t linestr,
232 size_t maxlines); 270 size_t maxlines);
...@@ -242,7 +280,7 @@ extern RETSIGTYPE pop3d_master_signal (int); ...@@ -242,7 +280,7 @@ extern RETSIGTYPE pop3d_master_signal (int);
242 extern RETSIGTYPE pop3d_child_signal (int); 280 extern RETSIGTYPE pop3d_child_signal (int);
243 281
244 #ifdef WITH_TLS 282 #ifdef WITH_TLS
245 extern int pop3d_stls (char *); 283 extern int pop3d_stls (char *, struct pop3d_session *);
246 extern void enable_stls (void); 284 extern void enable_stls (void);
247 #endif /* WITH_TLS */ 285 #endif /* WITH_TLS */
248 extern void pop3d_outf (const char *fmt, ...) MU_PRINTFLIKE(1,2); 286 extern void pop3d_outf (const char *fmt, ...) MU_PRINTFLIKE(1,2);
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
26 static void pop3d_fix_mark (); 26 static void pop3d_fix_mark ();
27 27
28 int 28 int
29 pop3d_quit (char *arg) 29 pop3d_quit (char *arg, struct pop3d_session *sess)
30 { 30 {
31 int err = OK; 31 int err = OK;
32 if (strlen (arg) != 0) 32 if (strlen (arg) != 0)
......
...@@ -64,7 +64,7 @@ pop3d_send_payload (mu_stream_t stream, mu_stream_t linestr, size_t maxlines) ...@@ -64,7 +64,7 @@ pop3d_send_payload (mu_stream_t stream, mu_stream_t linestr, size_t maxlines)
64 /* Prints out the specified message */ 64 /* Prints out the specified message */
65 65
66 int 66 int
67 pop3d_retr (char *arg) 67 pop3d_retr (char *arg, struct pop3d_session *sess)
68 { 68 {
69 size_t mesgno; 69 size_t mesgno;
70 mu_message_t msg = NULL; 70 mu_message_t msg = NULL;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 /* Resets the connection so that no messages are marked as deleted */ 20 /* Resets the connection so that no messages are marked as deleted */
21 21
22 int 22 int
23 pop3d_rset (char *arg) 23 pop3d_rset (char *arg, struct pop3d_session *sess)
24 { 24 {
25 size_t i; 25 size_t i;
26 size_t total = 0; 26 size_t total = 0;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 /* Prints the number of messages and the total size of all messages */ 20 /* Prints the number of messages and the total size of all messages */
21 21
22 int 22 int
23 pop3d_stat (char *arg) 23 pop3d_stat (char *arg, struct pop3d_session *sess)
24 { 24 {
25 size_t mesgno; 25 size_t mesgno;
26 size_t size = 0; 26 size_t size = 0;
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
21 #ifdef WITH_TLS 21 #ifdef WITH_TLS
22 22
23 int 23 int
24 pop3d_stls (char *arg) 24 pop3d_stls (char *arg, struct pop3d_session *session)
25 { 25 {
26 if (strlen (arg) != 0) 26 if (strlen (arg) != 0)
27 return ERR_BAD_ARGS; 27 return ERR_BAD_ARGS;
...@@ -29,6 +29,15 @@ pop3d_stls (char *arg) ...@@ -29,6 +29,15 @@ pop3d_stls (char *arg)
29 if (state != initial_state) 29 if (state != initial_state)
30 return ERR_WRONG_STATE; 30 return ERR_WRONG_STATE;
31 31
32 switch (session->tls)
33 {
34 case tls_ondemand:
35 case tls_required:
36 break;
37 default:
38 return ERR_WRONG_STATE;
39 }
40
32 if (tls_done) 41 if (tls_done)
33 return ERR_TLS_ACTIVE; 42 return ERR_TLS_ACTIVE;
34 43
...@@ -45,7 +54,7 @@ pop3d_stls (char *arg) ...@@ -45,7 +54,7 @@ pop3d_stls (char *arg)
45 } 54 }
46 55
47 state = AUTHORIZATION; /* Confirm we're in this state. Necessary for 56 state = AUTHORIZATION; /* Confirm we're in this state. Necessary for
48 --tls-required to work */ 57 "tls required" to work */
49 58
50 return OK; 59 return OK;
51 } 60 }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 /* Prints the header of a message plus a specified number of lines. */ 20 /* Prints the header of a message plus a specified number of lines. */
21 21
22 int 22 int
23 pop3d_top (char *arg) 23 pop3d_top (char *arg, struct pop3d_session *sess)
24 { 24 {
25 size_t mesgno; 25 size_t mesgno;
26 unsigned long lines; 26 unsigned long lines;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 #include "pop3d.h" 18 #include "pop3d.h"
19 19
20 int 20 int
21 pop3d_uidl (char *arg) 21 pop3d_uidl (char *arg, struct pop3d_session *sess)
22 { 22 {
23 size_t mesgno; 23 size_t mesgno;
24 char uidl[128]; 24 char uidl[128];
......
...@@ -72,7 +72,7 @@ pop3d_begin_session () ...@@ -72,7 +72,7 @@ pop3d_begin_session ()
72 } 72 }
73 73
74 int 74 int
75 pop3d_user (char *arg) 75 pop3d_user (char *arg, struct pop3d_session *sess)
76 { 76 {
77 char *buf, *pass, *cmd; 77 char *buf, *pass, *cmd;
78 char buffer[512]; 78 char buffer[512];
...@@ -129,7 +129,7 @@ pop3d_user (char *arg) ...@@ -129,7 +129,7 @@ pop3d_user (char *arg)
129 else if (mu_c_strcasecmp (cmd, "QUIT") == 0) 129 else if (mu_c_strcasecmp (cmd, "QUIT") == 0)
130 { 130 {
131 mu_diag_output (MU_DIAG_INFO, _("possible probe of account `%s'"), arg); 131 mu_diag_output (MU_DIAG_INFO, _("possible probe of account `%s'"), arg);
132 return pop3d_quit (pass); 132 return pop3d_quit (pass, sess);
133 } 133 }
134 else 134 else
135 { 135 {
......