0

Attempting to loop through a list of servers and connect to them with OpenSSL, retrieve SSL cert, and pull the server name, the date the cert expires, and calculate the number of days until cert expires. The code works fine printing to the terminal sessions but I am having trouble getting it to write to a text file for each server in this format: Server Name: Server01 Day Cert Expires: 2020-03-16 23:59:59 Days to expire: 564 Can someone tell me how I can capture each variable in the For loop and write it to a text file? I have tried numerous attempts with variations of the f.write and can't seem to get it to work.

f = open("SSL.txt", "a")
f.write(server_name, exp_date, days_to_expire) 

Complete code

import ssl
from datetime import datetime
import pytz
import OpenSSL
import socket
from datetime import timedelta
import colorama
from colorama import init
from colorama import Fore, Back, Style

## opening file
ipfile = open('server_ip.txt')
cur_date = datetime.utcnow()

for ip in ipfile:
  try:
    host = ip.strip().split(":")[0]
    port = ip.strip().split(":")[1]
    print("\nChecking certifcate for server ", host)
    ctx = OpenSSL.SSL.Context(ssl.PROTOCOL_TLSv1)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, int(port)))
    cnx = OpenSSL.SSL.Connection(ctx, s)
    cnx.set_connect_state()
    cnx.do_handshake()
    cert = cnx.get_peer_certificate()
    s.close()
    server_name = cert.get_subject().commonName
    print(server_name)
    edate = cert.get_notAfter()
    edate = edate.decode()
    exp_date = datetime.strptime(edate, '%Y%m%d%H%M%SZ')
    days_to_expire = int((exp_date - cur_date).days)
    print(exp_date)
    print("day to expire", days_to_expire)
    if days_to_expire <= 30:
      init(convert=True)
      print(Fore.YELLOW + "WARNING!",server_name, "SSL Certificate has less than 30 days before it expires." + Style.RESET_ALL)
  except:
      print("error on connection to Server,", host)

2 Answers 2

1

Following on from Victor's comment about closing the file, to pass multiple variables to on write, you can use python 3's string interpolation.

E.g:

>>> f = open('test.txt', 'a')
>>> for x in range(10):
...     y = str(1*x)
...     z = str(10* x)
...     j = str(100*x)
...     f.write(f"{y} {z} {j}\n")
>>> f.close()
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Oliver! This is what I ended up doing.
ssl_results[str(ip)][0] = hostssl_results[str(ip)][1] = server_name ssl_results[str(ip)][2] = exp_date ssl_results[str(ip)][3] = days_to_expire
0

Don't forget to close your file through f.close() otherwise the file will be empty. If you use the with keyword, the file will automatically close, as shown in this example code copied from The Python Tutorial 7.1 Reading and Writing Files:

>>> with open('workfile') as f:
...     read_data = f.read()
>>> f.closed
True

Also, the write method only takes 1 argument.

2 Comments

Thank you for the response Victor. Yes forgot to include the f.close() in my question. I had been including that but you may have hit on the problem I am having with the write method taking only 1 argument.
You could send this argument to write f"Server Name: {server_name} Day Cert Expires: {exp_date} Days to expire: {days_to_expire}" to send in a single string that Python will format to replace the bracketed variable names with their values in 3.7.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.