]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
lib: sanitize conditional exclusion around MIME
authorPatrick Monnerat <patrick@monnerat.net>
Wed, 28 Sep 2022 16:12:15 +0000 (18:12 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 29 Sep 2022 08:51:04 +0000 (10:51 +0200)
The introduction of CURL_DISABLE_MIME came with some additional bugs:
- Disabled MIME is compiled-in anyway if SMTP and/or IMAP is enabled.
- CURLOPT_MIMEPOST, CURLOPT_MIME_OPTIONS and CURLOPT_HTTPHEADER are
  conditioned on HTTP, although also needed for SMTP and IMAP MIME mail
  uploads.

In addition, the CURLOPT_HTTPHEADER and --header documentation does not
mention their use for MIME mail.

This commit fixes the problems above.

Closes #9610

docs/cmdline-opts/header.d
docs/libcurl/opts/CURLOPT_HTTPHEADER.3
lib/mime.c
lib/mime.h
lib/setopt.c
src/tool_listhelp.c
tests/data/test1590

index a7841edb368baf8f5067a8ddfc424d8883705c9b..9bf86534574703bce2ca70fa010a2a96e289aad8 100644 (file)
@@ -4,7 +4,7 @@ Long: header
 Short: H
 Arg: <header/@file>
 Help: Pass custom header(s) to server
-Protocols: HTTP
+Protocols: HTTP IMAP SMTP
 Category: http
 See-also: user-agent referer
 Example: -H "X-First-Name: Joe" $URL
@@ -12,16 +12,22 @@ Example: -H "User-Agent: yes-please/2000" $URL
 Example: -H "Host:" $URL
 Added: 5.0
 ---
-Extra header to include in the request when sending HTTP to a server. You may
-specify any number of extra headers. Note that if you should add a custom
-header that has the same name as one of the internal ones curl would use, your
-externally set header will be used instead of the internal one. This allows
-you to make even trickier stuff than curl would normally do. You should not
-replace internally set headers without knowing perfectly well what you are
-doing. Remove an internal header by giving a replacement without content on
-the right side of the colon, as in: -H "Host:". If you send the custom
-header with no-value then its header must be terminated with a semicolon, such
-as \-H "X-Custom-Header;" to send "X-Custom-Header:".
+Extra header to include in information sent. When used within an HTTP request,
+it is added to the regular request headers.
+
+For an IMAP or SMTP MIME uploaded mail built with --form options, it is
+prepended to the resulting MIME document, effectively incuding it at the mail
+global level. It does not affect raw uploaded mails (Added in 7.56.0).
+
+You may specify any number of extra headers. Note that if you should add a
+custom header that has the same name as one of the internal ones curl would
+use, your externally set header will be used instead of the internal one.
+This allows you to make even trickier stuff than curl would normally do. You
+should not replace internally set headers without knowing perfectly well what
+you are doing. Remove an internal header by giving a replacement without
+content on the right side of the colon, as in: -H "Host:". If you send the
+custom header with no-value then its header must be terminated with a
+semicolon, such as \-H "X-Custom-Header;" to send "X-Custom-Header:".
 
 curl will make sure that each header you add/replace is sent with the proper
 end-of-line marker, you should thus **not** add that as a part of the header
@@ -32,15 +38,20 @@ This option can take an argument in @filename style, which then adds a header
 for each line in the input file. Using @- will make curl read the header file
 from stdin. Added in 7.55.0.
 
+Please note that most anti-spam utilities check the presence and value of
+several MIME mail headers: these are "From:", "To:", "Date:" and "Subject:"
+among others and should be added with this option.
+
 You need --proxy-header to send custom headers intended for an HTTP
 proxy. Added in 7.37.0.
 
 Passing on a "Transfer-Encoding: chunked" header when doing an HTTP request
 with a request body, will make curl send the data using chunked encoding.
 
-**WARNING**: headers set with this option will be set in all requests - even
-after redirects are followed, like when told with --location. This can lead to
-the header being sent to other hosts than the original host, so sensitive
-headers should be used with caution combined with following redirects.
+**WARNING**: headers set with this option will be set in all HTTP requests
+- even after redirects are followed, like when told with --location. This can
+lead to the header being sent to other hosts than the original host, so
+sensitive headers should be used with caution combined with following
+redirects.
 
 This option can be used multiple times to add/replace/remove multiple headers.
index c6cf055e1c565917830b2cf7bc335095a16ad017..3458d9203192840c6df7703dadcba4004546ad0c 100644 (file)
@@ -37,6 +37,11 @@ Pass a pointer to a linked list of HTTP headers to pass to the server and/or
 proxy in your HTTP request. The same list can be used for both host and proxy
 requests!
 
+When used within an IMAP or SMTP request to upload a MIME mail, the given
+header list establishes the document-level MIME headers to prepend to the
+uploaded document described by \fICURLOPT_MIMEPOST(3)\fP. This does not affect
+raw mail uploads.
+
 The linked list should be a fully valid list of \fBstruct curl_slist\fP
 structs properly filled in. Use \fIcurl_slist_append(3)\fP to create the list
 and \fIcurl_slist_free_all(3)\fP to clean up an entire list. If you add a
@@ -52,8 +57,8 @@ because libcurl adds CRLF after each header item. Failure to comply with this
 will result in strange bugs because the server will most likely ignore part of
 the headers you specified.
 
-The first line in a request (containing the method, usually a GET or POST) is
-not a header and cannot be replaced using this option. Only the lines
+The first line in an HTTP request (containing the method, usually a GET or
+POST) is not a header and cannot be replaced using this option. Only the lines
 following the request-line are headers. Adding this method line in this list
 of headers will only cause your request to send an invalid header. Use
 \fICURLOPT_CUSTOMREQUEST(3)\fP to change the method.
@@ -65,14 +70,14 @@ the list.
 
 Pass a NULL to this option to reset back to no custom headers.
 
-The most commonly replaced headers have "shortcuts" in the options
+The most commonly replaced HTTP headers have "shortcuts" in the options
 \fICURLOPT_COOKIE(3)\fP, \fICURLOPT_USERAGENT(3)\fP and
 \fICURLOPT_REFERER(3)\fP. We recommend using those.
 
 There's an alternative option that sets or replaces headers only for requests
 that are sent with CONNECT to a proxy: \fICURLOPT_PROXYHEADER(3)\fP. Use
 \fICURLOPT_HEADEROPT(3)\fP to control the behavior.
-.SH SPECIFIC HEADERS
+.SH SPECIFIC HTTP HEADERS
 Setting some specific headers will cause libcurl to act differently.
 .IP "Host:"
 The specified host name will be used for cookie matching if the cookie engine
@@ -82,6 +87,24 @@ field and Host: will not be sent at all over the wire.
 .IP "Transfer-Encoding: chunked"
 Tells libcurl the upload is to be done using this chunked encoding instead of
 providing the Content-Length: field in the request.
+.SH SPECIFIC MIME HEADERS
+When used to build a MIME e-mail for IMAP or SMTP, the following
+document-level headers can be set to override libcurl-generated values:
+.IP "Mime-Version:"
+Tells the parser at the receiving site how to interpret the MIME framing.
+It defaults to "1.0" and should normally not be altered.
+.IP "Content-Type:"
+Indicates the document's global structure type. By default, libcurl sets it
+to "multipart/mixed", describing a document made of independent parts. When a
+MIME mail is only composed of alternative representations of the same data
+(i.e.: HTML and plain text), this header must be set to "multipart/alternative".
+In all cases the value must be of the form "multipart/*" to respect the
+document structure and may not include the "boundary=" parameter.
+.P
+Other specific headers that do not have a libcurl default value but are
+strongly desired by mail delivery and user agents should also be included.
+These are "From:", "To:", "Date:" and "Subject:" among others and their
+presence and value is generally checked by anti-spam utilities.
 .SH SECURITY CONCERNS
 By default, this option makes libcurl send the given headers in all HTTP
 requests done by this handle. You should therefore use this option with
@@ -108,7 +131,7 @@ permitted with the \fICURLOPT_UNRESTRICTED_AUTH(3)\fP option.
 .SH DEFAULT
 NULL
 .SH PROTOCOLS
-HTTP
+HTTP, IMAP and SMTP
 .SH EXAMPLE
 .nf
 CURL *curl = curl_easy_init();
@@ -130,9 +153,10 @@ if(curl) {
 .fi
 
 .SH AVAILABILITY
-As long as HTTP is enabled
+As long as HTTP is enabled. Use in MIME mail added in 7.56.0.
 .SH RETURN VALUE
 Returns CURLE_OK if HTTP is supported, and CURLE_UNKNOWN_OPTION if not.
 .SH "SEE ALSO"
 .BR CURLOPT_CUSTOMREQUEST "(3), " CURLOPT_HEADEROPT "(3), "
-.BR CURLOPT_PROXYHEADER "(3), " CURLOPT_HEADER "(3)"
+.BR CURLOPT_PROXYHEADER "(3), " CURLOPT_HEADER "(3), "
+.BR CURLOPT_MIMEPOST "(3), " curl_mime_init "(3)"
index 11e614dc3253339b780968b2ead0e585b3628c09..042141fc80b19598212d1f1f3ac8bacd378a02f7 100644 (file)
@@ -31,8 +31,9 @@
 #include "urldata.h"
 #include "sendf.h"
 
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
-  !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
+#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) ||      \
+                                    !defined(CURL_DISABLE_SMTP) ||      \
+                                    !defined(CURL_DISABLE_IMAP))
 
 #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
 #include <libgen.h>
@@ -1924,8 +1925,8 @@ void Curl_mime_unpause(curl_mimepart *part)
 }
 
 
