summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Monnerat <patrick@monnerat.net>2022-09-28 18:12:15 +0200
committerDaniel Stenberg <daniel@haxx.se>2022-09-29 10:51:04 +0200
commit2437fac01387e2653b8fae785335dc2744bab75a (patch)
tree76fff79cdfb4599831aac26c2bbf390529137cc4
parent75670e457367515dc88cf43f7a4b9ddb9c5ab59e (diff)
downloadcurl-2437fac01387e2653b8fae785335dc2744bab75a.tar.gz
lib: sanitize conditional exclusion around MIME
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
-rw-r--r--docs/cmdline-opts/header.d41
-rw-r--r--docs/libcurl/opts/CURLOPT_HTTPHEADER.338
-rw-r--r--lib/mime.c9
-rw-r--r--lib/mime.h5
-rw-r--r--lib/setopt.c58
-rw-r--r--src/tool_listhelp.c2
-rw-r--r--tests/data/test15903
7 files changed, 101 insertions, 55 deletions
diff --git a/docs/cmdline-opts/header.d b/docs/cmdline-opts/header.d
index a7841edb3..9bf865345 100644
--- a/docs/cmdline-opts/header.d
+++ b/docs/cmdline-opts/header.d
@@ -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.
diff --git a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
index c6cf055e1..3458d9203 100644
--- a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
+++ b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
@@ -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)"
diff --git a/lib/mime.c b/lib/mime.c
index 11e614dc3..042141fc8 100644
--- a/lib/mime.c
+++ b/lib/mime.c
@@ -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)
diff --git a/lib/mime.h b/lib/mime.h
index fe1a61c06..bafde29f4 100644
--- a/lib/mime.h
+++ b/lib/mime.h
@@ -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);
diff --git a/lib/setopt.c b/lib/setopt.c
index bc98d199f..5b5975485 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -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],
diff --git a/src/tool_listhelp.c b/src/tool_listhelp.c
index f3217be61..6a2d10fb6 100644
--- a/src/tool_listhelp.c
+++ b/src/tool_listhelp.c
@@ -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},
diff --git a/tests/data/test1590 b/tests/data/test1590
index bfaa7545c..dbb81cc29 100644
--- a/tests/data/test1590
+++ b/tests/data/test1590
@@ -28,6 +28,9 @@ body
#
# Client-side
<client>
+<features>
+Mime
+</features>
<server>
imap
</server>