38 #ifndef CURL_DISABLE_SMTP 40 #ifdef HAVE_NETINET_IN_H 41 #include <netinet/in.h> 43 #ifdef HAVE_ARPA_INET_H 44 #include <arpa/inet.h> 47 #include <sys/utsname.h> 57 #if (defined(NETWARE) && defined(__NOVELL_LIBC__)) 59 #define in_addr_t unsigned long 105 const char *initresp);
184 #define smtp_to_smtps(x) Curl_nop_stmt 209 if(line[3] ==
' ' || len == 5) {
218 else if(line[3] ==
'-' &&
236 char *message = NULL;
239 for(message = buffer + 4; *message ==
' ' || *message ==
'\t'; message++)
243 for(len = strlen(message); len--;)
244 if(message[len] !=
'\r' && message[len] !=
'\n' && message[len] !=
' ' &&
245 message[len] !=
'\t')
265 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) 267 static const char *
const names[] = {
284 if(smtpc->
state != newstate)
285 infof(conn->
data,
"SMTP %p state change from %s to %s\n",
286 (
void *)smtpc, names[smtpc->
state], names[newstate]);
289 smtpc->
state = newstate;
397 const char *initresp)
456 infof(conn->
data,
"No known authentication mechanisms supported!\n");
547 "Mime-Version: 1.0");
581 "MAIL FROM:%s", from);
582 else if(auth && !size)
584 "MAIL FROM:%s AUTH=%s", from, auth);
585 else if(auth && size)
587 "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size);
590 "MAIL FROM:%s SIZE=%s", from, size);
657 if(smtpcode/100 != 2) {
658 failf(data,
"Got unexpected smtp-server response: %d", smtpcode);
677 if(smtpcode != 220) {
679 failf(data,
"STARTTLS denied, code %d", smtpcode);
699 size_t len = strlen(line);
704 if(smtpcode/100 != 2 && smtpcode != 1) {
708 failf(data,
"Remote access denied: %d", smtpcode);
717 if(len >= 8 && !memcmp(line,
"STARTTLS", 8))
721 else if(len >= 4 && !memcmp(line,
"SIZE", 4))
725 else if(len >= 5 && !memcmp(line,
"AUTH ", 5)) {
735 unsigned int mechbit;
738 (*line ==
' ' || *line ==
'\t' ||
739 *line ==
'\r' || *line ==
'\n')) {
749 for(wordlen = 0; wordlen < len && line[wordlen] !=
' ' &&
750 line[wordlen] !=
'\t' && line[wordlen] !=
'\r' &&
751 line[wordlen] !=
'\n';)
756 if(mechbit && llen == wordlen)
774 failf(data,
"STARTTLS not supported.");
795 if(smtpcode/100 != 2) {
796 failf(data,
"Remote access denied: %d", smtpcode);
825 failf(data,
"Authentication cancelled");
843 size_t len = strlen(line);
847 if((smtp->
rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) ||
848 (!smtp->
rcpt && smtpcode/100 != 2 && smtpcode != 1)) {
849 failf(data,
"Command failed: %d", smtpcode);
890 if(smtpcode/100 != 2) {
891 failf(data,
"MAIL failed: %d", smtpcode);
911 if(smtpcode/100 != 2) {
912 failf(data,
"RCPT failed: %d", smtpcode);
942 if(smtpcode != 354) {
943 failf(data,
"DATA failed: %d", smtpcode);
1011 switch(smtpc->
state) {
1188 if(!smtp || !pp->
conn)
1192 connclose(conn,
"SMTP done with bad status");
1224 if(bytes_written != len) {
1229 pp->
sendleft = len - bytes_written;
1280 *dophase_done =
FALSE;
1386 else if(*dophase_done) {
1408 bool connected =
FALSE;
1424 if(!result && *dophase_done)
1462 while(!result && ptr && *ptr) {
1466 while(*ptr && *ptr !=
'=')
1471 while(*ptr && *ptr !=
';')
1476 value, ptr - value);
1546 char *newscratch = NULL;
1547 char *oldscratch = NULL;
1551 if(!scratch || data->
set.
crlf) {
1552 oldscratch = scratch;
1556 failf(data,
"Failed to alloc scratch buffer!");
1563 eob_sent = smtp->
eob;
1567 for(i = 0, si = 0; i < nread; i++) {
1577 else if(smtp->
eob) {
1580 si += smtp->
eob - eob_sent;
1607 if(smtp->
eob - eob_sent) {
1610 si += smtp->
eob - eob_sent;
#define SMTP_EOB_REPL_LEN
struct ssl_connect_data ssl[2]
static CURLcode smtp_perform_starttls(struct connectdata *conn)
CURLcode Curl_urldecode(struct Curl_easy *data, const char *string, size_t length, char **ostring, size_t *olen, bool reject_ctrl)
CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, struct curl_slist *headers, int take_ownership)
static CURLcode smtp_state_postdata_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
static CURLcode smtp_state_starttls_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
static CURLcode smtp_perform(struct connectdata *conn, bool *connected, bool *dophase_done)
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done)
int curlx_sltosi(long slnum)
#define PROTOPT_NOURLQUERY
CURLcode Curl_pp_disconnect(struct pingpong *pp)
static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
const struct Curl_handler Curl_handler_smtps
static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected)
static CURLcode smtp_state_helo_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks)
const struct Curl_handler * handler
UNITTEST_START char * ptr
const struct Curl_handler Curl_handler_smtp
curl_pp_transfer transfer
CURLcode Curl_pp_flushsend(struct pingpong *pp)
CURLcode Curl_mime_prepare_headers(curl_mimepart *part, const char *contenttype, const char *disposition, enum mimestrategy strategy)
static const struct SASLproto saslsmtp
#define Curl_ssl_connect_nonblocking(x, y, z)
void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params)
struct curl_slist * headers
static CURLcode smtp_parse_url_options(struct connectdata *conn)
UNITTEST_START int result
CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, bool force_ir, saslprogress *progress)
static srvr_sockaddr_union_t from
static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done)
CURLcode(* statemach_act)(struct connectdata *conn)
static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
memcpy(filename, filename1, strlen(filename1))
size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
void Curl_setup_transfer(struct connectdata *conn, int sockindex, curl_off_t size, bool getheader, curl_off_t *bytecountp, int writesockindex, curl_off_t *writecountp)
static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn)
struct curl_slist * mail_rcpt
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt,...)
bool(* endofresp)(struct connectdata *conn, char *ptr, size_t len, int *code)
CURLcode Curl_pp_statemach(struct pingpong *pp, bool block)
static CURLcode smtp_setup_connection(struct connectdata *conn)
CURLcode Curl_mime_rewind(curl_mimepart *part)
CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, int code, saslprogress *progress)
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn)
unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len)
static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len, int *resp)
#define strncasecompare(a, b, c)
void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
static CURLcode smtp_parse_custom_request(struct connectdata *conn)
void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
size_t(* curl_read_callback)(char *buffer, size_t size, size_t nitems, void *instream)
static CURLcode smtp_perform_authentication(struct connectdata *conn)
static CURLcode smtp_perform_command(struct connectdata *conn)
CURLcode Curl_write(struct connectdata *conn, curl_socket_t sockfd, const void *mem, size_t len, ssize_t *written)
static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len)
static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
#define Curl_safefree(ptr)
curl_socket_t writesockfd
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks, int numsocks)
bool Curl_pp_moredata(struct pingpong *pp)
static CURLcode smtp_statemach_act(struct connectdata *conn)
static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
curl_off_t Curl_mime_size(curl_mimepart *part)
static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
static void state(struct connectdata *conn, smtpstate newstate)
char * Curl_checkheaders(const struct connectdata *conn, const char *thisheader)
static CURLcode smtp_state_auth_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
static CURLcode smtp_perform_ehlo(struct connectdata *conn)
static CURLcode smtp_connect(struct connectdata *conn, bool *done)
void Curl_pp_init(struct pingpong *pp)
static CURLcode smtp_done(struct connectdata *conn, CURLcode status, bool premature)
struct connectdata * conn
static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp)
CURLcode Curl_pp_sendf(struct pingpong *pp, const char *fmt,...)
UNITTEST_START int * value
curl_read_callback fread_func
struct curl_slist * curlheaders
#define PROTOPT_URLOPTIONS
CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, const char *value, size_t len)
#define SMTP_EOB_FIND_LEN
static CURLcode smtp_state_servergreet_resp(struct connectdata *conn, int smtpcode, smtpstate instate)
union connectdata::@34 proto
static CURLcode smtp_do(struct connectdata *conn, bool *done)
CURLcode Curl_pp_readresp(curl_socket_t sockfd, struct pingpong *pp, int *code, size_t *size)
static CURLcode smtp_perform_quit(struct connectdata *conn)
static CURLcode smtp_init(struct connectdata *conn)
static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech, const char *initresp)
static CURLcode smtp_regular_transfer(struct connectdata *conn, bool *done)
#define PROTOPT_CLOSEACTION
static CURLcode smtp_perform_mail(struct connectdata *conn)
static CURLcode smtp_block_statemach(struct connectdata *conn)
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
static void smtp_get_message(char *buffer, char **outptr)
#define calloc(nbelem, size)
static CURLcode smtp_parse_url_path(struct connectdata *conn)
static CURLcode smtp_perform_helo(struct connectdata *conn)
static CURLcode smtp_disconnect(struct connectdata *conn, bool dead)
#define CURL_FORMAT_CURL_OFF_T