From 64c19759bfa6820bd67b47d659ea7241f2efbd9b Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Fri, 9 Nov 2001 00:41:09 +0000 Subject: Now takes a command-length argument so we can 1) avoid duping the command 2001-11-06 Jeffrey Stedfast * providers/imap/camel-imap-command.c (camel_imap_command_continuation): Now takes a command-length argument so we can 1) avoid duping the command string yet again, yay. 2) we now don't have to worry about embedded nul-chars screwing us over (we still need to avoid allowing them into the string but at least now it won't mess us up). * providers/imap/camel-imap-folder.c (do_append): Instead of appending a nul char to the end of the byte array and then passing that off as if it were a string to camel_imap_command_continuation, instead pass the byte-array length since that function now takes a length argument. Yay. Also encode any 8bit parts to avoid the possibility of sending embedded nul chars to the imap server. * providers/imap/camel-imap-store.c (try_auth): Updated to pass a command-length argument to camel_imap_command_continuation(). svn path=/trunk/; revision=14637 --- camel/ChangeLog | 20 ++++++++++++++++++++ camel/providers/imap/camel-imap-command.c | 21 ++++++++++++++++++--- camel/providers/imap/camel-imap-command.h | 1 + camel/providers/imap/camel-imap-folder.c | 30 +++++++++++++++++------------- camel/providers/imap/camel-imap-store.c | 23 +++++++++++------------ 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index 02e6a9ec8f..0d5a91551c 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,23 @@ +2001-11-06 Jeffrey Stedfast + + * providers/imap/camel-imap-command.c + (camel_imap_command_continuation): Now takes a command-length + argument so we can 1) avoid duping the command string yet again, + yay. 2) we now don't have to worry about embedded nul-chars + screwing us over (we still need to avoid allowing them into the + string but at least now it won't mess us up). + + * providers/imap/camel-imap-folder.c (do_append): Instead of + appending a nul char to the end of the byte array and then passing + that off as if it were a string to + camel_imap_command_continuation, instead pass the byte-array + length since that function now takes a length argument. Yay. Also + encode any 8bit parts to avoid the possibility of sending embedded + nul chars to the imap server. + + * providers/imap/camel-imap-store.c (try_auth): Updated to pass a + command-length argument to camel_imap_command_continuation(). + 2001-11-07 Jeffrey Stedfast * camel-tcp-stream-ssl.c (save_ssl_cert): Oops, pass a mode diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c index 5dd4206841..5639741a42 100644 --- a/camel/providers/imap/camel-imap-command.c +++ b/camel/providers/imap/camel-imap-command.c @@ -198,6 +198,7 @@ imap_command_start (CamelImapStore *store, CamelFolder *folder, * camel_imap_command_continuation: * @store: the IMAP store * @cmd: buffer containing the response/request data + * @cmdlen: command length * @ex: a CamelException * * This method is for sending continuing responses to the IMAP server @@ -211,10 +212,24 @@ imap_command_start (CamelImapStore *store, CamelFolder *folder, **/ CamelImapResponse * camel_imap_command_continuation (CamelImapStore *store, const char *cmd, - CamelException *ex) + size_t cmdlen, CamelException *ex) { - if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex, - "%s\r\n", cmd) < 0) { + CamelStream *stream; + + if (!camel_remote_store_connected (CAMEL_REMOTE_STORE (store), ex)) + return NULL; + + stream = CAMEL_REMOTE_STORE (store)->ostream; + + if (camel_stream_write (stream, cmd, cmdlen) == -1 || + camel_stream_write (stream, "\r\n", 2) == -1) { + if (errno == EINTR) + camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, + _("Operation cancelled")); + else + camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, + g_strerror (errno)); + camel_service_disconnect (CAMEL_SERVICE (store), FALSE, NULL); CAMEL_IMAP_STORE_UNLOCK (store, command_lock); return NULL; } diff --git a/camel/providers/imap/camel-imap-command.h b/camel/providers/imap/camel-imap-command.h index 69c28237cc..3539ac63d2 100644 --- a/camel/providers/imap/camel-imap-command.h +++ b/camel/providers/imap/camel-imap-command.h @@ -54,6 +54,7 @@ CamelImapResponse *camel_imap_command (CamelImapStore *store, const char *fmt, ...); CamelImapResponse *camel_imap_command_continuation (CamelImapStore *store, const char *cmd, + size_t cmdlen, CamelException *ex); void camel_imap_response_free (CamelImapStore *store, diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 67b515ec93..dcd33ad224 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -939,29 +939,33 @@ do_append (CamelFolder *folder, CamelMimeMessage *message, CamelStreamFilter *streamfilter; GByteArray *ba; char *flagstr, *result, *end; - + /* create flag string param */ if (info && info->flags) flagstr = imap_create_flag_list (info->flags); else flagstr = NULL; - + + /* encode any 8bit parts so we avoid sending embedded nul-chars and such */ + /* commented out because it might change the encoding on + signed parts which'd break stuff */ + /*camel_mime_message_encode_8bit_parts (message);*/ + /* FIXME: We could avoid this if we knew how big the message was. */ memstream = camel_stream_mem_new (); ba = g_byte_array_new (); camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (memstream), ba); - + streamfilter = camel_stream_filter_new_with_stream (memstream); - crlf_filter = camel_mime_filter_crlf_new ( - CAMEL_MIME_FILTER_CRLF_ENCODE, - CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY); + crlf_filter = camel_mime_filter_crlf_new (CAMEL_MIME_FILTER_CRLF_ENCODE, + CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY); camel_stream_filter_add (streamfilter, crlf_filter); camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), CAMEL_STREAM (streamfilter)); camel_object_unref (CAMEL_OBJECT (streamfilter)); camel_object_unref (CAMEL_OBJECT (crlf_filter)); camel_object_unref (CAMEL_OBJECT (memstream)); - + response = camel_imap_command (store, NULL, ex, "APPEND %F%s%s {%d}", folder->full_name, flagstr ? " " : "", flagstr ? flagstr : "", ba->len); @@ -971,27 +975,27 @@ do_append (CamelFolder *folder, CamelMimeMessage *message, g_byte_array_free (ba, TRUE); return NULL; } + result = camel_imap_response_extract_continuation (store, response, ex); if (!result) { g_byte_array_free (ba, TRUE); return NULL; } g_free (result); - + /* send the rest of our data - the mime message */ - g_byte_array_append (ba, "\0", 3); - response = camel_imap_command_continuation (store, ba->data, ex); + response = camel_imap_command_continuation (store, ba->data, ba->len, ex); g_byte_array_free (ba, TRUE); if (!response) return response; - + if (store->capabilities & IMAP_CAPABILITY_UIDPLUS) { *uid = strstrcase (response->status, "[APPENDUID "); if (*uid) *uid = strchr (*uid + 11, ' '); if (*uid) { *uid = g_strndup (*uid + 1, strcspn (*uid + 1, "]")); - /* Make sure it's a number */ + /* Make sure it's a number */ if (strtoul (*uid, &end, 10) == 0 || *end) { g_free (*uid); *uid = NULL; @@ -999,7 +1003,7 @@ do_append (CamelFolder *folder, CamelMimeMessage *message, } } else *uid = NULL; - + return response; } diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 1ef9b6edad..0811061280 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -446,31 +446,30 @@ try_auth (CamelImapStore *store, const char *mech, CamelException *ex) CamelImapResponse *response; char *resp; char *sasl_resp; - + CAMEL_IMAP_STORE_ASSERT_LOCKED (store, command_lock); - - response = camel_imap_command (store, NULL, ex, - "AUTHENTICATE %s", mech); + + response = camel_imap_command (store, NULL, ex, "AUTHENTICATE %s", mech); if (!response) return FALSE; - + sasl = camel_sasl_new ("imap", mech, CAMEL_SERVICE (store)); while (!camel_sasl_authenticated (sasl)) { resp = camel_imap_response_extract_continuation (store, response, ex); if (!resp) goto lose; - + sasl_resp = camel_sasl_challenge_base64 (sasl, resp + 2, ex); g_free (resp); if (camel_exception_is_set (ex)) goto break_and_lose; - - response = camel_imap_command_continuation (store, sasl_resp, ex); + + response = camel_imap_command_continuation (store, sasl_resp, strlen (sasl_resp), ex); g_free (sasl_resp); if (!response) goto lose; } - + resp = camel_imap_response_extract_continuation (store, response, NULL); if (resp) { /* Oops. SASL claims we're done, but the IMAP server @@ -483,13 +482,13 @@ try_auth (CamelImapStore *store, const char *mech, CamelException *ex) camel_object_unref (CAMEL_OBJECT (sasl)); return TRUE; - + break_and_lose: /* Get the server out of "waiting for continuation data" mode. */ - response = camel_imap_command_continuation (store, "*", NULL); + response = camel_imap_command_continuation (store, "*", 1, NULL); if (response) camel_imap_response_free (store, response); - + lose: if (!camel_exception_is_set (ex)) { camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, -- cgit