Added TLS/SSL support (via GnuTLS)
Showing
10 changed files
with
498 additions
and
316 deletions
1 | ## Process this file with GNU Automake to create Makefile.in | 1 | ## Process this file with GNU Automake to create Makefile.in |
2 | 2 | ||
3 | ## Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. | 3 | ## Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. |
4 | ## | 4 | ## |
5 | ## GNU Mailtuils is free software; you can redistribute it and/or | 5 | ## GNU Mailutils is free software; you can redistribute it and/or |
6 | ## modify it under the terms of the GNU General Public License as | 6 | ## modify it under the terms of the GNU General Public License as |
7 | ## published by the Free Software Foundation; either version 2, or (at | 7 | ## published by the Free Software Foundation; either version 2, or (at |
8 | ## your option) any later version. | 8 | ## your option) any later version. |
9 | ## | 9 | ## |
10 | ## This program is distributed in the hope that it will be useful, but | 10 | ## GNU Mailutils is distributed in the hope that it will be useful, but |
11 | ## WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | ## WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | ## General Public License for more details. | 13 | ## General Public License for more details. |
14 | ## | 14 | ## |
15 | ## You should have received a copy of the GNU General Public License | 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 | 16 | ## along with GNU Mailutils; if not, write to the Free Software |
17 | ## Foundation, Inc. | 17 | ## Foundation, Inc. |
18 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | 19 | ||
... | @@ -26,8 +26,8 @@ imap4d_LDADD = @AUTHOBJS@ ../mailbox/libmailbox.la @AUTHLIBS@ ../lib/libmailuti | ... | @@ -26,8 +26,8 @@ imap4d_LDADD = @AUTHOBJS@ ../mailbox/libmailbox.la @AUTHLIBS@ ../lib/libmailuti |
26 | imap4d_SOURCES = append.c authenticate.c bye.c capability.c check.c close.c \ | 26 | imap4d_SOURCES = append.c authenticate.c bye.c capability.c check.c close.c \ |
27 | commands.c copy.c create.c delete.c examine.c expunge.c fetch.c imap4d.c \ | 27 | commands.c copy.c create.c delete.c examine.c expunge.c fetch.c imap4d.c \ |
28 | imap4d.h list.c logout.c login.c lsub.c namespace.c noop.c rename.c search.c \ | 28 | imap4d.h list.c logout.c login.c lsub.c namespace.c noop.c rename.c search.c \ |
29 | select.c signal.c status.c store.c subscribe.c sync.c uid.c unsubscribe.c \ | 29 | select.c signal.c starttls.c status.c store.c subscribe.c sync.c uid.c \ |
30 | util.c version.c | 30 | unsubscribe.c util.c version.c |
31 | 31 | ||
32 | ## This kludge is necessary to correctly establish imap4d -> AUTHOBJS | 32 | ## This kludge is necessary to correctly establish imap4d -> AUTHOBJS |
33 | ## dependency. Think about better approach --gray | 33 | ## dependency. Think about better approach --gray | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -13,9 +13,10 @@ | ... | @@ -13,9 +13,10 @@ |
13 | 13 | ||
14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License |
15 | along with GNU Mailutils; if not, write to the Free Software | 15 | along with GNU Mailutils; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
17 | 17 | ||
18 | /* GSSAPI authentication for imap (rfc 1731). | 18 | /* |
19 | GSSAPI authentication for imap (rfc 1731). | ||
19 | */ | 20 | */ |
20 | 21 | ||
21 | #include "imap4d.h" | 22 | #include "imap4d.h" |
... | @@ -46,11 +47,8 @@ display_status_1 (char *m, OM_uint32 code, int type) | ... | @@ -46,11 +47,8 @@ display_status_1 (char *m, OM_uint32 code, int type) |
46 | do | 47 | do |
47 | { | 48 | { |
48 | maj_stat = gss_display_status (&min_stat, code, | 49 | maj_stat = gss_display_status (&min_stat, code, |
49 | type, GSS_C_NULL_OID, | 50 | type, GSS_C_NULL_OID, &msg_ctx, &msg); |
50 | &msg_ctx, &msg); | 51 | syslog (LOG_ERR, _("GSS-API error %s: %s\n"), m, (char *) msg.value); |
51 | syslog (LOG_ERR, | ||
52 | _("GSS-API error %s: %s\n"), m, | ||
53 | (char *)msg.value); | ||
54 | gss_release_buffer (&min_stat, &msg); | 52 | gss_release_buffer (&min_stat, &msg); |
55 | } | 53 | } |
56 | while (msg_ctx); | 54 | while (msg_ctx); |
... | @@ -64,14 +62,14 @@ display_status (char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) | ... | @@ -64,14 +62,14 @@ display_status (char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) |
64 | } | 62 | } |
65 | 63 | ||
66 | static int | 64 | static int |
67 | imap4d_gss_userok(gss_buffer_t client_name, char *name) | 65 | imap4d_gss_userok (gss_buffer_t client_name, char *name) |
68 | { | 66 | { |
69 | int rc = -1; | 67 | int rc = -1; |
70 | krb5_principal p; | 68 | krb5_principal p; |
71 | krb5_context kcontext; | 69 | krb5_context kcontext; |
72 | 70 | ||
73 | krb5_init_context (&kcontext); | 71 | krb5_init_context (&kcontext); |
74 | 72 | ||
75 | if (krb5_parse_name (kcontext, client_name->value, &p) != 0) | 73 | if (krb5_parse_name (kcontext, client_name->value, &p) != 0) |
76 | return -1; | 74 | return -1; |
77 | if (krb5_kuserok (kcontext, p, name)) | 75 | if (krb5_kuserok (kcontext, p, name)) |
... | @@ -99,57 +97,54 @@ auth_gssapi (struct imap4d_command *command, char **username) | ... | @@ -99,57 +97,54 @@ auth_gssapi (struct imap4d_command *command, char **username) |
99 | gss_qop_t quality; | 97 | gss_qop_t quality; |
100 | gss_name_t client; | 98 | gss_name_t client; |
101 | gss_buffer_desc client_name; | 99 | gss_buffer_desc client_name; |
102 | 100 | ||
103 | /* Obtain server credentials. RFC 1732 states, that | 101 | /* Obtain server credentials. RFC 1732 states, that |
104 | "The server must issue a ready response with no data and pass the | 102 | "The server must issue a ready response with no data and pass the |
105 | resulting client supplied token to GSS_Accept_sec_context as | 103 | resulting client supplied token to GSS_Accept_sec_context as |
106 | input_token, setting acceptor_cred_handle to NULL (for "use default | 104 | input_token, setting acceptor_cred_handle to NULL (for "use default |
107 | credentials"), and 0 for input_context_handle (initially)." | 105 | credentials"), and 0 for input_context_handle (initially)." |
108 | In MIT implementation, passing NULL as acceptor_cred_handle won't | 106 | In MIT implementation, passing NULL as acceptor_cred_handle won't |
109 | work (possibly due to a bug in krb5_gss_accept_sec_context()), so | 107 | work (possibly due to a bug in krb5_gss_accept_sec_context()), so |
110 | we acquire server credentials explicitly. */ | 108 | we acquire server credentials explicitly. */ |
111 | 109 | ||
112 | asprintf ((char**)&tmp, "imap@%s", util_localname ()); | 110 | asprintf ((char **) &tmp, "imap@%s", util_localname ()); |
113 | tokbuf.value = tmp; | 111 | tokbuf.value = tmp; |
114 | tokbuf.length = strlen (tokbuf.value) + 1; | 112 | tokbuf.length = strlen (tokbuf.value) + 1; |
115 | maj_stat = gss_import_name (&min_stat, &tokbuf, | 113 | maj_stat = gss_import_name (&min_stat, &tokbuf, |
116 | gss_nt_service_name, | 114 | gss_nt_service_name, &server_name); |
117 | &server_name); | ||
118 | if (maj_stat != GSS_S_COMPLETE) | 115 | if (maj_stat != GSS_S_COMPLETE) |
119 | { | 116 | { |
120 | display_status ("import name", maj_stat, min_stat); | 117 | display_status ("import name", maj_stat, min_stat); |
121 | util_finish (command, RESP_NO, | 118 | util_finish (command, RESP_NO, "GSSAPI authentication not available"); |
122 | "GSSAPI authentication not available"); | ||
123 | return 1; | 119 | return 1; |
124 | } | 120 | } |
125 | 121 | ||
126 | maj_stat = gss_acquire_cred (&min_stat, server_name, 0, | 122 | maj_stat = gss_acquire_cred (&min_stat, server_name, 0, |
127 | GSS_C_NULL_OID_SET, GSS_C_ACCEPT, | 123 | GSS_C_NULL_OID_SET, GSS_C_ACCEPT, |
128 | &server_creds, NULL, NULL); | 124 | &server_creds, NULL, NULL); |
129 | gss_release_name(&min_stat2, &server_name); | 125 | gss_release_name (&min_stat2, &server_name); |
130 | 126 | ||
131 | if (maj_stat != GSS_S_COMPLETE) | 127 | if (maj_stat != GSS_S_COMPLETE) |
132 | { | 128 | { |
133 | display_status ("acquire credentials", maj_stat, min_stat); | 129 | display_status ("acquire credentials", maj_stat, min_stat); |
134 | util_finish (command, RESP_NO, | 130 | util_finish (command, RESP_NO, "GSSAPI authentication not available"); |
135 | "GSSAPI authentication not available"); | ||
136 | return 1; | 131 | return 1; |
137 | } | 132 | } |
138 | 133 | ||
139 | /* Start the dialogue */ | 134 | /* Start the dialogue */ |
140 | 135 | ||
141 | util_send ("+ GO AHEAD\r\n"); | 136 | util_send ("+ GO AHEAD\r\n"); |
142 | 137 | ||
143 | context = GSS_C_NO_CONTEXT; | 138 | context = GSS_C_NO_CONTEXT; |
144 | 139 | ||
145 | for (;;) | 140 | for (;;) |
146 | { | 141 | { |
147 | token_str = imap4d_readline_ex (ifile); | 142 | token_str = imap4d_readline_ex (); |
148 | util_base64_decode (token_str, strlen (token_str), &tmp, &size); | 143 | util_base64_decode (token_str, strlen (token_str), &tmp, &size); |
149 | tokbuf.value = tmp; | 144 | tokbuf.value = tmp; |
150 | tokbuf.length = size; | 145 | tokbuf.length = size; |
151 | free (token_str); | 146 | free (token_str); |
152 | 147 | ||
153 | maj_stat = gss_accept_sec_context (&min_stat, | 148 | maj_stat = gss_accept_sec_context (&min_stat, |
154 | &context, | 149 | &context, |
155 | server_creds, | 150 | server_creds, |
... | @@ -158,9 +153,7 @@ auth_gssapi (struct imap4d_command *command, char **username) | ... | @@ -158,9 +153,7 @@ auth_gssapi (struct imap4d_command *command, char **username) |
158 | &client, | 153 | &client, |
159 | &mech_type, | 154 | &mech_type, |
160 | &outbuf, | 155 | &outbuf, |
161 | &cflags, | 156 | &cflags, NULL, &cred_handle); |
162 | NULL, | ||
163 | &cred_handle); | ||
164 | free (tmp); | 157 | free (tmp); |
165 | if (maj_stat == GSS_S_CONTINUE_NEEDED) | 158 | if (maj_stat == GSS_S_CONTINUE_NEEDED) |
166 | { | 159 | { |
... | @@ -176,12 +169,11 @@ auth_gssapi (struct imap4d_command *command, char **username) | ... | @@ -176,12 +169,11 @@ auth_gssapi (struct imap4d_command *command, char **username) |
176 | else if (maj_stat == GSS_S_COMPLETE) | 169 | else if (maj_stat == GSS_S_COMPLETE) |
177 | break; | 170 | break; |
178 | /* Bail out otherwise */ | 171 | /* Bail out otherwise */ |
179 | 172 | ||
180 | display_status ("accept context", maj_stat, min_stat); | 173 | display_status ("accept context", maj_stat, min_stat); |
181 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); | 174 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); |
182 | gss_release_buffer (&min_stat, &outbuf); | 175 | gss_release_buffer (&min_stat, &outbuf); |
183 | util_finish (command, RESP_NO, | 176 | util_finish (command, RESP_NO, "GSSAPI authentication failed"); |
184 | "GSSAPI authentication failed"); | ||
185 | return 1; | 177 | return 1; |
186 | } | 178 | } |
187 | 179 | ||
... | @@ -191,7 +183,7 @@ auth_gssapi (struct imap4d_command *command, char **username) | ... | @@ -191,7 +183,7 @@ auth_gssapi (struct imap4d_command *command, char **username) |
191 | util_send ("+ %*.*s\r\n", size, size, tmp); | 183 | util_send ("+ %*.*s\r\n", size, size, tmp); |
192 | free (tmp); | 184 | free (tmp); |
193 | gss_release_buffer (&min_stat, &outbuf); | 185 | gss_release_buffer (&min_stat, &outbuf); |
194 | token_str = imap4d_readline_ex (ifile); | 186 | token_str = imap4d_readline_ex (); |
195 | free (token_str); | 187 | free (token_str); |
196 | } | 188 | } |
197 | 189 | ||
... | @@ -205,15 +197,15 @@ auth_gssapi (struct imap4d_command *command, char **username) | ... | @@ -205,15 +197,15 @@ auth_gssapi (struct imap4d_command *command, char **username) |
205 | util_send ("+ %*.*s\r\n", size, size, tmp); | 197 | util_send ("+ %*.*s\r\n", size, size, tmp); |
206 | free (tmp); | 198 | free (tmp); |
207 | 199 | ||
208 | token_str = imap4d_readline_ex (ifile); | 200 | token_str = imap4d_readline_ex (); |
209 | util_base64_decode (token_str, strlen (token_str), | 201 | util_base64_decode (token_str, strlen (token_str), |
210 | (unsigned char **)&tokbuf.value, &tokbuf.length); | 202 | (unsigned char **) &tokbuf.value, &tokbuf.length); |
211 | free (token_str); | 203 | free (token_str); |
212 | 204 | ||
213 | gss_unwrap (&min_stat, context, &tokbuf, &outbuf, &cflags, &quality); | 205 | gss_unwrap (&min_stat, context, &tokbuf, &outbuf, &cflags, &quality); |
214 | free (tokbuf.value); | 206 | free (tokbuf.value); |
215 | 207 | ||
216 | sec_level = ntohl (*(OM_uint32*)outbuf.value); | 208 | sec_level = ntohl (*(OM_uint32 *) outbuf.value); |
217 | 209 | ||
218 | /* FIXME: parse sec_level and act accordingly to its settings */ | 210 | /* FIXME: parse sec_level and act accordingly to its settings */ |
219 | mech = sec_level >> 24; | 211 | mech = sec_level >> 24; |
... | @@ -226,25 +218,23 @@ auth_gssapi (struct imap4d_command *command, char **username) | ... | @@ -226,25 +218,23 @@ auth_gssapi (struct imap4d_command *command, char **username) |
226 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); | 218 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); |
227 | gss_release_buffer (&min_stat, &outbuf); | 219 | gss_release_buffer (&min_stat, &outbuf); |
228 | util_finish (command, RESP_NO, | 220 | util_finish (command, RESP_NO, |
229 | "GSSAPI authentication failed: unsupported protection mechanism"); | 221 | "GSSAPI authentication failed: unsupported protection mechanism"); |
230 | return 1; | 222 | return 1; |
231 | } | 223 | } |
232 | protection_mech = mech; | 224 | protection_mech = mech; |
233 | client_buffer_size = sec_level & 0x00ffffffff; | 225 | client_buffer_size = sec_level & 0x00ffffffff; |
234 | 226 | ||
235 | *username = strdup ((char*)outbuf.value + 4); | 227 | *username = strdup ((char *) outbuf.value + 4); |
236 | gss_release_buffer (&min_stat, &outbuf); | 228 | gss_release_buffer (&min_stat, &outbuf); |
237 | 229 | ||
238 | maj_stat = gss_display_name(&min_stat, client, | 230 | maj_stat = gss_display_name (&min_stat, client, &client_name, &mech_type); |
239 | &client_name, &mech_type); | ||
240 | if (maj_stat != GSS_S_COMPLETE) | 231 | if (maj_stat != GSS_S_COMPLETE) |
241 | { | 232 | { |
242 | display_status ("get client name", maj_stat, min_stat); | 233 | display_status ("get client name", maj_stat, min_stat); |
243 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); | 234 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); |
244 | gss_release_buffer (&min_stat, &outbuf); | 235 | gss_release_buffer (&min_stat, &outbuf); |
245 | free (*username); | 236 | free (*username); |
246 | util_finish (command, RESP_NO, | 237 | util_finish (command, RESP_NO, "GSSAPI authentication failed"); |
247 | "GSSAPI authentication failed"); | ||
248 | return 1; | 238 | return 1; |
249 | } | 239 | } |
250 | 240 | ||
... | @@ -270,8 +260,6 @@ auth_gssapi (struct imap4d_command *command, char **username) | ... | @@ -270,8 +260,6 @@ auth_gssapi (struct imap4d_command *command, char **username) |
270 | gss_release_buffer (&min_stat, &client_name); | 260 | gss_release_buffer (&min_stat, &client_name); |
271 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); | 261 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); |
272 | gss_release_buffer (&min_stat, &outbuf); | 262 | gss_release_buffer (&min_stat, &outbuf); |
273 | util_finish (command, RESP_OK, | 263 | util_finish (command, RESP_OK, "GSSAPI authentication successful"); |
274 | "GSSAPI authentication successful"); | ||
275 | return 0; | 264 | return 0; |
276 | } | 265 | } |
277 | ... | ... |
... | @@ -44,7 +44,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command) | ... | @@ -44,7 +44,7 @@ imap4d_bye0 (int reason, struct imap4d_command *command) |
44 | break; | 44 | break; |
45 | 45 | ||
46 | case ERR_SIGNAL: | 46 | case ERR_SIGNAL: |
47 | if (ofile) | 47 | if (util_is_ofile()) |
48 | util_out (RESP_BYE, "Quitting on signal"); | 48 | util_out (RESP_BYE, "Quitting on signal"); |
49 | syslog (LOG_ERR, _("Quitting on signal")); | 49 | syslog (LOG_ERR, _("Quitting on signal")); |
50 | break; | 50 | break; |
... | @@ -78,6 +78,14 @@ imap4d_bye0 (int reason, struct imap4d_command *command) | ... | @@ -78,6 +78,14 @@ imap4d_bye0 (int reason, struct imap4d_command *command) |
78 | 78 | ||
79 | if (status == EXIT_SUCCESS && command) | 79 | if (status == EXIT_SUCCESS && command) |
80 | util_finish (command, RESP_OK, "Completed"); | 80 | util_finish (command, RESP_OK, "Completed"); |
81 | |||
82 | #ifdef WITH_TLS | ||
83 | if (tls_done) | ||
84 | imap4d_deinit_tls_server (); | ||
85 | if (tls_available) | ||
86 | mu_deinit_tls_libs (); | ||
87 | #endif /* WITH_TLS */ | ||
88 | |||
81 | closelog (); | 89 | closelog (); |
82 | exit (status); | 90 | exit (status); |
83 | } | 91 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2003 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | 13 | ||
14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License |
15 | along with GNU Mailutils; if not, write to the Free Software | 15 | along with GNU Mailutils; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
17 | 17 | ||
18 | #include "imap4d.h" | 18 | #include "imap4d.h" |
19 | 19 | ||
... | @@ -28,13 +28,20 @@ int | ... | @@ -28,13 +28,20 @@ int |
28 | imap4d_capability (struct imap4d_command *command, char *arg) | 28 | imap4d_capability (struct imap4d_command *command, char *arg) |
29 | { | 29 | { |
30 | int i; | 30 | int i; |
31 | 31 | ||
32 | (void)arg; | 32 | (void) arg; |
33 | util_send ("* CAPABILITY"); | 33 | util_send ("* CAPABILITY"); |
34 | |||
34 | for (i = 0; capa[i]; i++) | 35 | for (i = 0; capa[i]; i++) |
35 | util_send(" %s", capa[i]); | 36 | util_send (" %s", capa[i]); |
37 | |||
38 | #ifdef WITH_TLS | ||
39 | if (tls_available) | ||
40 | util_send (" STARTTLS"); | ||
41 | #endif /* WITH_TLS */ | ||
42 | |||
36 | imap4d_auth_capability (); | 43 | imap4d_auth_capability (); |
37 | util_send("\r\n"); | 44 | util_send ("\r\n"); |
38 | 45 | ||
39 | return util_finish (command, RESP_OK, "Completed"); | 46 | return util_finish (command, RESP_OK, "Completed"); |
40 | } | 47 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2003 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | 13 | ||
14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License |
15 | along with GNU Mailutils; if not, write to the Free Software | 15 | along with GNU Mailutils; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
17 | 17 | ||
18 | #include "imap4d.h" | 18 | #include "imap4d.h" |
19 | 19 | ||
... | @@ -45,5 +45,8 @@ struct imap4d_command imap4d_command_table [] = | ... | @@ -45,5 +45,8 @@ struct imap4d_command imap4d_command_table [] = |
45 | { "UID", imap4d_uid, STATE_SEL, STATE_NONE, STATE_NONE, NULL }, | 45 | { "UID", imap4d_uid, STATE_SEL, STATE_NONE, STATE_NONE, NULL }, |
46 | { "NAMESPACE", imap4d_namespace, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL }, | 46 | { "NAMESPACE", imap4d_namespace, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL }, |
47 | { "X-VERSION", imap4d_version, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL }, | 47 | { "X-VERSION", imap4d_version, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE, NULL }, |
48 | #ifdef WITH_TLS | ||
49 | { "STARTTLS", imap4d_starttls, STATE_NONAUTH, STATE_NONE, STATE_NONE, NULL }, | ||
50 | #endif /* WITH_TLS */ | ||
48 | { NULL, 0, 0, 0, 0, NULL } | 51 | { NULL, 0, 0, 0, 0, NULL } |
49 | }; | 52 | }; | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -13,47 +13,50 @@ | ... | @@ -13,47 +13,50 @@ |
13 | 13 | ||
14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License |
15 | along with GNU Mailutils; if not, write to the Free Software | 15 | along with GNU Mailutils; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
17 | 17 | ||
18 | #include "imap4d.h" | 18 | #include "imap4d.h" |
19 | 19 | ||
20 | FILE *ifile; | ||
21 | FILE *ofile; | ||
22 | mailbox_t mbox; | 20 | mailbox_t mbox; |
23 | char *homedir; | 21 | char *homedir; |
24 | int state = STATE_NONAUTH; | 22 | int state = STATE_NONAUTH; |
25 | int debug_mode = 0; | 23 | int debug_mode = 0; |
26 | struct mu_auth_data *auth_data; | 24 | struct mu_auth_data *auth_data; |
27 | 25 | ||
28 | struct daemon_param daemon_param = { | 26 | struct daemon_param daemon_param = { |
29 | MODE_INTERACTIVE, /* Start in interactive (inetd) mode */ | 27 | MODE_INTERACTIVE, /* Start in interactive (inetd) mode */ |
30 | 20, /* Default maximum number of children */ | 28 | 20, /* Default maximum number of children */ |
31 | 143, /* Standard IMAP4 port */ | 29 | 143, /* Standard IMAP4 port */ |
32 | 1800, /* RFC2060: 30 minutes. */ | 30 | 1800, /* RFC2060: 30 minutes. */ |
33 | 0 /* No transcript by default */ | 31 | 0 /* No transcript by default */ |
34 | }; | 32 | }; |
35 | 33 | ||
34 | #ifdef WITH_TLS | ||
35 | int tls_available; | ||
36 | int tls_done; | ||
37 | #endif /* WITH_TLS */ | ||
38 | |||
36 | /* Number of child processes. */ | 39 | /* Number of child processes. */ |
37 | volatile size_t children; | 40 | volatile size_t children; |
38 | 41 | ||
39 | const char *argp_program_version = "imap4d (" PACKAGE_STRING ")"; | 42 | const char *argp_program_version = "imap4d (" PACKAGE_STRING ")"; |
40 | static char doc[] = N_("GNU imap4d -- the IMAP4D daemon"); | 43 | static char doc[] = N_("GNU imap4d -- the IMAP4D daemon"); |
41 | 44 | ||
42 | static struct argp_option options[] = | 45 | static struct argp_option options[] = { |
43 | { | ||
44 | {"other-namespace", 'O', N_("PATHLIST"), 0, | 46 | {"other-namespace", 'O', N_("PATHLIST"), 0, |
45 | N_("set the `other' namespace"), 0}, | 47 | N_("set the `other' namespace"), 0}, |
46 | {"shared-namespace", 'S', N_("PATHLIST"), 0, | 48 | {"shared-namespace", 'S', N_("PATHLIST"), 0, |
47 | N_("set the `shared' namespace"), 0}, | 49 | N_("set the `shared' namespace"), 0}, |
48 | { NULL, 0, NULL, 0, NULL, 0 } | 50 | {NULL, 0, NULL, 0, NULL, 0} |
49 | }; | 51 | }; |
50 | 52 | ||
51 | static error_t imap4d_parse_opt (int key, char *arg, struct argp_state *state); | 53 | static error_t imap4d_parse_opt (int key, char *arg, |
54 | struct argp_state *state); | ||
52 | 55 | ||
53 | static struct argp argp = { | 56 | static struct argp argp = { |
54 | options, | 57 | options, |
55 | imap4d_parse_opt, | 58 | imap4d_parse_opt, |
56 | NULL, | 59 | NULL, |
57 | doc, | 60 | doc, |
58 | NULL, | 61 | NULL, |
59 | NULL, NULL | 62 | NULL, NULL |
... | @@ -62,6 +65,9 @@ static struct argp argp = { | ... | @@ -62,6 +65,9 @@ static struct argp argp = { |
62 | static const char *imap4d_capa[] = { | 65 | static const char *imap4d_capa[] = { |
63 | "daemon", | 66 | "daemon", |
64 | "auth", | 67 | "auth", |
68 | #ifdef WITH_TLS | ||
69 | "tls", | ||
70 | #endif /* WITH_TLS */ | ||
65 | "common", | 71 | "common", |
66 | "mailbox", | 72 | "mailbox", |
67 | "logging", | 73 | "logging", |
... | @@ -69,10 +75,10 @@ static const char *imap4d_capa[] = { | ... | @@ -69,10 +75,10 @@ static const char *imap4d_capa[] = { |
69 | NULL | 75 | NULL |
70 | }; | 76 | }; |
71 | 77 | ||
72 | static int imap4d_mainloop __P ((int, int)); | 78 | static int imap4d_mainloop __P ((int, int)); |
73 | static void imap4d_daemon_init __P ((void)); | 79 | static void imap4d_daemon_init __P ((void)); |
74 | static void imap4d_daemon __P ((unsigned int, unsigned int)); | 80 | static void imap4d_daemon __P ((unsigned int, unsigned int)); |
75 | static int imap4d_mainloop __P ((int, int)); | 81 | static int imap4d_mainloop __P ((int, int)); |
76 | 82 | ||
77 | static error_t | 83 | static error_t |
78 | imap4d_parse_opt (int key, char *arg, struct argp_state *state) | 84 | imap4d_parse_opt (int key, char *arg, struct argp_state *state) |
... | @@ -82,15 +88,15 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -82,15 +88,15 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) |
82 | case ARGP_KEY_INIT: | 88 | case ARGP_KEY_INIT: |
83 | state->child_inputs[0] = state->input; | 89 | state->child_inputs[0] = state->input; |
84 | break; | 90 | break; |
85 | 91 | ||
86 | case 'O': | 92 | case 'O': |
87 | set_namespace (NS_OTHER, arg); | 93 | set_namespace (NS_OTHER, arg); |
88 | break; | 94 | break; |
89 | 95 | ||
90 | case 'S': | 96 | case 'S': |
91 | set_namespace (NS_SHARED, arg); | 97 | set_namespace (NS_SHARED, arg); |
92 | break; | 98 | break; |
93 | 99 | ||
94 | default: | 100 | default: |
95 | return ARGP_ERR_UNKNOWN; | 101 | return ARGP_ERR_UNKNOWN; |
96 | } | 102 | } |
... | @@ -106,9 +112,12 @@ main (int argc, char **argv) | ... | @@ -106,9 +112,12 @@ main (int argc, char **argv) |
106 | /* Native Language Support */ | 112 | /* Native Language Support */ |
107 | mu_init_nls (); | 113 | mu_init_nls (); |
108 | 114 | ||
109 | state = STATE_NONAUTH; /* Starting state in non-auth. */ | 115 | state = STATE_NONAUTH; /* Starting state in non-auth. */ |
110 | 116 | ||
111 | MU_AUTH_REGISTER_ALL_MODULES(); | 117 | MU_AUTH_REGISTER_ALL_MODULES (); |
118 | #ifdef WITH_TLS | ||
119 | mu_tls_init_argp (); | ||
120 | #endif /* WITH_TLS */ | ||
112 | mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param); | 121 | mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param); |
113 | 122 | ||
114 | #ifdef USE_LIBPAM | 123 | #ifdef USE_LIBPAM |
... | @@ -131,7 +140,7 @@ main (int argc, char **argv) | ... | @@ -131,7 +140,7 @@ main (int argc, char **argv) |
131 | perror (_("Error getting mail group")); | 140 | perror (_("Error getting mail group")); |
132 | exit (1); | 141 | exit (1); |
133 | } | 142 | } |
134 | 143 | ||
135 | if (setgid (gr->gr_gid) == -1) | 144 | if (setgid (gr->gr_gid) == -1) |
136 | { | 145 | { |
137 | perror (_("Error setting mail group")); | 146 | perror (_("Error setting mail group")); |
... | @@ -143,7 +152,7 @@ main (int argc, char **argv) | ... | @@ -143,7 +152,7 @@ main (int argc, char **argv) |
143 | { | 152 | { |
144 | list_t bookie; | 153 | list_t bookie; |
145 | registrar_get_list (&bookie); | 154 | registrar_get_list (&bookie); |
146 | list_append (bookie, mbox_record); | 155 | list_append (bookie, mbox_record); |
147 | list_append (bookie, path_record); | 156 | list_append (bookie, path_record); |
148 | } | 157 | } |
149 | 158 | ||
... | @@ -174,8 +183,15 @@ main (int argc, char **argv) | ... | @@ -174,8 +183,15 @@ main (int argc, char **argv) |
174 | /* Redirect any stdout error from the library to syslog, they | 183 | /* Redirect any stdout error from the library to syslog, they |
175 | should not go to the client. */ | 184 | should not go to the client. */ |
176 | mu_error_set_print (mu_syslog_error_printer); | 185 | mu_error_set_print (mu_syslog_error_printer); |
177 | 186 | ||
178 | umask (S_IROTH | S_IWOTH | S_IXOTH); /* 007 */ | 187 | umask (S_IROTH | S_IWOTH | S_IXOTH); /* 007 */ |
188 | |||
189 | /* Check TLS environment, i.e. cert and key files */ | ||
190 | #ifdef WITH_TLS | ||
191 | tls_available = mu_check_tls_environment (); | ||
192 | if (tls_available) | ||
193 | tls_available = mu_init_tls_libs (); | ||
194 | #endif /* WITH_TLS */ | ||
179 | 195 | ||
180 | /* Actually run the daemon. */ | 196 | /* Actually run the daemon. */ |
181 | if (daemon_param.mode == MODE_DAEMON) | 197 | if (daemon_param.mode == MODE_DAEMON) |
... | @@ -194,18 +210,13 @@ static int | ... | @@ -194,18 +210,13 @@ static int |
194 | imap4d_mainloop (int infile, int outfile) | 210 | imap4d_mainloop (int infile, int outfile) |
195 | { | 211 | { |
196 | char *text; | 212 | char *text; |
197 | 213 | ||
198 | /* Reset hup to exit. */ | 214 | /* Reset hup to exit. */ |
199 | signal (SIGHUP, imap4d_signal); | 215 | signal (SIGHUP, imap4d_signal); |
200 | /* Timeout alarm. */ | 216 | /* Timeout alarm. */ |
201 | signal (SIGALRM, imap4d_signal); | 217 | signal (SIGALRM, imap4d_signal); |
202 | 218 | ||
203 | ifile = fdopen (infile, "r"); | 219 | util_setio (infile, outfile); |
204 | ofile = fdopen (outfile, "w"); | ||
205 | if (!ofile || !ifile) | ||
206 | imap4d_bye (ERR_NO_OFILE); | ||
207 | |||
208 | setvbuf(ofile, NULL, _IOLBF, 0); | ||
209 | 220 | ||
210 | /* log information on the connecting client */ | 221 | /* log information on the connecting client */ |
211 | if (!debug_mode) | 222 | if (!debug_mode) |
... | @@ -214,11 +225,11 @@ imap4d_mainloop (int infile, int outfile) | ... | @@ -214,11 +225,11 @@ imap4d_mainloop (int infile, int outfile) |
214 | int len = sizeof cs; | 225 | int len = sizeof cs; |
215 | 226 | ||
216 | syslog (LOG_INFO, _("Incoming connection opened")); | 227 | syslog (LOG_INFO, _("Incoming connection opened")); |
217 | if (getpeername (infile, (struct sockaddr*)&cs, &len) < 0) | 228 | if (getpeername (infile, (struct sockaddr *) &cs, &len) < 0) |
218 | syslog (LOG_ERR, _("can't obtain IP address of client: %s"), | 229 | syslog (LOG_ERR, _("can't obtain IP address of client: %s"), |
219 | strerror (errno)); | 230 | strerror (errno)); |
220 | else | 231 | else |
221 | syslog (LOG_INFO, _("connect from %s"), inet_ntoa(cs.sin_addr)); | 232 | syslog (LOG_INFO, _("connect from %s"), inet_ntoa (cs.sin_addr)); |
222 | text = "IMAP4rev1"; | 233 | text = "IMAP4rev1"; |
223 | } | 234 | } |
224 | else | 235 | else |
... | @@ -226,23 +237,22 @@ imap4d_mainloop (int infile, int outfile) | ... | @@ -226,23 +237,22 @@ imap4d_mainloop (int infile, int outfile) |
226 | syslog (LOG_INFO, _("Started in debugging mode")); | 237 | syslog (LOG_INFO, _("Started in debugging mode")); |
227 | text = "IMAP4rev1 Debugging mode"; | 238 | text = "IMAP4rev1 Debugging mode"; |
228 | } | 239 | } |
229 | 240 | ||
230 | /* Greetings. */ | 241 | /* Greetings. */ |
231 | util_out (RESP_OK, text); | 242 | util_out (RESP_OK, text); |
232 | fflush (ofile); | 243 | util_flush_output (); |
233 | 244 | ||
234 | while (1) | 245 | while (1) |
235 | { | 246 | { |
236 | char *cmd = imap4d_readline (ifile); | 247 | char *cmd = imap4d_readline (); |
237 | /* check for updates */ | 248 | /* check for updates */ |
238 | imap4d_sync (); | 249 | imap4d_sync (); |
239 | util_do_command (cmd); | 250 | util_do_command (cmd); |
240 | imap4d_sync (); | 251 | imap4d_sync (); |
241 | free (cmd); | 252 | free (cmd); |
242 | fflush (ofile); | 253 | util_flush_output (); |
243 | } | 254 | } |
244 | 255 | ||
245 | closelog (); | ||
246 | return EXIT_SUCCESS; | 256 | return EXIT_SUCCESS; |
247 | } | 257 | } |
248 | 258 | ||
... | @@ -256,7 +266,7 @@ imap4d_daemon_init (void) | ... | @@ -256,7 +266,7 @@ imap4d_daemon_init (void) |
256 | first three one, in, out, err */ | 266 | first three one, in, out, err */ |
257 | if (daemon (0, 0) < 0) | 267 | if (daemon (0, 0) < 0) |
258 | { | 268 | { |
259 | perror(_("fork failed:")); | 269 | perror (_("fork failed:")); |
260 | exit (1); | 270 | exit (1); |
261 | } | 271 | } |
262 | 272 | ||
... | @@ -289,18 +299,18 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port) | ... | @@ -289,18 +299,18 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port) |
289 | listenfd = socket (AF_INET, SOCK_STREAM, 0); | 299 | listenfd = socket (AF_INET, SOCK_STREAM, 0); |
290 | if (listenfd == -1) | 300 | if (listenfd == -1) |
291 | { | 301 | { |
292 | syslog (LOG_ERR, "socket: %s", strerror(errno)); | 302 | syslog (LOG_ERR, "socket: %s", strerror (errno)); |
293 | exit (1); | 303 | exit (1); |
294 | } | 304 | } |
295 | size = 1; /* Use size here to avoid making a new variable. */ | 305 | size = 1; /* Use size here to avoid making a new variable. */ |
296 | setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof(size)); | 306 | setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof (size)); |
297 | size = sizeof (server); | 307 | size = sizeof (server); |
298 | memset (&server, 0, size); | 308 | memset (&server, 0, size); |
299 | server.sin_family = AF_INET; | 309 | server.sin_family = AF_INET; |
300 | server.sin_addr.s_addr = htonl (INADDR_ANY); | 310 | server.sin_addr.s_addr = htonl (INADDR_ANY); |
301 | server.sin_port = htons (port); | 311 | server.sin_port = htons (port); |
302 | 312 | ||
303 | if (bind (listenfd, (struct sockaddr *)&server, size) == -1) | 313 | if (bind (listenfd, (struct sockaddr *) &server, size) == -1) |
304 | { | 314 | { |
305 | syslog (LOG_ERR, "bind: %s", strerror (errno)); | 315 | syslog (LOG_ERR, "bind: %s", strerror (errno)); |
306 | exit (1); | 316 | exit (1); |
... | @@ -315,38 +325,37 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port) | ... | @@ -315,38 +325,37 @@ imap4d_daemon (unsigned int maxchildren, unsigned int port) |
315 | for (;;) | 325 | for (;;) |
316 | { | 326 | { |
317 | if (children > maxchildren) | 327 | if (children > maxchildren) |
318 | { | 328 | { |
319 | syslog (LOG_ERR, _("too many children (%lu)"), | 329 | syslog (LOG_ERR, _("too many children (%lu)"), |
320 | (unsigned long) children); | 330 | (unsigned long) children); |
321 | pause (); | 331 | pause (); |
322 | continue; | 332 | continue; |
323 | } | 333 | } |
324 | connfd = accept (listenfd, (struct sockaddr *)&client, | 334 | connfd = accept (listenfd, (struct sockaddr *) &client, |
325 | (socklen_t*) &size); | 335 | (socklen_t *) & size); |
326 | if (connfd == -1) | 336 | if (connfd == -1) |
327 | { | 337 | { |
328 | if (errno == EINTR) | 338 | if (errno == EINTR) |
329 | continue; | 339 | continue; |
330 | syslog (LOG_ERR, "accept: %s", strerror (errno)); | 340 | syslog (LOG_ERR, "accept: %s", strerror (errno)); |
331 | exit (1); | 341 | exit (1); |
332 | } | 342 | } |
333 | 343 | ||
334 | pid = fork (); | 344 | pid = fork (); |
335 | if (pid == -1) | 345 | if (pid == -1) |
336 | syslog(LOG_ERR, "fork: %s", strerror (errno)); | 346 | syslog (LOG_ERR, "fork: %s", strerror (errno)); |
337 | else if (pid == 0) /* Child. */ | 347 | else if (pid == 0) /* Child. */ |
338 | { | 348 | { |
339 | int status; | 349 | int status; |
340 | close (listenfd); | 350 | close (listenfd); |
341 | status = imap4d_mainloop (connfd, connfd); | 351 | status = imap4d_mainloop (connfd, connfd); |
342 | closelog (); | 352 | closelog (); |
343 | exit (status); | 353 | exit (status); |
344 | } | 354 | } |
345 | else | 355 | else |
346 | { | 356 | { |
347 | ++children; | 357 | ++children; |
348 | } | 358 | } |
349 | close (connfd); | 359 | close (connfd); |
350 | } | 360 | } |
351 | } | 361 | } |
352 | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | 13 | ||
14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License |
15 | along with GNU Mailutils; if not, write to the Free Software | 15 | along with GNU Mailutils; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
17 | 17 | ||
18 | #ifndef _IMAP4D_H | 18 | #ifndef _IMAP4D_H |
19 | #define _IMAP4D_H 1 | 19 | #define _IMAP4D_H 1 |
... | @@ -87,6 +87,7 @@ | ... | @@ -87,6 +87,7 @@ |
87 | #include <mailutils/stream.h> | 87 | #include <mailutils/stream.h> |
88 | #include <mailutils/mu_auth.h> | 88 | #include <mailutils/mu_auth.h> |
89 | #include <mailutils/url.h> | 89 | #include <mailutils/url.h> |
90 | #include <mailutils/tls.h> | ||
90 | #include <mailutils/nls.h> | 91 | #include <mailutils/nls.h> |
91 | 92 | ||
92 | #ifdef __cplusplus | 93 | #ifdef __cplusplus |
... | @@ -126,7 +127,8 @@ struct imap4d_command | ... | @@ -126,7 +127,8 @@ struct imap4d_command |
126 | #define ERR_NO_OFILE 2 | 127 | #define ERR_NO_OFILE 2 |
127 | #define ERR_TIMEOUT 3 | 128 | #define ERR_TIMEOUT 3 |
128 | #define ERR_SIGNAL 4 | 129 | #define ERR_SIGNAL 4 |
129 | 130 | #define ERR_TLS 5 | |
131 | |||
130 | /* Namespace numbers */ | 132 | /* Namespace numbers */ |
131 | #define NS_PRIVATE 0 | 133 | #define NS_PRIVATE 0 |
132 | #define NS_OTHER 1 | 134 | #define NS_OTHER 1 |
... | @@ -139,8 +141,6 @@ struct imap4d_command | ... | @@ -139,8 +141,6 @@ struct imap4d_command |
139 | #define WCARD_RECURSE_MATCH 2 | 141 | #define WCARD_RECURSE_MATCH 2 |
140 | 142 | ||
141 | extern struct imap4d_command imap4d_command_table[]; | 143 | extern struct imap4d_command imap4d_command_table[]; |
142 | extern FILE *ifile; | ||
143 | extern FILE *ofile; | ||
144 | extern mailbox_t mbox; | 144 | extern mailbox_t mbox; |
145 | extern char *homedir; | 145 | extern char *homedir; |
146 | extern char *rootdir; | 146 | extern char *rootdir; |
... | @@ -149,7 +149,12 @@ extern volatile size_t children; | ... | @@ -149,7 +149,12 @@ extern volatile size_t children; |
149 | extern int is_virtual; | 149 | extern int is_virtual; |
150 | extern struct daemon_param daemon_param; | 150 | extern struct daemon_param daemon_param; |
151 | extern struct mu_auth_data *auth_data; | 151 | extern struct mu_auth_data *auth_data; |
152 | 152 | ||
153 | #ifdef WITH_TLS | ||
154 | extern int tls_available; | ||
155 | extern int tls_done; | ||
156 | #endif /* WITH_TLS */ | ||
157 | |||
153 | #ifndef HAVE_STRTOK_R | 158 | #ifndef HAVE_STRTOK_R |
154 | extern char *strtok_r __P((char *s, const char *delim, char **save_ptr)); | 159 | extern char *strtok_r __P((char *s, const char *delim, char **save_ptr)); |
155 | #endif | 160 | #endif |
... | @@ -181,6 +186,9 @@ extern int imap4d_search0 __P((char *arg, int isuid, char *replybuf, size_t rep | ... | @@ -181,6 +186,9 @@ extern int imap4d_search0 __P((char *arg, int isuid, char *replybuf, size_t rep |
181 | extern int imap4d_select __P ((struct imap4d_command *, char *)); | 186 | extern int imap4d_select __P ((struct imap4d_command *, char *)); |
182 | extern int imap4d_select0 __P ((struct imap4d_command *, char *, int)); | 187 | extern int imap4d_select0 __P ((struct imap4d_command *, char *, int)); |
183 | extern int imap4d_select_status __P((void)); | 188 | extern int imap4d_select_status __P((void)); |
189 | #ifdef WITH_TLS | ||
190 | extern int imap4d_starttls __P ((struct imap4d_command *, char *)); | ||
191 | #endif /* WITH_TLS */ | ||
184 | extern int imap4d_status __P ((struct imap4d_command *, char *)); | 192 | extern int imap4d_status __P ((struct imap4d_command *, char *)); |
185 | extern int imap4d_store __P ((struct imap4d_command *, char *)); | 193 | extern int imap4d_store __P ((struct imap4d_command *, char *)); |
186 | extern int imap4d_store0 __P ((char *, int, char *, size_t)); | 194 | extern int imap4d_store0 __P ((char *, int, char *, size_t)); |
... | @@ -220,8 +228,8 @@ extern int util_start __P ((char *)); | ... | @@ -220,8 +228,8 @@ extern int util_start __P ((char *)); |
220 | extern int util_finish __P ((struct imap4d_command *, int, const char *, ...)); | 228 | extern int util_finish __P ((struct imap4d_command *, int, const char *, ...)); |
221 | extern int util_getstate __P ((void)); | 229 | extern int util_getstate __P ((void)); |
222 | extern int util_do_command __P ((char *)); | 230 | extern int util_do_command __P ((char *)); |
223 | extern char *imap4d_readline __P ((FILE*)); | 231 | extern char *imap4d_readline __P ((void)); |
224 | extern char *imap4d_readline_ex __P ((FILE*)); | 232 | extern char *imap4d_readline_ex __P ((void)); |
225 | extern char *util_getword __P ((char *, char **)); | 233 | extern char *util_getword __P ((char *, char **)); |
226 | extern char *util_getitem __P ((char *, const char *, char **)); | 234 | extern char *util_getitem __P ((char *, const char *, char **)); |
227 | extern int util_token __P ((char *, size_t, char **)); | 235 | extern int util_token __P ((char *, size_t, char **)); |
... | @@ -256,7 +264,15 @@ int util_attribute_to_type __P((const char *item, int *type)); | ... | @@ -256,7 +264,15 @@ int util_attribute_to_type __P((const char *item, int *type)); |
256 | int util_type_to_attribute __P((int type, char **attr_str)); | 264 | int util_type_to_attribute __P((int type, char **attr_str)); |
257 | int util_attribute_matches_flag __P((attribute_t attr, const char *item)); | 265 | int util_attribute_matches_flag __P((attribute_t attr, const char *item)); |
258 | int util_uidvalidity __P((mailbox_t smbox, unsigned long *uidvp)); | 266 | int util_uidvalidity __P((mailbox_t smbox, unsigned long *uidvp)); |
259 | 267 | ||
268 | void util_setio __P((int, int)); | ||
269 | void util_flush_output __P((void)); | ||
270 | FILE *util_is_ofile __P((void)); | ||
271 | #ifdef WITH_TLS | ||
272 | int imap4d_init_tls_server __P((void)); | ||
273 | void imap4d_deinit_tls_server __P((void)); | ||
274 | #endif /* WITH_TLS */ | ||
275 | |||
260 | #ifdef __cplusplus | 276 | #ifdef __cplusplus |
261 | } | 277 | } |
262 | #endif | 278 | #endif | ... | ... |
... | @@ -41,7 +41,7 @@ imap4d_signal (int signo) | ... | @@ -41,7 +41,7 @@ imap4d_signal (int signo) |
41 | { | 41 | { |
42 | syslog (LOG_CRIT, _("got signal %s"), strsignal (signo)); | 42 | syslog (LOG_CRIT, _("got signal %s"), strsignal (signo)); |
43 | /* Master process. */ | 43 | /* Master process. */ |
44 | if (!ofile) | 44 | if (!(util_is_ofile())) |
45 | { | 45 | { |
46 | syslog (LOG_CRIT, _("MASTER: exiting on signal")); | 46 | syslog (LOG_CRIT, _("MASTER: exiting on signal")); |
47 | exit (1); /* abort(); */ | 47 | exit (1); /* abort(); */ | ... | ... |
imap4d/starttls.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2003 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Mailutils; if not, write to the Free Software | ||
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ | ||
17 | |||
18 | #include "imap4d.h" | ||
19 | |||
20 | #ifdef WITH_TLS | ||
21 | |||
22 | int | ||
23 | imap4d_starttls (struct imap4d_command *command, char *arg) | ||
24 | { | ||
25 | int status; | ||
26 | char *sp = NULL; | ||
27 | |||
28 | if (!tls_available || tls_done) | ||
29 | return util_finish (command, RESP_BAD, "Invalid command"); | ||
30 | |||
31 | if (util_getword (arg, &sp)) | ||
32 | return util_finish (command, RESP_BAD, "Too many args"); | ||
33 | |||
34 | status = util_finish (command, RESP_OK, "Begin TLS negotiation"); | ||
35 | tls_done = imap4d_init_tls_server (); | ||
36 | |||
37 | return status; | ||
38 | } | ||
39 | |||
40 | #endif /* WITH_TLS */ | ||
41 | |||
42 | /* EOF */ |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -13,10 +13,16 @@ | ... | @@ -13,10 +13,16 @@ |
13 | 13 | ||
14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License |
15 | along with GNU Mailutils; if not, write to the Free Software | 15 | along with GNU Mailutils; if not, write to the Free Software |
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
17 | 17 | ||
18 | #include "imap4d.h" | 18 | #include "imap4d.h" |
19 | 19 | ||
20 | static FILE *ifile; | ||
21 | static FILE *ofile; | ||
22 | #ifdef WITH_TLS | ||
23 | static gnutls_session sfile; | ||
24 | #endif /* WITH_TLS */ | ||
25 | |||
20 | static int add2set __P ((size_t **, int *, unsigned long)); | 26 | static int add2set __P ((size_t **, int *, unsigned long)); |
21 | static const char *sc2string __P ((int)); | 27 | static const char *sc2string __P ((int)); |
22 | 28 | ||
... | @@ -36,7 +42,7 @@ util_getitem (char *s, const char *delim, char **save) | ... | @@ -36,7 +42,7 @@ util_getitem (char *s, const char *delim, char **save) |
36 | char *p; | 42 | char *p; |
37 | if ((p = s) || (p = *save)) | 43 | if ((p = s) || (p = *save)) |
38 | { | 44 | { |
39 | while (isspace ((unsigned)*p)) | 45 | while (isspace ((unsigned) *p)) |
40 | p++; | 46 | p++; |
41 | if (*p == '"') | 47 | if (*p == '"') |
42 | { | 48 | { |
... | @@ -45,7 +51,7 @@ util_getitem (char *s, const char *delim, char **save) | ... | @@ -45,7 +51,7 @@ util_getitem (char *s, const char *delim, char **save) |
45 | while (*p && *p != '"') | 51 | while (*p && *p != '"') |
46 | p++; | 52 | p++; |
47 | if (*p == '"') | 53 | if (*p == '"') |
48 | p++; | 54 | p++; |
49 | *save = (*p) ? p + 1 : p; | 55 | *save = (*p) ? p + 1 : p; |
50 | *p = '\0'; | 56 | *p = '\0'; |
51 | return s; | 57 | return s; |
... | @@ -70,23 +76,22 @@ util_token (char *buf, size_t len, char **ptr) | ... | @@ -70,23 +76,22 @@ util_token (char *buf, size_t len, char **ptr) |
70 | for (i = 1; **ptr && i < len; (*ptr)++, buf++, i++) | 76 | for (i = 1; **ptr && i < len; (*ptr)++, buf++, i++) |
71 | { | 77 | { |
72 | if (**ptr == ' ' || **ptr == '.' | 78 | if (**ptr == ' ' || **ptr == '.' |
73 | || **ptr == '(' || **ptr == ')' | 79 | || **ptr == '(' || **ptr == ')' |
74 | || **ptr == '[' || **ptr == ']' | 80 | || **ptr == '[' || **ptr == ']' |
75 | || **ptr == '<' || **ptr == '>' | 81 | || **ptr == '<' || **ptr == '>' || **ptr == '\r' || **ptr == '\n') |
76 | || **ptr == '\r' || **ptr == '\n') | 82 | { |
77 | { | 83 | /* Advance. */ |
78 | /* Advance. */ | 84 | if (start == (*ptr)) |
79 | if (start == (*ptr)) | 85 | (*ptr)++; |
80 | (*ptr)++; | 86 | break; |
81 | break; | 87 | } |
82 | } | ||
83 | *buf = **ptr; | 88 | *buf = **ptr; |
84 | } | 89 | } |
85 | *buf = '\0'; | 90 | *buf = '\0'; |
86 | /* Skip trailing space. */ | 91 | /* Skip trailing space. */ |
87 | while (**ptr && **ptr == ' ') | 92 | while (**ptr && **ptr == ' ') |
88 | (*ptr)++; | 93 | (*ptr)++; |
89 | return *ptr - start; | 94 | return *ptr - start; |
90 | } | 95 | } |
91 | 96 | ||
92 | /* Remove the surrounding double quotes. */ | 97 | /* Remove the surrounding double quotes. */ |
... | @@ -100,9 +105,9 @@ util_unquote (char **ptr) | ... | @@ -100,9 +105,9 @@ util_unquote (char **ptr) |
100 | { | 105 | { |
101 | char *p = ++s; | 106 | char *p = ++s; |
102 | while (*p && *p != '"') | 107 | while (*p && *p != '"') |
103 | p++; | 108 | p++; |
104 | if (*p == '"') | 109 | if (*p == '"') |
105 | *p = '\0'; | 110 | *p = '\0'; |
106 | } | 111 | } |
107 | *ptr = s; | 112 | *ptr = s; |
108 | } | 113 | } |
... | @@ -123,7 +128,8 @@ util_getfullpath (char *name, const char *delim) | ... | @@ -123,7 +128,8 @@ util_getfullpath (char *name, const char *delim) |
123 | char *p = util_tilde_expansion (name, delim); | 128 | char *p = util_tilde_expansion (name, delim); |
124 | if (*p != delim[0]) | 129 | if (*p != delim[0]) |
125 | { | 130 | { |
126 | char *s = calloc (strlen (homedir) + strlen (delim) + strlen (p) + 1, 1); | 131 | char *s = |
132 | calloc (strlen (homedir) + strlen (delim) + strlen (p) + 1, 1); | ||
127 | sprintf (s, "%s%s%s", homedir, delim, p); | 133 | sprintf (s, "%s%s%s", homedir, delim, p); |
128 | free (p); | 134 | free (p); |
129 | p = s; | 135 | p = s; |
... | @@ -134,7 +140,7 @@ util_getfullpath (char *name, const char *delim) | ... | @@ -134,7 +140,7 @@ util_getfullpath (char *name, const char *delim) |
134 | static int | 140 | static int |
135 | comp_int (const void *a, const void *b) | 141 | comp_int (const void *a, const void *b) |
136 | { | 142 | { |
137 | return *(int*)a - *(int*)b; | 143 | return *(int *) a - *(int *) b; |
138 | } | 144 | } |
139 | 145 | ||
140 | /* Return in set an allocated array contain (n) numbers, for imap messsage set | 146 | /* Return in set an allocated array contain (n) numbers, for imap messsage set |
... | @@ -150,7 +156,7 @@ comp_int (const void *a, const void *b) | ... | @@ -150,7 +156,7 @@ comp_int (const void *a, const void *b) |
150 | FIXME: The algo below is to relaxe, things like <,,,> or <:12> or <20:10> | 156 | FIXME: The algo below is to relaxe, things like <,,,> or <:12> or <20:10> |
151 | will not generate an error. */ | 157 | will not generate an error. */ |
152 | int | 158 | int |
153 | util_msgset (char *s, size_t **set, int *n, int isuid) | 159 | util_msgset (char *s, size_t ** set, int *n, int isuid) |
154 | { | 160 | { |
155 | unsigned long val = 0; | 161 | unsigned long val = 0; |
156 | unsigned long low = 0; | 162 | unsigned long low = 0; |
... | @@ -158,7 +164,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -158,7 +164,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
158 | int status = 0; | 164 | int status = 0; |
159 | size_t max = 0; | 165 | size_t max = 0; |
160 | size_t *tmp; | 166 | size_t *tmp; |
161 | int i,j; | 167 | int i, j; |
162 | 168 | ||
163 | status = mailbox_messages_count (mbox, &max); | 169 | status = mailbox_messages_count (mbox, &max); |
164 | if (status != 0) | 170 | if (status != 0) |
... | @@ -178,8 +184,16 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -178,8 +184,16 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
178 | switch (*s) | 184 | switch (*s) |
179 | { | 185 | { |
180 | /* isdigit */ | 186 | /* isdigit */ |
181 | case '0': case '1': case '2': case '3': case '4': | 187 | case '0': |
182 | case '5': case '6': case '7': case '8': case '9': | 188 | case '1': |
189 | case '2': | ||
190 | case '3': | ||
191 | case '4': | ||
192 | case '5': | ||
193 | case '6': | ||
194 | case '7': | ||
195 | case '8': | ||
196 | case '9': | ||
183 | { | 197 | { |
184 | errno = 0; | 198 | errno = 0; |
185 | val = strtoul (s, &s, 10); | 199 | val = strtoul (s, &s, 10); |
... | @@ -206,7 +220,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -206,7 +220,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
206 | low = val; | 220 | low = val; |
207 | val = tmp; | 221 | val = tmp; |
208 | } | 222 | } |
209 | for (;low && low <= val; low++) | 223 | for (; low && low <= val; low++) |
210 | { | 224 | { |
211 | status = add2set (set, n, low); | 225 | status = add2set (set, n, low); |
212 | if (status != 0) | 226 | if (status != 0) |
... | @@ -227,7 +241,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -227,7 +241,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
227 | contiguous set of mesages ranging from the first number to the | 241 | contiguous set of mesages ranging from the first number to the |
228 | second: | 242 | second: |
229 | 3:5 --> 3 4 5 | 243 | 3:5 --> 3 4 5 |
230 | */ | 244 | */ |
231 | case ':': | 245 | case ':': |
232 | low = val + 1; | 246 | low = val + 1; |
233 | s++; | 247 | s++; |
... | @@ -236,7 +250,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -236,7 +250,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
236 | /* As a convenience. '*' is provided to refer to the highest message | 250 | /* As a convenience. '*' is provided to refer to the highest message |
237 | number int the mailbox: | 251 | number int the mailbox: |
238 | 5:* --> 5 6 7 8 | 252 | 5:* --> 5 6 7 8 |
239 | */ | 253 | */ |
240 | case '*': | 254 | case '*': |
241 | { | 255 | { |
242 | val = max; | 256 | val = max; |
... | @@ -250,7 +264,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -250,7 +264,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
250 | /* IMAP also allows a set of noncontiguous numbers to be specified | 264 | /* IMAP also allows a set of noncontiguous numbers to be specified |
251 | with the ',' character: | 265 | with the ',' character: |
252 | 1,3,5,7 --> 1 3 5 7 | 266 | 1,3,5,7 --> 1 3 5 7 |
253 | */ | 267 | */ |
254 | case ',': | 268 | case ',': |
255 | s++; | 269 | s++; |
256 | break; | 270 | break; |
... | @@ -262,11 +276,11 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -262,11 +276,11 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
262 | *n = 0; | 276 | *n = 0; |
263 | return EINVAL; | 277 | return EINVAL; |
264 | 278 | ||
265 | } /* switch */ | 279 | } /* switch */ |
266 | 280 | ||
267 | if (done) | 281 | if (done) |
268 | break; | 282 | break; |
269 | } /* while */ | 283 | } /* while */ |
270 | 284 | ||
271 | if (low) | 285 | if (low) |
272 | { | 286 | { |
... | @@ -284,7 +298,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -284,7 +298,7 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
284 | low = val; | 298 | low = val; |
285 | val = tmp; | 299 | val = tmp; |
286 | } | 300 | } |
287 | for (;low && low <= val; low++) | 301 | for (; low && low <= val; low++) |
288 | { | 302 | { |
289 | status = add2set (set, n, low); | 303 | status = add2set (set, n, low); |
290 | if (status != 0) | 304 | if (status != 0) |
... | @@ -298,32 +312,49 @@ util_msgset (char *s, size_t **set, int *n, int isuid) | ... | @@ -298,32 +312,49 @@ util_msgset (char *s, size_t **set, int *n, int isuid) |
298 | /* Remove duplicates. tmp serves to avoid extra dereferences */ | 312 | /* Remove duplicates. tmp serves to avoid extra dereferences */ |
299 | tmp = *set; | 313 | tmp = *set; |
300 | for (i = 0, j = 1; i < *n; i++) | 314 | for (i = 0, j = 1; i < *n; i++) |
301 | if (tmp[j-1] != tmp[i]) | 315 | if (tmp[j - 1] != tmp[i]) |
302 | tmp[j++] = tmp[i]; | 316 | tmp[j++] = tmp[i]; |
303 | *n = j; | 317 | *n = j; |
304 | return 0; | 318 | return 0; |
305 | } | 319 | } |
306 | 320 | ||
307 | /* Use vfprintf for the dirty work. */ | 321 | static int |
322 | util_send_lowlevel (char *buf) | ||
323 | { | ||
324 | int status; | ||
325 | |||
326 | if (buf) | ||
327 | { | ||
328 | #ifdef WITH_TLS | ||
329 | if (tls_done) | ||
330 | status = gnutls_record_send (sfile, buf, strlen (buf)); | ||
331 | else | ||
332 | #endif /* WITH_TLS */ | ||
333 | status = fprintf (ofile, buf); | ||
334 | } | ||
335 | |||
336 | return status; | ||
337 | } | ||
338 | |||
308 | int | 339 | int |
309 | util_send (const char *format, ...) | 340 | util_send (const char *format, ...) |
310 | { | 341 | { |
311 | int status; | 342 | char *buf = NULL; |
343 | int status = 0; | ||
312 | va_list ap; | 344 | va_list ap; |
345 | |||
313 | va_start (ap, format); | 346 | va_start (ap, format); |
347 | vasprintf (&buf, format, ap); | ||
314 | 348 | ||
315 | if (daemon_param.transcript) | 349 | if (buf) |
316 | { | 350 | { |
317 | char *buf; | 351 | if (daemon_param.transcript) |
318 | vasprintf (&buf, format, ap); | 352 | syslog (LOG_DEBUG, "sent: %s", buf); |
319 | if (buf) | 353 | |
320 | { | 354 | status = util_send_lowlevel (buf); |
321 | syslog (LOG_DEBUG, "sent: %s", buf); | 355 | free (buf); |
322 | free (buf); | ||
323 | } | ||
324 | } | 356 | } |
325 | 357 | ||
326 | status = vfprintf (ofile, format, ap); | ||
327 | va_end (ap); | 358 | va_end (ap); |
328 | return status; | 359 | return status; |
329 | } | 360 | } |
... | @@ -361,24 +392,26 @@ util_send_literal (const char *buffer) | ... | @@ -361,24 +392,26 @@ util_send_literal (const char *buffer) |
361 | int | 392 | int |
362 | util_out (int rc, const char *format, ...) | 393 | util_out (int rc, const char *format, ...) |
363 | { | 394 | { |
395 | char *tempbuf = NULL; | ||
364 | char *buf = NULL; | 396 | char *buf = NULL; |
365 | int status; | 397 | int status = 0; |
366 | va_list ap; | 398 | va_list ap; |
367 | asprintf (&buf, "* %s%s\r\n", sc2string (rc), format); | 399 | |
400 | asprintf (&tempbuf, "* %s%s\r\n", sc2string (rc), format); | ||
368 | va_start (ap, format); | 401 | va_start (ap, format); |
369 | if (daemon_param.transcript) | 402 | vasprintf (&buf, tempbuf, ap); |
403 | |||
404 | if (buf) | ||
370 | { | 405 | { |
371 | char *buf1 = NULL; | 406 | if (daemon_param.transcript) |
372 | vasprintf (&buf1, buf, ap); | 407 | syslog (LOG_DEBUG, "sent: %s", buf); |
373 | if (buf1) | 408 | |
374 | { | 409 | status = util_send_lowlevel (buf); |
375 | syslog (LOG_DEBUG, "sent: %s", buf1); | 410 | free (buf); |
376 | free (buf1); | ||
377 | } | ||
378 | } | 411 | } |
379 | status = vfprintf (ofile, buf, ap); | 412 | |
380 | va_end (ap); | 413 | va_end (ap); |
381 | free (buf); | 414 | free (tempbuf); |
382 | return status; | 415 | return status; |
383 | } | 416 | } |
384 | 417 | ||
... | @@ -386,29 +419,29 @@ util_out (int rc, const char *format, ...) | ... | @@ -386,29 +419,29 @@ util_out (int rc, const char *format, ...) |
386 | int | 419 | int |
387 | util_finish (struct imap4d_command *command, int rc, const char *format, ...) | 420 | util_finish (struct imap4d_command *command, int rc, const char *format, ...) |
388 | { | 421 | { |
422 | char *tempbuf = NULL; | ||
389 | char *buf = NULL; | 423 | char *buf = NULL; |
390 | int new_state; | 424 | int new_state; |
391 | int status; | 425 | int status = 0; |
392 | va_list ap; | 426 | va_list ap; |
393 | 427 | ||
394 | asprintf (&buf, "%s %s%s %s\r\n", command->tag, sc2string (rc), | 428 | asprintf (&tempbuf, "%s %s%s %s\r\n", command->tag, sc2string (rc), |
395 | command->name, format); | 429 | command->name, format); |
396 | |||
397 | va_start (ap, format); | 430 | va_start (ap, format); |
398 | if (daemon_param.transcript) | 431 | vasprintf (&buf, tempbuf, ap); |
432 | |||
433 | if (buf) | ||
399 | { | 434 | { |
400 | char *buf1 = NULL; | 435 | if (daemon_param.transcript) |
401 | vasprintf (&buf1, buf, ap); | 436 | syslog (LOG_DEBUG, "sent: %s", buf); |
402 | if (buf1) | 437 | |
403 | { | 438 | status = util_send_lowlevel (buf); |
404 | syslog (LOG_DEBUG, "sent: %s", buf1); | 439 | free (buf); |
405 | free (buf1); | ||
406 | } | ||
407 | } | 440 | } |
408 | 441 | ||
409 | status = vfprintf (ofile, buf, ap); | ||
410 | va_end (ap); | 442 | va_end (ap); |
411 | free (buf); | 443 | free (tempbuf); |
444 | |||
412 | /* Reset the state. */ | 445 | /* Reset the state. */ |
413 | if (rc == RESP_OK) | 446 | if (rc == RESP_OK) |
414 | new_state = command->success; | 447 | new_state = command->success; |
... | @@ -416,9 +449,10 @@ util_finish (struct imap4d_command *command, int rc, const char *format, ...) | ... | @@ -416,9 +449,10 @@ util_finish (struct imap4d_command *command, int rc, const char *format, ...) |
416 | new_state = command->failure; | 449 | new_state = command->failure; |
417 | else | 450 | else |
418 | new_state = STATE_NONE; | 451 | new_state = STATE_NONE; |
419 | 452 | ||
420 | if (new_state != STATE_NONE) | 453 | if (new_state != STATE_NONE) |
421 | state = new_state; | 454 | state = new_state; |
455 | |||
422 | return status; | 456 | return status; |
423 | } | 457 | } |
424 | 458 | ||
... | @@ -429,7 +463,7 @@ util_finish (struct imap4d_command *command, int rc, const char *format, ...) | ... | @@ -429,7 +463,7 @@ util_finish (struct imap4d_command *command, int rc, const char *format, ...) |
429 | the number of octets, close brace ("}"), and CRLF. | 463 | the number of octets, close brace ("}"), and CRLF. |
430 | */ | 464 | */ |
431 | char * | 465 | char * |
432 | imap4d_readline (FILE *fp) | 466 | imap4d_readline (void) |
433 | { | 467 | { |
434 | char buffer[512]; | 468 | char buffer[512]; |
435 | size_t len; | 469 | size_t len; |
... | @@ -440,13 +474,28 @@ imap4d_readline (FILE *fp) | ... | @@ -440,13 +474,28 @@ imap4d_readline (FILE *fp) |
440 | if (!line) | 474 | if (!line) |
441 | imap4d_bye (ERR_NO_MEM); | 475 | imap4d_bye (ERR_NO_MEM); |
442 | 476 | ||
443 | line[0] = '\0'; /* start with a empty string. */ | 477 | line[0] = '\0'; /* start with a empty string. */ |
444 | do | 478 | do |
445 | { | 479 | { |
446 | alarm (daemon_param.timeout); | 480 | alarm (daemon_param.timeout); |
447 | if (fgets (buffer, sizeof (buffer), fp) == NULL) | 481 | #ifdef WITH_TLS |
482 | if (tls_done) | ||
483 | { | ||
484 | len = gnutls_record_recv (sfile, buffer, sizeof (buffer) - 1); | ||
485 | if (len < 0) | ||
486 | { | ||
487 | syslog (LOG_INFO, _("TLS error on read: %s"), | ||
488 | gnutls_strerror (len)); | ||
489 | imap4d_bye (ERR_TLS); | ||
490 | } | ||
491 | else | ||
492 | buffer[len] = 0; | ||
493 | } | ||
494 | else | ||
495 | #endif /* WITH_TLS */ | ||
496 | if (fgets (buffer, sizeof (buffer), ifile) == NULL) | ||
448 | { | 497 | { |
449 | if (feof (fp)) | 498 | if (feof (ifile)) |
450 | syslog (LOG_INFO, _("unexpected eof on input")); | 499 | syslog (LOG_INFO, _("unexpected eof on input")); |
451 | else if (errno) | 500 | else if (errno) |
452 | syslog (LOG_INFO, _("error reading from input file: %m")); | 501 | syslog (LOG_INFO, _("error reading from input file: %m")); |
... | @@ -458,9 +507,9 @@ imap4d_readline (FILE *fp) | ... | @@ -458,9 +507,9 @@ imap4d_readline (FILE *fp) |
458 | 507 | ||
459 | len = strlen (buffer); | 508 | len = strlen (buffer); |
460 | /* If we were in a litteral substract. We have to do it here since the CR | 509 | /* If we were in a litteral substract. We have to do it here since the CR |
461 | is part of the count in a literal. */ | 510 | is part of the count in a literal. */ |
462 | if (number) | 511 | if (number) |
463 | number -= len; | 512 | number -= len; |
464 | 513 | ||
465 | /* Remove CR. */ | 514 | /* Remove CR. */ |
466 | if (len > 1 && buffer[len - 1] == '\n') | 515 | if (len > 1 && buffer[len - 1] == '\n') |
... | @@ -479,36 +528,37 @@ imap4d_readline (FILE *fp) | ... | @@ -479,36 +528,37 @@ imap4d_readline (FILE *fp) |
479 | total = strlen (line); | 528 | total = strlen (line); |
480 | 529 | ||
481 | /* I observe some client requesting long FETCH operations since, I did | 530 | /* I observe some client requesting long FETCH operations since, I did |
482 | not see any limit in the command length in the RFC, catch things | 531 | not see any limit in the command length in the RFC, catch things |
483 | here. */ | 532 | here. */ |
484 | /* Check that we do have a terminated NL line and we are not retrieving | 533 | /* Check that we do have a terminated NL line and we are not retrieving |
485 | a literal. If we don't continue the read. */ | 534 | a literal. If we don't continue the read. */ |
486 | if (number <= 0 && total && line[total - 1] != '\n') | 535 | if (number <= 0 && total && line[total - 1] != '\n') |
487 | continue; | 536 | continue; |
488 | 537 | ||
489 | /* Check if the client try to send a literal and make sure we are not | 538 | /* Check if the client try to send a literal and make sure we are not |
490 | already retrieving a literal. */ | 539 | already retrieving a literal. */ |
491 | if (number <= 0 && len > 2) | 540 | if (number <= 0 && len > 2) |
492 | { | 541 | { |
493 | size_t n = total - 1; /* C arrays are 0-based. */ | 542 | size_t n = total - 1; /* C arrays are 0-based. */ |
494 | /* A literal is this "{number}\n". The CR is already strip. */ | 543 | /* A literal is this "{number}\n". The CR is already strip. */ |
495 | if (line[n] == '\n' && line[n - 1] == '}') | 544 | if (line[n] == '\n' && line[n - 1] == '}') |
496 | { | 545 | { |
497 | /* Search for the matching bracket. */ | 546 | /* Search for the matching bracket. */ |
498 | while (n && line[n] != '{') n--; | 547 | while (n && line[n] != '{') |
499 | if (line [n] == '{') | 548 | n--; |
500 | { | 549 | if (line[n] == '{') |
501 | char *sp = NULL; | 550 | { |
551 | char *sp = NULL; | ||
502 | /* Truncate where the literal number was. */ | 552 | /* Truncate where the literal number was. */ |
503 | line[n] = '\0'; | 553 | line[n] = '\0'; |
504 | number = strtoul (line + n + 1, &sp, 10); | 554 | number = strtoul (line + n + 1, &sp, 10); |
505 | /* Client can ask for non synchronise literal, | 555 | /* Client can ask for non synchronise literal, |
506 | if a '+' is append to the octet count. */ | 556 | if a '+' is append to the octet count. */ |
507 | if (*sp != '+') | 557 | if (*sp != '+') |
508 | util_send ("+ GO AHEAD\r\n"); | 558 | util_send ("+ GO AHEAD\r\n"); |
509 | } | 559 | } |
510 | } | 560 | } |
511 | } | 561 | } |
512 | } | 562 | } |
513 | while (number > 0 || (total && line[total - 1] != '\n')); | 563 | while (number > 0 || (total && line[total - 1] != '\n')); |
514 | if (daemon_param.transcript) | 564 | if (daemon_param.transcript) |
... | @@ -517,16 +567,16 @@ imap4d_readline (FILE *fp) | ... | @@ -517,16 +567,16 @@ imap4d_readline (FILE *fp) |
517 | } | 567 | } |
518 | 568 | ||
519 | char * | 569 | char * |
520 | imap4d_readline_ex (FILE *fp) | 570 | imap4d_readline_ex (void) |
521 | { | 571 | { |
522 | int len; | 572 | int len; |
523 | char *s = imap4d_readline (fp); | 573 | char *s = imap4d_readline (); |
524 | 574 | ||
525 | if (s && (len = strlen (s)) > 0 && s[len-1] == '\n') | 575 | if (s && (len = strlen (s)) > 0 && s[len - 1] == '\n') |
526 | s[len-1] = 0; | 576 | s[len - 1] = 0; |
527 | return s; | 577 | return s; |
528 | } | 578 | } |
529 | 579 | ||
530 | int | 580 | int |
531 | util_do_command (char *prompt) | 581 | util_do_command (char *prompt) |
532 | { | 582 | { |
... | @@ -540,7 +590,7 @@ util_do_command (char *prompt) | ... | @@ -540,7 +590,7 @@ util_do_command (char *prompt) |
540 | if (!tag) | 590 | if (!tag) |
541 | { | 591 | { |
542 | nullcommand.name = ""; | 592 | nullcommand.name = ""; |
543 | nullcommand.tag = (char *)"*"; | 593 | nullcommand.tag = (char *) "*"; |
544 | return util_finish (&nullcommand, RESP_BAD, "Null command"); | 594 | return util_finish (&nullcommand, RESP_BAD, "Null command"); |
545 | } | 595 | } |
546 | else if (!cmd) | 596 | else if (!cmd) |
... | @@ -557,16 +607,16 @@ util_do_command (char *prompt) | ... | @@ -557,16 +607,16 @@ util_do_command (char *prompt) |
557 | { | 607 | { |
558 | nullcommand.name = ""; | 608 | nullcommand.name = ""; |
559 | nullcommand.tag = tag; | 609 | nullcommand.tag = tag; |
560 | return util_finish (&nullcommand, RESP_BAD, "Invalid command"); | 610 | return util_finish (&nullcommand, RESP_BAD, "Invalid command"); |
561 | } | 611 | } |
562 | 612 | ||
563 | command->tag = tag; | 613 | command->tag = tag; |
564 | 614 | ||
565 | if (command->states && (command->states & state) == 0) | 615 | if (command->states && (command->states & state) == 0) |
566 | return util_finish (command, RESP_BAD, "Wrong state"); | 616 | return util_finish (command, RESP_BAD, "Wrong state"); |
567 | 617 | ||
568 | len = strlen (sp); | 618 | len = strlen (sp); |
569 | if (len && sp[len - 1] == '\n') | 619 | if (len && sp[len - 1] == '\n') |
570 | sp[len - 1] = '\0'; | 620 | sp[len - 1] = '\0'; |
571 | return command->func (command, sp); | 621 | return command->func (command, sp); |
572 | } | 622 | } |
... | @@ -577,7 +627,7 @@ util_upper (char *s) | ... | @@ -577,7 +627,7 @@ util_upper (char *s) |
577 | if (!s) | 627 | if (!s) |
578 | return 0; | 628 | return 0; |
579 | for (; *s; s++) | 629 | for (; *s; s++) |
580 | *s = toupper ((unsigned)*s); | 630 | *s = toupper ((unsigned) *s); |
581 | return 0; | 631 | return 0; |
582 | } | 632 | } |
583 | 633 | ||
... | @@ -585,7 +635,7 @@ util_upper (char *s) | ... | @@ -585,7 +635,7 @@ util_upper (char *s) |
585 | int | 635 | int |
586 | util_start (char *tag) | 636 | util_start (char *tag) |
587 | { | 637 | { |
588 | (void)tag; | 638 | (void) tag; |
589 | return 0; | 639 | return 0; |
590 | } | 640 | } |
591 | 641 | ||
... | @@ -632,7 +682,7 @@ sc2string (int rc) | ... | @@ -632,7 +682,7 @@ sc2string (int rc) |
632 | } | 682 | } |
633 | 683 | ||
634 | static int | 684 | static int |
635 | add2set (size_t **set, int *n, unsigned long val) | 685 | add2set (size_t ** set, int *n, unsigned long val) |
636 | { | 686 | { |
637 | size_t *tmp; | 687 | size_t *tmp; |
638 | tmp = realloc (*set, (*n + 1) * sizeof (**set)); | 688 | tmp = realloc (*set, (*n + 1) * sizeof (**set)); |
... | @@ -650,18 +700,18 @@ add2set (size_t **set, int *n, unsigned long val) | ... | @@ -650,18 +700,18 @@ add2set (size_t **set, int *n, unsigned long val) |
650 | } | 700 | } |
651 | 701 | ||
652 | int | 702 | int |
653 | util_parse_internal_date0 (char *date, time_t *timep, char **endp) | 703 | util_parse_internal_date0 (char *date, time_t * timep, char **endp) |
654 | { | 704 | { |
655 | struct tm tm; | 705 | struct tm tm; |
656 | mu_timezone tz; | 706 | mu_timezone tz; |
657 | time_t time; | 707 | time_t time; |
658 | char **datep = &date; | 708 | char **datep = &date; |
659 | 709 | ||
660 | if (mu_parse_imap_date_time((const char **)datep, &tm, &tz)) | 710 | if (mu_parse_imap_date_time ((const char **) datep, &tm, &tz)) |
661 | return 1; | 711 | return 1; |
662 | 712 | ||
663 | time = mu_tm2time (&tm, &tz); | 713 | time = mu_tm2time (&tm, &tz); |
664 | if (time == (time_t) -1) | 714 | if (time == (time_t) - 1) |
665 | return 2; | 715 | return 2; |
666 | 716 | ||
667 | *timep = time; | 717 | *timep = time; |
... | @@ -671,20 +721,20 @@ util_parse_internal_date0 (char *date, time_t *timep, char **endp) | ... | @@ -671,20 +721,20 @@ util_parse_internal_date0 (char *date, time_t *timep, char **endp) |
671 | } | 721 | } |
672 | 722 | ||
673 | int | 723 | int |
674 | util_parse_internal_date (char *date, time_t *timep) | 724 | util_parse_internal_date (char *date, time_t * timep) |
675 | { | 725 | { |
676 | return util_parse_internal_date0 (date, timep, NULL); | 726 | return util_parse_internal_date0 (date, timep, NULL); |
677 | } | 727 | } |
678 | 728 | ||
679 | 729 | ||
680 | int | 730 | int |
681 | util_parse_822_date (char *date, time_t *timep) | 731 | util_parse_822_date (char *date, time_t * timep) |
682 | { | 732 | { |
683 | struct tm tm; | 733 | struct tm tm; |
684 | mu_timezone tz; | 734 | mu_timezone tz; |
685 | const char* p = date; | 735 | const char *p = date; |
686 | 736 | ||
687 | if (parse822_date_time(&p, date+strlen(date), &tm, &tz) == 0) | 737 | if (parse822_date_time (&p, date + strlen (date), &tm, &tz) == 0) |
688 | { | 738 | { |
689 | *timep = mu_tm2time (&tm, &tz); | 739 | *timep = mu_tm2time (&tm, &tz); |
690 | return 0; | 740 | return 0; |
... | @@ -693,12 +743,12 @@ util_parse_822_date (char *date, time_t *timep) | ... | @@ -693,12 +743,12 @@ util_parse_822_date (char *date, time_t *timep) |
693 | } | 743 | } |
694 | 744 | ||
695 | int | 745 | int |
696 | util_parse_ctime_date (const char *date, time_t *timep) | 746 | util_parse_ctime_date (const char *date, time_t * timep) |
697 | { | 747 | { |
698 | struct tm tm; | 748 | struct tm tm; |
699 | mu_timezone tz; | 749 | mu_timezone tz; |
700 | 750 | ||
701 | if (mu_parse_ctime_date_time(&date, &tm, &tz) == 0) | 751 | if (mu_parse_ctime_date_time (&date, &tm, &tz) == 0) |
702 | { | 752 | { |
703 | *timep = mu_tm2time (&tm, &tz); | 753 | *timep = mu_tm2time (&tm, &tz); |
704 | return 0; | 754 | return 0; |
... | @@ -711,8 +761,8 @@ util_parse_ctime_date (const char *date, time_t *timep) | ... | @@ -711,8 +761,8 @@ util_parse_ctime_date (const char *date, time_t *timep) |
711 | char * | 761 | char * |
712 | util_strcasestr (const char *haystack, const char *needle) | 762 | util_strcasestr (const char *haystack, const char *needle) |
713 | { | 763 | { |
714 | register char *needle_end = strchr(needle, '\0'); | 764 | register char *needle_end = strchr (needle, '\0'); |
715 | register char *haystack_end = strchr(haystack, '\0'); | 765 | register char *haystack_end = strchr (haystack, '\0'); |
716 | register size_t needle_len = needle_end - needle; | 766 | register size_t needle_len = needle_end - needle; |
717 | register size_t needle_last = needle_len - 1; | 767 | register size_t needle_last = needle_len - 1; |
718 | register const char *begin; | 768 | register const char *begin; |
... | @@ -729,7 +779,7 @@ util_strcasestr (const char *haystack, const char *needle) | ... | @@ -729,7 +779,7 @@ util_strcasestr (const char *haystack, const char *needle) |
729 | register const char *h = begin; | 779 | register const char *h = begin; |
730 | 780 | ||
731 | do | 781 | do |
732 | if (tolower(*h) != tolower(*n)) | 782 | if (tolower (*h) != tolower (*n)) |
733 | goto loop; /* continue for loop */ | 783 | goto loop; /* continue for loop */ |
734 | while (--n >= needle && --h >= haystack); | 784 | while (--n >= needle && --h >= haystack); |
735 | 785 | ||
... | @@ -746,14 +796,27 @@ struct | ... | @@ -746,14 +796,27 @@ struct |
746 | { | 796 | { |
747 | char *name; | 797 | char *name; |
748 | int flag; | 798 | int flag; |
749 | } _imap4d_attrlist[] = { | 799 | } |
750 | { "\\Answered", MU_ATTRIBUTE_ANSWERED }, | 800 | _imap4d_attrlist[] = |
751 | { "\\Flagged", MU_ATTRIBUTE_FLAGGED }, | 801 | { |
752 | { "\\Deleted", MU_ATTRIBUTE_DELETED }, | 802 | { |
753 | { "\\Draft", MU_ATTRIBUTE_DRAFT }, | 803 | "\\Answered", MU_ATTRIBUTE_ANSWERED} |
754 | { "\\Seen", MU_ATTRIBUTE_READ }, | 804 | , |
755 | { "\\Recent", MU_ATTRIBUTE_RECENT }, | 805 | { |
756 | }; | 806 | "\\Flagged", MU_ATTRIBUTE_FLAGGED} |
807 | , | ||
808 | { | ||
809 | "\\Deleted", MU_ATTRIBUTE_DELETED} | ||
810 | , | ||
811 | { | ||
812 | "\\Draft", MU_ATTRIBUTE_DRAFT} | ||
813 | , | ||
814 | { | ||
815 | "\\Seen", MU_ATTRIBUTE_READ} | ||
816 | , | ||
817 | { | ||
818 | "\\Recent", MU_ATTRIBUTE_RECENT} | ||
819 | ,}; | ||
757 | 820 | ||
758 | #define NATTR sizeof(_imap4d_attrlist)/sizeof(_imap4d_attrlist[0]) | 821 | #define NATTR sizeof(_imap4d_attrlist)/sizeof(_imap4d_attrlist[0]) |
759 | 822 | ||
... | @@ -781,8 +844,8 @@ util_type_to_attribute (int type, char **attr_str) | ... | @@ -781,8 +844,8 @@ util_type_to_attribute (int type, char **attr_str) |
781 | int i; | 844 | int i; |
782 | size_t len = 0; | 845 | size_t len = 0; |
783 | 846 | ||
784 | if (MU_ATTRIBUTE_IS_UNSEEN(type)) | 847 | if (MU_ATTRIBUTE_IS_UNSEEN (type)) |
785 | *attr_str = strdup("\\Recent"); | 848 | *attr_str = strdup ("\\Recent"); |
786 | else | 849 | else |
787 | *attr_str = NULL; | 850 | *attr_str = NULL; |
788 | 851 | ||
... | @@ -790,33 +853,33 @@ util_type_to_attribute (int type, char **attr_str) | ... | @@ -790,33 +853,33 @@ util_type_to_attribute (int type, char **attr_str) |
790 | if (type & _imap4d_attrlist[i].flag) | 853 | if (type & _imap4d_attrlist[i].flag) |
791 | { | 854 | { |
792 | attr_list[nattr++] = _imap4d_attrlist[i].name; | 855 | attr_list[nattr++] = _imap4d_attrlist[i].name; |
793 | len += 1 + strlen(_imap4d_attrlist[i].name); | 856 | len += 1 + strlen (_imap4d_attrlist[i].name); |
794 | } | 857 | } |
795 | 858 | ||
796 | *attr_str = malloc(len+1); | 859 | *attr_str = malloc (len + 1); |
797 | (*attr_str)[0] = 0; | 860 | (*attr_str)[0] = 0; |
798 | if (*attr_str) | 861 | if (*attr_str) |
799 | { | 862 | { |
800 | for (i = 0; i < nattr; i++) | 863 | for (i = 0; i < nattr; i++) |
801 | { | 864 | { |
802 | strcat(*attr_str, attr_list[i]); | 865 | strcat (*attr_str, attr_list[i]); |
803 | if (i != nattr-1) | 866 | if (i != nattr - 1) |
804 | strcat(*attr_str, " "); | 867 | strcat (*attr_str, " "); |
805 | } | 868 | } |
806 | } | 869 | } |
807 | 870 | ||
808 | if (!*attr_str) | 871 | if (!*attr_str) |
809 | imap4d_bye (ERR_NO_MEM); | 872 | imap4d_bye (ERR_NO_MEM); |
810 | return 0; | 873 | return 0; |
811 | } | 874 | } |
812 | 875 | ||
813 | void | 876 | void |
814 | util_print_flags(attribute_t attr) | 877 | util_print_flags (attribute_t attr) |
815 | { | 878 | { |
816 | int i; | 879 | int i; |
817 | int flags = 0; | 880 | int flags = 0; |
818 | int space = 0; | 881 | int space = 0; |
819 | 882 | ||
820 | attribute_get_flags (attr, &flags); | 883 | attribute_get_flags (attr, &flags); |
821 | for (i = 0; i < _imap4d_nattr; i++) | 884 | for (i = 0; i < _imap4d_nattr; i++) |
822 | if (flags & _imap4d_attrlist[i].flag) | 885 | if (flags & _imap4d_attrlist[i].flag) |
... | @@ -827,11 +890,11 @@ util_print_flags(attribute_t attr) | ... | @@ -827,11 +890,11 @@ util_print_flags(attribute_t attr) |
827 | space = 1; | 890 | space = 1; |
828 | util_send (_imap4d_attrlist[i].name); | 891 | util_send (_imap4d_attrlist[i].name); |
829 | } | 892 | } |
830 | 893 | ||
831 | if (MU_ATTRIBUTE_IS_UNSEEN(flags)) | 894 | if (MU_ATTRIBUTE_IS_UNSEEN (flags)) |
832 | { | 895 | { |
833 | if (space) | 896 | if (space) |
834 | util_send (" "); | 897 | util_send (" "); |
835 | util_send ("\\Recent"); | 898 | util_send ("\\Recent"); |
836 | } | 899 | } |
837 | } | 900 | } |
... | @@ -840,7 +903,7 @@ int | ... | @@ -840,7 +903,7 @@ int |
840 | util_attribute_matches_flag (attribute_t attr, const char *item) | 903 | util_attribute_matches_flag (attribute_t attr, const char *item) |
841 | { | 904 | { |
842 | int flags = 0, mask = 0; | 905 | int flags = 0, mask = 0; |
843 | 906 | ||
844 | attribute_get_flags (attr, &flags); | 907 | attribute_get_flags (attr, &flags); |
845 | util_attribute_to_type (item, &mask); | 908 | util_attribute_to_type (item, &mask); |
846 | if (mask == MU_ATTRIBUTE_RECENT) | 909 | if (mask == MU_ATTRIBUTE_RECENT) |
... | @@ -851,7 +914,7 @@ util_attribute_matches_flag (attribute_t attr, const char *item) | ... | @@ -851,7 +914,7 @@ util_attribute_matches_flag (attribute_t attr, const char *item) |
851 | 914 | ||
852 | 915 | ||
853 | int | 916 | int |
854 | util_parse_attributes(char *items, char **save, int *flags) | 917 | util_parse_attributes (char *items, char **save, int *flags) |
855 | { | 918 | { |
856 | int rc = 0; | 919 | int rc = 0; |
857 | 920 | ||
... | @@ -880,13 +943,13 @@ util_parse_attributes(char *items, char **save, int *flags) | ... | @@ -880,13 +943,13 @@ util_parse_attributes(char *items, char **save, int *flags) |
880 | 943 | ||
881 | int | 944 | int |
882 | util_base64_encode (const unsigned char *input, size_t input_len, | 945 | util_base64_encode (const unsigned char *input, size_t input_len, |
883 | unsigned char **output, size_t *output_len) | 946 | unsigned char **output, size_t * output_len) |
884 | { | 947 | { |
885 | static char b64tab[] = | 948 | static char b64tab[] = |
886 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 949 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
887 | size_t olen = 4 * (input_len + 2) / 3; | 950 | size_t olen = 4 * (input_len + 2) / 3; |
888 | unsigned char *out = malloc (olen); | 951 | unsigned char *out = malloc (olen); |
889 | 952 | ||
890 | if (!out) | 953 | if (!out) |
891 | return 1; | 954 | return 1; |
892 | *output = out; | 955 | *output = out; |
... | @@ -896,7 +959,7 @@ util_base64_encode (const unsigned char *input, size_t input_len, | ... | @@ -896,7 +959,7 @@ util_base64_encode (const unsigned char *input, size_t input_len, |
896 | *out++ = b64tab[((input[0] << 4) & 0x30) | (input[1] >> 4)]; | 959 | *out++ = b64tab[((input[0] << 4) & 0x30) | (input[1] >> 4)]; |
897 | *out++ = b64tab[((input[1] << 2) & 0x3c) | (input[2] >> 6)]; | 960 | *out++ = b64tab[((input[1] << 2) & 0x3c) | (input[2] >> 6)]; |
898 | *out++ = b64tab[input[2] & 0x3f]; | 961 | *out++ = b64tab[input[2] & 0x3f]; |
899 | olen -= 4; | 962 | olen -= 4; |
900 | input_len -= 3; | 963 | input_len -= 3; |
901 | input += 3; | 964 | input += 3; |
902 | } | 965 | } |
... | @@ -917,17 +980,17 @@ util_base64_encode (const unsigned char *input, size_t input_len, | ... | @@ -917,17 +980,17 @@ util_base64_encode (const unsigned char *input, size_t input_len, |
917 | 980 | ||
918 | int | 981 | int |
919 | util_base64_decode (const unsigned char *input, size_t input_len, | 982 | util_base64_decode (const unsigned char *input, size_t input_len, |
920 | unsigned char **output, size_t *output_len) | 983 | unsigned char **output, size_t * output_len) |
921 | { | 984 | { |
922 | static int b64val[128] = { | 985 | static int b64val[128] = { |
923 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | 986 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
924 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | 987 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
925 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, | 988 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, |
926 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, | 989 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, |
927 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, | 990 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
928 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, | 991 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, |
929 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, | 992 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, |
930 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 | 993 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 |
931 | }; | 994 | }; |
932 | int olen = input_len; | 995 | int olen = input_len; |
933 | unsigned char *out = malloc (olen); | 996 | unsigned char *out = malloc (olen); |
... | @@ -940,7 +1003,8 @@ util_base64_decode (const unsigned char *input, size_t input_len, | ... | @@ -940,7 +1003,8 @@ util_base64_decode (const unsigned char *input, size_t input_len, |
940 | if (input[0] > 127 || b64val[input[0]] == -1 | 1003 | if (input[0] > 127 || b64val[input[0]] == -1 |
941 | || input[1] > 127 || b64val[input[1]] == -1 | 1004 | || input[1] > 127 || b64val[input[1]] == -1 |
942 | || input[2] > 127 || ((input[2] != '=') && (b64val[input[2]] == -1)) | 1005 | || input[2] > 127 || ((input[2] != '=') && (b64val[input[2]] == -1)) |
943 | || input[3] > 127 || ((input[3] != '=') && (b64val[input[3]] == -1))) | 1006 | || input[3] > 127 || ((input[3] != '=') |
1007 | && (b64val[input[3]] == -1))) | ||
944 | return -1; | 1008 | return -1; |
945 | *out++ = (b64val[input[0]] << 2) | (b64val[input[1]] >> 4); | 1009 | *out++ = (b64val[input[0]] << 2) | (b64val[input[1]] >> 4); |
946 | if (input[2] != '=') | 1010 | if (input[2] != '=') |
... | @@ -968,7 +1032,7 @@ util_localname () | ... | @@ -968,7 +1032,7 @@ util_localname () |
968 | int name_len = 256; | 1032 | int name_len = 256; |
969 | int status = 1; | 1033 | int status = 1; |
970 | struct hostent *hp; | 1034 | struct hostent *hp; |
971 | 1035 | ||
972 | name = malloc (name_len); | 1036 | name = malloc (name_len); |
973 | while (name | 1037 | while (name |
974 | && (status = gethostname (name, name_len)) == 0 | 1038 | && (status = gethostname (name, name_len)) == 0 |
... | @@ -981,19 +1045,19 @@ util_localname () | ... | @@ -981,19 +1045,19 @@ util_localname () |
981 | { | 1045 | { |
982 | syslog (LOG_CRIT, _("Can't find out my own hostname")); | 1046 | syslog (LOG_CRIT, _("Can't find out my own hostname")); |
983 | exit (1); | 1047 | exit (1); |
984 | } | 1048 | } |
985 | 1049 | ||
986 | hp = gethostbyname (name); | 1050 | hp = gethostbyname (name); |
987 | if (hp) | 1051 | if (hp) |
988 | { | 1052 | { |
989 | struct in_addr inaddr; | 1053 | struct in_addr inaddr; |
990 | inaddr.s_addr = *(unsigned int*)hp->h_addr; | 1054 | inaddr.s_addr = *(unsigned int *) hp->h_addr; |
991 | hp = gethostbyaddr ((const char *)&inaddr, | 1055 | hp = gethostbyaddr ((const char *) &inaddr, |
992 | sizeof (struct in_addr), AF_INET); | 1056 | sizeof (struct in_addr), AF_INET); |
993 | if (hp) | 1057 | if (hp) |
994 | { | 1058 | { |
995 | free (name); | 1059 | free (name); |
996 | name = strdup ((char *)hp->h_name); | 1060 | name = strdup ((char *) hp->h_name); |
997 | } | 1061 | } |
998 | } | 1062 | } |
999 | localname = name; | 1063 | localname = name; |
... | @@ -1009,7 +1073,7 @@ util_wcard_match (const char *string, const char *pattern, const char *delim) | ... | @@ -1009,7 +1073,7 @@ util_wcard_match (const char *string, const char *pattern, const char *delim) |
1009 | const char *p = pattern, *n = string; | 1073 | const char *p = pattern, *n = string; |
1010 | char c; | 1074 | char c; |
1011 | 1075 | ||
1012 | for (;(c = *p++) != '\0' && *n; n++) | 1076 | for (; (c = *p++) != '\0' && *n; n++) |
1013 | { | 1077 | { |
1014 | switch (c) | 1078 | switch (c) |
1015 | { | 1079 | { |
... | @@ -1071,3 +1135,48 @@ util_uidvalidity (mailbox_t smbox, unsigned long *uidvp) | ... | @@ -1071,3 +1135,48 @@ util_uidvalidity (mailbox_t smbox, unsigned long *uidvp) |
1071 | smbox = mbox; | 1135 | smbox = mbox; |
1072 | return mailbox_uidvalidity (smbox, uidvp); | 1136 | return mailbox_uidvalidity (smbox, uidvp); |
1073 | } | 1137 | } |
1138 | |||
1139 | |||
1140 | void | ||
1141 | util_setio (int infile, int outfile) | ||
1142 | { | ||
1143 | ifile = fdopen (infile, "r"); | ||
1144 | ofile = fdopen (outfile, "w"); | ||
1145 | if (!ofile || !ifile) | ||
1146 | imap4d_bye (ERR_NO_OFILE); | ||
1147 | |||
1148 | setvbuf (ofile, NULL, _IOLBF, 0); | ||
1149 | } | ||
1150 | |||
1151 | void | ||
1152 | util_flush_output () | ||
1153 | { | ||
1154 | if (!tls_done) | ||
1155 | fflush (ofile); | ||
1156 | } | ||
1157 | |||
1158 | FILE * | ||
1159 | util_is_ofile () | ||
1160 | { | ||
1161 | return ofile; | ||
1162 | } | ||
1163 | |||
1164 | #ifdef WITH_TLS | ||
1165 | |||
1166 | int | ||
1167 | imap4d_init_tls_server () | ||
1168 | { | ||
1169 | sfile = | ||
1170 | (gnutls_session) mu_init_tls_server (fileno (ifile), fileno (ofile)); | ||
1171 | if (!sfile) | ||
1172 | return 0; | ||
1173 | return 1; | ||
1174 | } | ||
1175 | |||
1176 | void | ||
1177 | imap4d_deinit_tls_server () | ||
1178 | { | ||
1179 | mu_deinit_tls_server (sfile); | ||
1180 | } | ||
1181 | |||
1182 | #endif /* WITH_TLS */ | ... | ... |
-
Please register or sign in to post a comment