send-mail and send-letter enhancements allow using SSL and starting STARTTLS negotiations

Allegro CL has for some time facilities for sending mail -- see imap.htm and the descriptions of the functions send-smtp and send-letter. But these would not work if the mail-server being contacted needed SSL or needed to negotiate STARTTLS. In a recent update (see sys:update-allegro), the sending functions mentioned above (along with send-smtp-auth) have been enhanced to support SSL and starting STARTTLS negotiations.

The new facilities are accessed using the mail-server (first required) argument to the listed functions. This argument has always allowed you to specify the mail-server and the port number to be used. Now it can also encode additional information. In its most general form, the value of the argument can be a list of the following form:

(server-name &key (port 25) (ssl nil) (starttls nil) ...ssl-client-keywords...)

where

  • server-name is a string naming the server or an IP address.
  • port allows for another way to specify the port to connect to. The default port for tcp connections is 25. When ssl is non-nil, the default port is 465.
  • If ssl is non-nil, make-ssl-client-stream will be called after establishing a connection to the SMTP server. All ssl-client-keywords are passed to make-ssl-client-stream as well.
  • If starttls is non-nil, it allows for negotiation of a secure connection (TLSv1) if the server supports it. If the server supports both auth and starttls, starttls will be negotiated before attempting authentication.
  • ...ssl-client-keywords...: all keyword args to make-ssl-client-stream are accepted. e.g. :method :ciphers, certificate related args, etc.

An example

Here is some code which (when real users and servers are substituted for the dummies used) should use SSL or start STARTTLS negotiations.

(use-package :net.post-office)
(defparameter *smtp-host* "localhost")
(defparameter *smtp-user* "someuser")
(defparameter *smtp-password* "somepassword")

;; ssl with authentication
(let ((part (make-mime-part 
             :text "This is a test message sent via Secure SMTP server with authentication."
             :headers '(("From" . "Test User <joe@example.com>")
                        ("To" . "Recipient <jimmy@yahoo.com>")
                        ("Subject" . "This is a test email")))))
  (with-mime-part-constructed-stream (s part)
    (send-smtp-auth (list *smtp-host* :ssl t :method :sslv3+)
                     *smtp-user*
                     "jimmy@yahoo.com"
                     *smtp-user* *smtp-password*
                     s)))

;; with starttls negotiation
(let ((part (make-mime-part 
             :text "This is a test message sent possibly via a TLSv1 encrypted channel."
             :headers '(("From" . "Test User <joe@example.com>")
                        ("To" . "Recipient <jimmy@yahoo.com>")
                        ("Subject" . "This is a test email")))))
  (with-mime-part-constructed-stream (s part)
    (send-smtp (list *smtp-host* :starttls t)
                     *smtp-user*
                     "jimmy@yahoo.com"
                     s)))
Copyright © 2023 Franz Inc., All Rights Reserved | Privacy Statement Twitter