-#else /* !CURL_DISABLE_HTTP && !CURL_DISABLE_MIME ||
-         !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
+#else /* !CURL_DISABLE_MIME && (!CURL_DISABLE_HTTP ||
+                                !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP) */
 
 /* Mime not compiled in: define stubs for externally-referenced functions. */
 curl_mime *curl_mime_init(CURL *easy)
index fe1a61c0609d4207227312e46f3a4eb72a24a3cd..bafde29f4006cb2fe552310bd21673b0d2cd2cb4 100644 (file)
@@ -134,8 +134,9 @@ struct curl_mimepart {
 
 CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
 
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) ||     \
-  !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
+#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) ||      \
+                                    !defined(CURL_DISABLE_SMTP) ||      \
+                                    !defined(CURL_DISABLE_IMAP))
 
 /* Prototypes. */
 void Curl_mime_initpart(struct curl_mimepart *part, struct Curl_easy *easy);
index bc98d199f8c5de499ca7b8e8432c0f6ee2e82082..5b5975485c6423ebd3f55d62c1cba8b7cc032b2a 100644 (file)
@@ -654,6 +654,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     data->set.upload = FALSE;
     break;
 
+#ifndef CURL_DISABLE_MIME
   case CURLOPT_HTTPPOST:
     /*
      * Set to make us do HTTP POST
@@ -662,6 +663,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     data->set.method = HTTPREQ_POST_FORM;
     data->set.opt_no_body = FALSE; /* this is implied */
     break;
