This started off as a question to me about TLS certificates and ended up with a Python solution.
The short version of this blog post is I could send an email to Gmail using Python – but could not use the IBM CSSMTP solution because it does not support authentication. I was also sent a link to Sending Email from z/OS using Java.
As far as I can tell, SMTP authentication does not use client certificates. If you want to use userid and password, make sure the session is encrypted using TLS.
What types of email are there?
Through JES spool
On my system with id S0W1, I can use TSO XMIT S0W1.IBMUSER and send an email.
The recipient (IBMUSER) can use TSO receive to read the email.
You can use XMIT OVERTHER.MYID to send the email over NJE to other system, such as z/OS, z/VM and z/VSE. You say (on z/OS) xmit node.userid da(‘…’). or xmit node.userid . The JES2 configuration has an IP address and port to send it to a remote spool.
JES2 destinations
You can configure destinations on JES2, and have program (“a writer”) process the node name (destination) data.
You can display the defined destinations using the JES2 command
$DDESTID
Example JCL to write to a destination,
//COPY EXEC PGM=IEBGENER //SYSPRINT DD SYSOUT=* //SYSIN DD DUMMY //SYSUT2 DD SYSOUT=(A,MYDEST),SPIN=UNALLOC //SYSUT1 DD * line1 /* //
This writes the data from SYSUT1 to SYOUT2 which goes to nodename MYDEST.
You configure CSSMP and specify ExtWrtName MYDEST, for CSSMTP to read from.
SMTP
There is Simple Mail Transport Protocol. A stream of data is provided such as
MAIL FROM:<ME@MYSYSTEM.COM> RCPT TO:<MYBOSS@MYSYSTEM.COMU> RCPT TO:<YOU@yoursystem.com> DATA Blah blah blah. QUIT
which is sent to the mail server over TCPIP (usually port 25 or 587).
SMTP is a popular protocol. It can support encrypted session encryption. The protocol can support different levels of authorisation.
z/OS provides CSSMTP which reads from the spool and sends the data over TCPIP to a server. However CSSMTP does not seems to support the passing of authentication information to the server – and as most mail servers want you to authenticate before sending emails – CSSMTP cannot be used for these. I know this from the documentation because the AUTH command is not listed in the list of supported SMTP commands, and AUTH does not work!
Using Python to send an email.
I used Python to send an email to my Gmail account. The script I used is
#!/usr/bin/python import smtplib import ssl import sys from email.mime.text import MIMEText host = "173.194.76.108" sender = 'colinpaicetest@gmail.com' receivers = ['colinpaicemq@gmail.com','colinpaicetest@gmail.com'] msg = MIMEText('This is test mail2') msg['Subject'] = 'Test mail3' msg['From'] = 'colinpaice3@gmail.com' msg['To'] ='colinpaicemq@gmail.com , colinpaicetest@gmail.com' with smtplib.SMTP(host , 587) as server: # if you need to validate the certificate sent to client.. you need a context context=ssl.create_default_context( purpose=ssl.Purpose.CLIENT_AUTH,cafile="pem.pem") server.starttls(context=context) # server.starttls() # for servers that do not send a certificate print(server.esmtp_features) # print info about the connection such as auth types server.login('colinpaice3@gmail.com', 'abcpasswordxyz') server.sendmail(sender, receivers, msg.as_string()) print("Successfully sent email")
- context=ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH,cafile=”pem.pem”) is used to set up the CA cert for verifying any certificate sent from the server. GMAIL does not send a certificate, so the CA is not needed, and you can use server.starttls()
- server.starttls(context=context) creates the TLS session. This is handled by PAGENT.
- server.login(‘colinpaice3@gmail.com’, ‘ZYC123….’) does the authentication
- server.sendmail(sender, receivers, msg.as_string()) sends the message.
The id in the sender must match the id in the login.
This does not use PAGENT or AT-TLS.
In the TLS handshake 57 cipher specs were sent to the server, and cipher spec TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xC02B) was used.
Setting up CSSMTP
Basic configuration
Even though I could not use CSSMTP because I could not authenticate, I learned a lot on my doomed journey.
In the CSSMTP configuration I had
ExtWrtName MYDEST # the external writer name TargetServer { TargetIp aaa.bbb.ccc.ddd # This IP address # TargetName ConnectPort 25 # port to connect to target server Secure Yes # Transport Layer Security (TLS) } ...
Each CSSMTP instance reads from one nodeName and sends to one server. If you want to support more nodeNames you need more CSSMTP instances.
Certificates
As part of the TLS handshake, some servers will send down a certificate (to authenticate the server).
If your TLS provider, such as AT-TLS, uses keyrings, you need to import certificate into RACF, and connect the CA certificate to the keyring. Your keyring needs the CA for this certificate. You can get the servers certificate from the network flow, or from an openssl command.
If you are not using keyrings, for example Python uses openssl, you need the certificate in a file in Unix Services.