I'm using the libcurl C library to access (fetch,search) gmail imaps server, i'm using the code from the libcurl examples i.e "imap-ssl.c" as a test example. The example code when executed for the first time it works fine and fetched me the required email from my gmail account, but when you try to execute the program again it fails when one wants to fetch a different email or the same one again, but if I re-run the program after some 20 minutes it works and fetches the required mail.
Seems like gmail requires us to fetch the whole inbox from the server at once i.e synchronization of the local (fetched) emails with the online gmail server is allowed only once in 20 minutes or what.??? what if one wants to access one email only once at a time or just going through his whole gmail inbox mails one by one?
Also i tried to use the openssl command line tool to fetch or execute imaps commands on imap.gmail.com:993 (ssl enabled) and it works like a charm , no matter how many times i try to access gmail it never say a word of trouble but libcurl does.
#include<stdio.h>
#include<string.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res = CURLE_OK;
curl = curl_easy_init();
if(curl) {
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERNAME, "[email protected]");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "examplepassword");
/* This will fetch message 1 from the user's inbox. Note the use of
* imaps:// rather than imap:// to request a SSL based connection. */
curl_easy_setopt(curl, CURLOPT_URL,"imaps://imap.gmail.com:993/INBOX/;UID=5");
/* Note: CA cert is already in the right place (checked) */
#ifdef SKIP_PEER_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
/* If the site you're connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure. */
#ifdef SKIP_HOSTNAME_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* Perform the fetch */
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_easy_cleanup(curl);
}
return (int)res;
}
> * Hostname was NOT found in DNS cache
> * Trying 74.125.206.109...
> * Connected to imap.gmail.com (74.125.206.109) port 993 (#0)
> * successfully set certificate verify locations:
> * CAfile: none
> > CApath: /etc/ssl/certs
> * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
> * Server certificate:
> * subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=imap.gmail.com
> * start date: 2017-03-22 16:46:00 GMT
> * expire date: 2017-06-14 16:17:00 GMT
> * subjectAltName: imap.gmail.com matched
> * issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
> * SSL certificate verify ok.
> * OK Gimap ready for requests from 182.180.90.60
> * A001 CAPABILITY
> > CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN
> AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH A001 OK Thats all
> she wrote! 9
> * A002 AUTHENTICATE PLAIN
> * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
> UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE
> APPENDLIMIT=35651584
> * A002 OK [email protected] authenticated (Success)
> * A003 SELECT INBOX
> * FLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing)
> * OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing \*)] Flags permitted.
> * OK [UIDVALIDITY 1] UIDs valid.
> * 32 EXISTS
> * 0 RECENT
> * OK [UIDNEXT 46] Predicted next UID.
> * OK [HIGHESTMODSEQ 4777]
> * A003 OK [READ-WRITE] INBOX selected. (Success)
> * A004 FETCH 5 BODY[]
> * 5 FETCH (BODY[] {628}
> *Found 628 bytes to download
> > Bcc: [email protected]
> > Return-Path: <[email protected]>
> > Received: from localhost (["MY IP Address])
> > by smtp.gmail.com with ESMTPSA id
> > for <[email protected]>
> > (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
> > Wed, 15 Mar 2017 03:13:29 -0700 (PDT)
> * Message-ID: <"msg id"@mx.google.com>
> * Date: Wed, 15 Mar 2017 03:13:29 -0700 (PDT)
> * From: [email protected]
> > Written 489 bytes, 139 bytes are left for transfer
> > Hi, i'm using openssl to send this message, i hope you are doing great man
> > Thank you so much
> > I just wanted to tell you that this is also possible
> * A004 OK Success
> * Connection #0 to host imap.gmail.com left intact
> * Hostname was NOT found in DNS cache
> * Trying 74.125.133.108...
> * Trying 2a00:1450:400c:c07::6d...
> * connect to 2a00:1450:400c:c07::6d port 993 failed: Network is unreachable
>* Failed to connect to imap.gmail.com port 993: Network is unreachable
>* Closing connection 0
>>curl_easy_perform() failed: Couldn't connect to server
Any code example will really be appreciated.
P.S: Code Added
On the second attempt it cant connect to the imap server, but this is not related to libcurl.
You can add the following code to make sure it only connects over IPv4, then the error message in the debug output will be from the connection attempt to the IPv4 address which is more relevant for you (since you most likely don't have IPv6 support):
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
More information on that option here: https://curl.haxx.se/libcurl/c/CURLOPT_IPRESOLVE.html
Try connecting to port 993 on the exact same IP as the libcurl program tries to connect to via telnet during the time when the libcurl program doesn't work. I'm sure it too will fail.
The way forward would probably to investigate if you have some sort of firewall in place which could cause the issue. Try running tcpdump(or wireshark if you want a GUI) to see what happens on a TCP level.