+#endif
 
   case CURLOPT_AWS_SIGV4:
     /*
@@ -677,18 +679,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
       data->set.httpauth = CURLAUTH_AWS_SIGV4;
     break;
 
-  case CURLOPT_MIMEPOST:
-    /*
-     * Set to make us do MIME/form POST
-     */
-    result = Curl_mime_set_subparts(&data->set.mimepost,
-                                    va_arg(param, curl_mime *), FALSE);
-    if(!result) {
-      data->set.method = HTTPREQ_POST_MIME;
-      data->set.opt_no_body = FALSE; /* this is implied */
-    }
-    break;
-
   case CURLOPT_REFERER:
     /*
      * String to set in the HTTP Referer: field.
@@ -710,13 +700,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
                             va_arg(param, char *));
     break;
 
-  case CURLOPT_HTTPHEADER:
-    /*
-     * Set a list with HTTP headers to use (or replace internals with)
-     */
-    data->set.headers = va_arg(param, struct curl_slist *);
-    break;
-
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXYHEADER:
     /*
@@ -954,6 +937,36 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     break;
 #endif   /* CURL_DISABLE_HTTP */
 
+#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) ||       \
+    !defined(CURL_DISABLE_IMAP)
+# if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MIME)
+  case CURLOPT_HTTPHEADER:
+    /*
+     * Set a list with HTTP headers to use (or replace internals with)
+     */
+    data->set.headers = va_arg(param, struct curl_slist *);
+    break;
+# endif
+
+# ifndef CURL_DISABLE_MIME
+  case CURLOPT_MIMEPOST:
+    /*
+     * Set to make us do MIME POST
+     */
+    result = Curl_mime_set_subparts(&data->set.mimepost,
+                                    va_arg(param, curl_mime *), FALSE);
+    if(!result) {
+      data->set.method = HTTPREQ_POST_MIME;
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    break;
+
+  case CURLOPT_MIME_OPTIONS:
+    data->set.mime_options = (unsigned int)va_arg(param, long);
+    break;
+# endif
+#endif
+
   case CURLOPT_HTTPAUTH:
     /*
      * Set HTTP Authentication type BITMASK.
@@ -2659,13 +2672,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     break;
 #endif
 
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
-  !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
-  case CURLOPT_MIME_OPTIONS:
-    data->set.mime_options = (unsigned int)va_arg(param, long);
-    break;
-#endif
-
   case CURLOPT_SASL_AUTHZID:
     /* Authorization identity (identity to act as) */
     result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
index f3217be619c292e06826743ba099527ffd789a3c..6a2d10fb69a53d85bedd67262b1f0568db6d4841 100644 (file)
@@ -251,7 +251,7 @@ const struct helptxt helptext[] = {
    CURLHELP_HTTP | CURLHELP_FTP | CURLHELP_FILE},
   {"-H, --header <header/@file>",
    "Pass custom header(s) to server",
-   CURLHELP_HTTP},
+   CURLHELP_HTTP | CURLHELP_IMAP | CURLHELP_SMTP},
   {"-h, --help <category>",
    "Get help for commands",
    CURLHELP_IMPORTANT | CURLHELP_CURL},
index bfaa7545c990ffb0a341a7009be86657269863f4..dbb81cc29f503a756d47ad9ddd11cbaff42dad53 100644 (file)
@@ -28,6 +28,9 @@ body
 #
 # Client-side
 <client>
+<features>
+Mime
+</features>
 <server>
 imap
 </server>