00001 /*************************************************************************** 00002 * _ _ ____ _ 00003 * Project ___| | | | _ \| | 00004 * / __| | | | |_) | | 00005 * | (__| |_| | _ <| |___ 00006 * \___|\___/|_| \_\_____| 00007 * 00008 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. 00009 * 00010 * This software is licensed as described in the file COPYING, which 00011 * you should have received as part of this distribution. The terms 00012 * are also available at https://curl.haxx.se/docs/copyright.html. 00013 * 00014 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 00015 * copies of the Software, and permit persons to whom the Software is 00016 * furnished to do so, under the terms of the COPYING file. 00017 * 00018 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 00019 * KIND, either express or implied. 00020 * 00021 ***************************************************************************/ 00022 00023 /* <DESC> 00024 * SMTP example using TLS 00025 * </DESC> 00026 */ 00027 00028 #include <stdio.h> 00029 #include <string.h> 00030 #include <curl/curl.h> 00031 00032 /* This is a simple example showing how to send mail using libcurl's SMTP 00033 * capabilities. It builds on the smtp-mail.c example to add authentication 00034 * and, more importantly, transport security to protect the authentication 00035 * details from being snooped. 00036 * 00037 * Note that this example requires libcurl 7.20.0 or above. 00038 */ 00039 00040 #define FROM "<sender@example.org>" 00041 #define TO "<addressee@example.net>" 00042 #define CC "<info@example.org>" 00043 00044 static const char *payload_text[] = { 00045 "Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n", 00046 "To: " TO "\r\n", 00047 "From: " FROM "(Example User)\r\n", 00048 "Cc: " CC "(Another example User)\r\n", 00049 "Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@" 00050 "rfcpedant.example.org>\r\n", 00051 "Subject: SMTP TLS example message\r\n", 00052 "\r\n", /* empty line to divide headers from body, see RFC5322 */ 00053 "The body of the message starts here.\r\n", 00054 "\r\n", 00055 "It could be a lot of lines, could be MIME encoded, whatever.\r\n", 00056 "Check RFC5322.\r\n", 00057 NULL 00058 }; 00059 00060 struct upload_status { 00061 int lines_read; 00062 }; 00063 00064 static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp) 00065 { 00066 struct upload_status *upload_ctx = (struct upload_status *)userp; 00067 const char *data; 00068 00069 if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) { 00070 return 0; 00071 } 00072 00073 data = payload_text[upload_ctx->lines_read]; 00074 00075 if(data) { 00076 size_t len = strlen(data); 00077 memcpy(ptr, data, len); 00078 upload_ctx->lines_read++; 00079 00080 return len; 00081 } 00082 00083 return 0; 00084 } 00085 00086 int main(void) 00087 { 00088 CURL *curl; 00089 CURLcode res = CURLE_OK; 00090 struct curl_slist *recipients = NULL; 00091 struct upload_status upload_ctx; 00092 00093 upload_ctx.lines_read = 0; 00094 00095 curl = curl_easy_init(); 00096 if(curl) { 00097 /* Set username and password */ 00098 curl_easy_setopt(curl, CURLOPT_USERNAME, "user"); 00099 curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret"); 00100 00101 /* This is the URL for your mailserver. Note the use of port 587 here, 00102 * instead of the normal SMTP port (25). Port 587 is commonly used for 00103 * secure mail submission (see RFC4403), but you should use whatever 00104 * matches your server configuration. */ 00105 curl_easy_setopt(curl, CURLOPT_URL, "smtp://mainserver.example.net:587"); 00106 00107 /* In this example, we'll start with a plain text connection, and upgrade 00108 * to Transport Layer Security (TLS) using the STARTTLS command. Be careful 00109 * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer 00110 * will continue anyway - see the security discussion in the libcurl 00111 * tutorial for more details. */ 00112 curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); 00113 00114 /* If your server doesn't have a valid certificate, then you can disable 00115 * part of the Transport Layer Security protection by setting the 00116 * CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false). 00117 * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 00118 * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 00119 * That is, in general, a bad idea. It is still better than sending your 00120 * authentication details in plain text though. Instead, you should get 00121 * the issuer certificate (or the host certificate if the certificate is 00122 * self-signed) and add it to the set of certificates that are known to 00123 * libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See docs/SSLCERTS 00124 * for more information. */ 00125 curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem"); 00126 00127 /* Note that this option isn't strictly required, omitting it will result 00128 * in libcurl sending the MAIL FROM command with empty sender data. All 00129 * autoresponses should have an empty reverse-path, and should be directed 00130 * to the address in the reverse-path which triggered them. Otherwise, 00131 * they could cause an endless loop. See RFC 5321 Section 4.5.5 for more 00132 * details. 00133 */ 00134 curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM); 00135 00136 /* Add two recipients, in this particular case they correspond to the 00137 * To: and Cc: addressees in the header, but they could be any kind of 00138 * recipient. */ 00139 recipients = curl_slist_append(recipients, TO); 00140 recipients = curl_slist_append(recipients, CC); 00141 curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients); 00142 00143 /* We're using a callback function to specify the payload (the headers and 00144 * body of the message). You could just use the CURLOPT_READDATA option to 00145 * specify a FILE pointer to read from. */ 00146 curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source); 00147 curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx); 00148 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); 00149 00150 /* Since the traffic will be encrypted, it is very useful to turn on debug 00151 * information within libcurl to see what is happening during the transfer. 00152 */ 00153 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 00154 00155 /* Send the message */ 00156 res = curl_easy_perform(curl); 00157 00158 /* Check for errors */ 00159 if(res != CURLE_OK) 00160 fprintf(stderr, "curl_easy_perform() failed: %s\n", 00161 curl_easy_strerror(res)); 00162 00163 /* Free the list of recipients */ 00164 curl_slist_free_all(recipients); 00165 00166 /* Always cleanup */ 00167 curl_easy_cleanup(curl); 00168 } 00169 00170 return (int)res; 00171 }