sending an email with libcurl/smtp with gmail: log

2019-05-14 04:20发布

问题:

I know there are hundreds of posts out there but somehow this does not work for me. I am trying to send an email with libcurl. This is my code:

#include <stdio.h>
#include <string.h>
#include <curl/curl.h>

#define FROM    "<myemail@gmail.com>"
#define TO      "<someother@gmail.com>"
#define CC      "<someother2@hotmail.com>"

static const char *payload_text[] = {
  "Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
  "To: " TO "\r\n",
  "From: " FROM "(Example User)\r\n",
  "Cc: " CC "(Another example User)\r\n",
  "Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
  "rfcpedant.example.org>\r\n",
  "Subject: SMTP example message\r\n",
  "\r\n", /* empty line to divide headers from body, see RFC5322 */
  "The body of the message starts here.\r\n",
  "\r\n",
  "It could be a lot of lines, could be MIME encoded, whatever.\r\n",
  "Check RFC5322.\r\n",
  NULL
};

struct upload_status {
  int lines_read;
};

static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
  struct upload_status *upload_ctx = (struct upload_status *)userp;
  const char *data;

  if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
    return 0;
  }

  data = payload_text[upload_ctx->lines_read];

  if(data) {
    size_t len = strlen(data);
    memcpy(ptr, data, len);
    upload_ctx->lines_read++;

    return len;
  }

  return 0;
}

int main(void)
{
  CURL *curl;
  CURLcode res = CURLE_OK;
  struct curl_slist *recipients = NULL;
  struct upload_status upload_ctx;

  upload_ctx.lines_read = 0;

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.gmail.com:587");
    curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
    curl_easy_setopt(curl, CURLOPT_USERNAME, "myemail@gmail.com");
    curl_easy_setopt(curl, CURLOPT_PASSWORD, "mypassword");
    curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);

    recipients = curl_slist_append(recipients, TO);
    recipients = curl_slist_append(recipients, CC);
    curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);

   curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);

    res = curl_easy_perform(curl);

    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));

    curl_slist_free_all(recipients);

    curl_easy_cleanup(curl);
  }

  return (int)res;
}

I also tried this example which is very similar except the text gets piped through a different file.

But I always get

curl_easy_perform() failed: Login denied

and then gmail sends me a message saying that someone tried to hack into my account. (login credentials are correct)

This curl-config --feature

gives me

SSL IPv6 UnixSockets libz NTLM NTLM_WB

Reading a couple of blogposts I also tried with hotmail using smtp://smtp.live.com:465

But here I get

curl_easy_perform() failed: Couldn't connect to server

What am I doing wrong here?

回答1:

I had to spend a great deal of time to get this to work but I finally got it to work. Here's what I found:

First:

#define FROM    "<myemail@gmail.com>"
#define TO      "<someother@gmail.com>"
#define CC      "<someother2@hotmail.com>"

There should not be any "<" or ">" in the email adress. I did the mistake of reusing the defines and could not for my life understand why the login failed.

Second:

You will most likely need to go here and allow unsecure apps: https://www.google.com/settings/security/lesssecureapps

Third:

If you're using port 587 you will need the following line:

curl_easy_setopt(m_curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);

This does not seem to be needed for 465.

Note:

It's ok to use either port 465 or 587. 465 requires SSL so you will need to use smtps instead of smtp to specify this - smtps://smtp.gmail.com:465. I found some info about it here: https://support.google.com/a/answer/176600?hl=en



回答2:

i am use libcurl, so i've been downloaded the curl-7.49.1 and inside the directory

i copied the imap-fetch.c to generate an specific imap for gmail, than i copy, paste and rename to imap-fetch-gmail.h

inside the imap-fetch-gmail.h i set my parameters on this lines:

curl_easy_setopt(curl, CURLOPT_USERNAME, "myemail@gmail.com");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "mypassword");

/* This will fetch message 1 from the user's inbox */
curl_easy_setopt(curl, CURLOPT_URL,
                 "imaps://imap.gmail.com:993/INBOX/;UID=1");

then, inside the curl folder i call GCC to compile my imap-fetch-gmail.h with my account settings such as E-mail, Password and parameters with this command

gcc imap-fetch-gmail.c -o imap-fetch-gmail -lcurl

After this,

First, you need to enable your IMAP Settings on your GMAIL account, then you need to enable less secure apps to access your gmail account. If you does not do it you've receice an security email with the subject : "Attempting to login prevented"

You can manage access to less secure apps on this link: https://www.google.com/settings/security/lesssecureapps

For more information about the individual components of an IMAP URL please see RFC 5092.