0

Hello I am trying to build a script that will list sites' SSL cert expiration date. The first function of the code def sslExpiresDate works great on its own. It's when I add the second function def all_sites_list where my code has broken. I don't know how to run sslExpiresDate to get an outcome for each URL in the list sites. I have tried to do this by building a second function and calling the first one from it, but it does not work.

I would like the expected outcome to be in a readable table format (but I haven't even gotten that far). Something like:

SITE              EXP DATE
www.site1.com     03-05-18
www.site2.com     08-12-19
www.site3.com     12-12-21

Meanwhile here is the code I'm struggling with. Thanks:

import OpenSSL 
import ssl

sites = ['www.site1.com', 'www.site2.com', 'www.site3.com']

def sslExpiresDate():
    cert = ssl.get_server_certificate((sites, 443)) 
    x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) 
    print(x509.get_notAfter())
    return

def all_sites_list(sites, sslExpiresDate):
    for site in sites():
        sslExpiresDate(site)
    return

all_sites_list(sites, sslExpiresDate)
RaptorPete
  • 139
  • 12
  • 2
    The reason your code doesn't work is that you're doing `for site in sites():` instead of `for site in sites:`. Your `sites` is a list, not a function that returns a list, so you don't call it. – abarnert May 22 '18 at 18:38
  • Beyond that, you still need to write other stuff, like formatting the output in your desired format. And you could probably improve your code in various ways—e.g., have `sslExpiresData` return a value for the caller to use instead of printing it out and returning nothing. But the part you're stuck on is just a simple typo. – abarnert May 22 '18 at 18:39
  • 2
    You're calling `sslExpiresDate()` with one parameter, but the function itself is not declared to take any parameters. Also, there's no point in that function being passed to `all_sites_list()` as a parameter (it can be directly accessed by name), although you are perhaps planning to have other functions that can be specified in the future. – jasonharper May 22 '18 at 18:40

1 Answers1

0

The map function allows you to send each value in a sequence to a function producing a sequence of the results. You can the zip this sequence with the original sequence to get a table as you wanted:

import OpenSSL 
import ssl
from datetime import datetime

dateformat = '%Y%m%d%H%M%SZ'

sites = ['www.google.com', 'www.plus.net']

def sslExpiresDate(site):
    cert = ssl.get_server_certificate((site, 443)) 
    x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) 
    return datetime.strptime(x509.get_notAfter().decode(),dateformat).date().isoformat()


def all_sites_list(sites, sslExpiresDate):
    return list(zip(sites,map(sslExpiresDate,sites)))

tab_format = '{:18s}{:18s}'
print(tab_format.format('SITE','EXP DATE'))
for site in sorted(all_sites_list(sites, sslExpiresDate), key=lambda site: site[1]):
    print(tab_format.format(*site))

gives:

SITE              EXP DATE          
www.google.com    2018-07-10        
www.plus.net      2020-02-27        

​
Highland Mark
  • 1,002
  • 1
  • 7
  • 12
  • Thank you very much, this is perfect and what I was looking for. One last question, is it possible to format that list by date closest to expiring? – RaptorPete May 22 '18 at 21:20
  • Yes, we just need to sort on the date. Changed the code to suit. – Highland Mark May 22 '18 at 21:58
  • Don't forget to give me a tick! – Highland Mark May 22 '18 at 22:01
  • That just means an upvote right? I tried to but I don't think my reputation is high enough for it to show up :( – RaptorPete May 23 '18 at 14:44
  • Mark it's working great, thanks so much for the help. I would like to ask, what does the * symbol do in the line: `print(tab_format.format(*site))` I am going to do more research on some of the code snippets that you've provided, but I need to know what to look for. I am also a bit lost on `key=lambda site: site[1])` What does key=lambda mean? Like I said everything works great, but I would like to learn it myself for the next time. What part of Python are these lines associated with? – RaptorPete May 23 '18 at 16:18