SendMail SSL via port 465

Just starting out? Need help? Post your questions and find answers here.
davebar
User
User
Posts: 82
Joined: Fri Aug 31, 2018 9:23 am
Location: Australia

SendMail SSL via port 465

Post by davebar »

Hi Folks,
I have been scratching around these PB forums for the last few days and cannot find any pointers to solve my issue.
My own servers use mail as opposed to smtp The message is created OK, but SendMail(0, "mail.example.net", 465, #PB_Mail_UseSSL, Login$, "password") fails.
Any advice (excluding everything related to Gmail) would be welcome.
Best Regards, Dave
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: SendMail SSL via port 465

Post by Dude »

Remember that every single mail parameter has to be correct (case-sensitivity for the server name, your login, and your password), and don't forget that some mail servers need you to use an app-specific password (your PureBasic executable may be seen as an "app" by the server), instead of your usual web browser password for logging in. It's happened to me so I speak from experience here.

I've also had a situation where using port 465 and #PB_Mail_UseSSL together actually fails, and I had to remove #PB_Mail_UseSSL or change the port number. Can't remember what that was, but changing one of those actually fixed the problem for me and let the mails be sent. Try experimenting with those parameters.

Lastly, don't forget that firewall and anti-virus software could be blocking the sending of mails, so check them out.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: SendMail SSL via port 465

Post by davido »

@davebar,

If you haven't looked at the thread below, you might find some help therein:

http://www.purebasic.fr/english/viewtop ... 84#p475184
DE AA EB
davebar
User
User
Posts: 82
Joined: Fri Aug 31, 2018 9:23 am
Location: Australia

Re: SendMail SSL via port 465

Post by davebar »

Hi Dude,
Thanks for taking the time to reply.
I have triple checked the accuracy and case sensitivity of all the parameters, in fact most I copied directly from my thunderbird settings.
Not sure what an "app specific" password would be. It is my web hosting mail server and I can find no setting in my mail server to control anything like this.
I have tried every possible combination ports, with and without #PB_Mail_UseSSL
The PB Help file Gmail example works perfectly for sending via my dummy Gmail account, so I doubt my FW or AV are the culprits.
Guess I will have to give up on finding a PB solution.
Regards Dave
davebar
User
User
Posts: 82
Joined: Fri Aug 31, 2018 9:23 am
Location: Australia

Re: SendMail SSL via port 465

Post by davebar »

Thanks davido, but as I said in my response to Dude, the PB Help file Gmail example works perfectly for sending via my dummy Gmail account.
I believe my issue is with my mail server requiring mail.example.net as opposed to smtp.example.net through port 465
Regards Dave
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: SendMail SSL via port 465

Post by Dude »

davebar wrote:I believe my issue is with my mail server requiring mail.example.net as opposed to smtp.example.net
Is that a public server that anyone (like myself) can test with? Or private?
infratec
Always Here
Always Here
Posts: 7586
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: SendMail SSL via port 465

Post by infratec »

If nothing helps, you can try it with the inbuild libcurl.
The smtp and smtps part is included.

Then look here:
https://curl.haxx.se/libcurl/c/smtp-ssl.html

Bernd
davebar
User
User
Posts: 82
Joined: Fri Aug 31, 2018 9:23 am
Location: Australia

Re: SendMail SSL via port 465

Post by davebar »

Dude: Access to the server setup is private.

Thanks infratec. This might well be a possibility, but translating the example code into PB is way above my coding skill.

Best Regards, Dave
infratec
Always Here
Always Here
Posts: 7586
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: SendMail SSL via port 465

Post by infratec »

Hi,

I directly converted the libcurl example.
In native PB I would do the message stuff a bit differnet. Not as an array.

Code: Select all

EnableExplicit

IncludeFile "libcurl.pbi"

#User$ = "user@xy.z"
#Password$ = "password123"

#Server$ = "mail.example.net"

#FROM$ = "<user@xy.z>"
#To$ = "<test@testerserver.net>"
#CC$ = "<test@mailtest.net>"


Global Dim payload_text$(11)

payload_text$(0) = "Date: Sun, 01 Sep 2018 17:30:29 +1100" + #CRLF$
payload_text$(1) = "To: "+ #To$ + #CRLF$
payload_text$(2) = "From: " + #FROM$ + " (Example User)" + #CRLF$
payload_text$(3) = "Cc: " + #CC$ + " (Another example User)" + #CRLF$
payload_text$(4) = "Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>" + #CRLF$
payload_text$(5) = "Subject: SMTP SSL example message" + #CRLF$
payload_text$(6) = #CRLF$ ; empty line To divide headers from body, see RFC5322
payload_text$(7) = "The body of the message starts here." + #CRLF$
payload_text$(8) =  #CRLF$
payload_text$(9) = "It could be a lot of lines, could be MIME encoded, whatever." + #CRLF$
payload_text$(10) = "Check RFC5322." + #CRLF$
payload_text$(11) = ""


Structure upload_status
  lines_read.i
EndStructure


ProcedureC payload_source(*ptr, size.i, nmemb.i, *userp)

  Protected *upload_ctx.upload_status = *userp
  Protected *Data
  Protected length.i
 
  If (size = 0 Or nmemb = 0) Or (size * nmemb < 1)
    ProcedureReturn 0
  EndIf
  
  If *upload_ctx\lines_read < ArraySize(payload_text$())
    *Data = UTF8(payload_text$(*upload_ctx\lines_read))
    
    If *Data
      length = MemorySize(*Data) - 1
      CopyMemory(*Data, *ptr, length)
      *upload_ctx\lines_read + 1
      
      FreeMemory(*Data)
      
      ProcedureReturn length
    EndIf
  EndIf
 
  ProcedureReturn 0
  
EndProcedure




;-Main
Define curl.i
Define res.i = #CURLE_OK
Define *recipients.curl_slist
Define upload_ctx.upload_status
 
curl = curl_easy_init()
If curl
  ; Set username And password
  curl_easy_setopt_str(curl, #CURLOPT_USERNAME, #User$)
  curl_easy_setopt_str(curl, #CURLOPT_PASSWORD, #Password$)
  
  ; This is the URL For your mailserver. Note the use of smtps:// rather
  ; than smtp:// To request a SSL based connection.
  curl_easy_setopt_str(curl, #CURLOPT_URL, "smtps://" + #Server$)
  
  ; If you want To connect To a site who isn't using a certificate that is
  ; signed by one of the certs in the CA bundle you have, you can skip the
  ; verification of the server's certificate. This makes the connection
  ; A LOT LESS SECURE.
  ;
  ; If you have a CA cert For the server stored someplace Else than in the
  ; Default bundle, then the CURLOPT_CAPATH option might come handy For
  ; you.
  CompilerIf Defined(SKIP_PEER_VERIFICATION, #PB_Constant)
    CompilerIf #SKIP_PEER_VERIFICATION
      curl_easy_setopt(curl, #CURLOPT_SSL_VERIFYPEER, 0)
    CompilerEndIf
  CompilerEndIf
  
  ; 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. */ 
  CompilerIf Defined(SKIP_HOSTNAME_VERIFICATION, #PB_Constant)
    CompilerIf #SKIP_HOSTNAME_VERIFICATION
      curl_easy_setopt(curl, #CURLOPT_SSL_VERIFYHOST, 0)
    CompilerEndIf
  CompilerEndIf
  
  ; Note that this option isn't strictly required, omitting it will result
  ; in libcurl sending the MAIL FROM command With empty sender Data. All
  ; autoresponses should have an empty reverse-path, And should be directed
  ; To the address in the reverse-path which triggered them. Otherwise,
  ; they could cause an endless loop. See RFC 5321 Section 4.5.5 For more
  ; details.
  ; 
  curl_easy_setopt_str(curl, #CURLOPT_MAIL_FROM, #FROM$)
  
  ; Add two recipients, in this particular Case they correspond To the
  ; To: And Cc: addressees in the header, but they could be any kind of
  ; recipient.
  *recipients = curl_slist_append(*recipients, #To$)
  *recipients = curl_slist_append(*recipients, #CC$)
  curl_easy_setopt(curl, #CURLOPT_MAIL_RCPT, *recipients)
  
  ; We're using a callback function to specify the payload (the headers and
  ; body of the message). You could just use the CURLOPT_READDATA option To
  ; specify a FILE pointer To Read from.
  curl_easy_setopt(curl, #CURLOPT_READFUNCTION, @payload_source())
  curl_easy_setopt(curl, #CURLOPT_READDATA, @upload_ctx)
  curl_easy_setopt(curl, #CURLOPT_UPLOAD, 1)
  
  ; Since the traffic will be encrypted, it is very useful To turn on Debug
  ; information within libcurl To see what is happening during the
  ; transfer
  curl_easy_setopt(curl, #CURLOPT_VERBOSE, 1)
  
  ; Send the message
  res = curl_easy_perform(curl)
  
  ; Check For errors
  If res <> #CURLE_OK
    Debug "curl_easy_perform() failed: " + curl_easy_strerror(res)
  EndIf
    
  ; Free the List of recipients
  curl_slist_free_all(*recipients)
    
  ; Always cleanup
  curl_easy_cleanup(curl)
EndIf
My libcurl.pbi:
https://oc.ednt.de/index.php/s/UeeKoMco3is23Zk

Bernd
Last edited by infratec on Sat Sep 01, 2018 4:38 pm, edited 2 times in total.
infratec
Always Here
Always Here
Posts: 7586
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: SendMail SSL via port 465

Post by infratec »

Ups... something with the encoding is wrong. But no time left now ...
davebar
User
User
Posts: 82
Joined: Fri Aug 31, 2018 9:23 am
Location: Australia

Re: SendMail SSL via port 465

Post by davebar »

Wow! That's extremely generous infratec.
I am happy to wait until you have the time to recheck the encoding.
Many Thanks, Dave
infratec
Always Here
Always Here
Posts: 7586
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: SendMail SSL via port 465

Post by infratec »

Corrected!

Was not an encoding problem, I simply swapped src and dst inside the CopyMemory() call.

I was able to send an SSL email via our company mailserver to an address at gmx.de

Bernd
infratec
Always Here
Always Here
Posts: 7586
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: SendMail SSL via port 465

Post by infratec »

If you still have problems try:

Code: Select all

#SKIP_PEER_VERIFICATION = #True
#SKIP_HOSTNAME_VERIFICATION = #True
davebar
User
User
Posts: 82
Joined: Fri Aug 31, 2018 9:23 am
Location: Australia

Re: SendMail SSL via port 465

Post by davebar »

Thanks for continuing to help me with this.
I can't pretend to understand the logic of this code, but if I can get it to work I will definitely make the time and effort to learn.
You correction says "the src and dst are swapped inside the CopyMemory() call", could you please post the corrected version of the call.
Best Regards
Dave
infratec
Always Here
Always Here
Posts: 7586
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: SendMail SSL via port 465

Post by infratec »

I wrote was, which is past.
This means I corrected it already before I wrote the comment about it :wink:
Post Reply