diff --git a/README.md b/README.md index 7d3cdc4..0006b28 100644 --- a/README.md +++ b/README.md @@ -8,55 +8,69 @@ ### 설치 방법 1. Git Clone -``` +```bash $ https://github.com/happylie/sosci.git ``` ### 실행 방법 -1. Help -``` +#### 1. Help +```bash $ python sosci.py -h -usage: sosci.py [-h] [-u URL] [-e] [-v] +usage: sosci.py [-h] [-e] [-v] url Search of SSL Certification Information(SoSCI) -optional arguments: - -h, --help show this help message and exit - -u URL, --url URL Check URL(HTTPS URL or Hostname) - -e, --expire Certification Expire Date - -v, --version show program's version number and exit +positional arguments: + url Check URL(HTTPS URL or Hostname) +optional arguments: + -h, --help show this help message and exit + -e, --expire Certification Expire Date (default: False) + -v, --version show program's version number and exit ``` -2. Search of SSL Certification Information -``` -$ python sosci.py -u https://happylie.tistory.com +#### 2. Search of SSL Certification Information +```bash +$ python sosci.py https://happylie.tistory.com { -"subject":{ - "countryName":"KR", - "stateOrProvinceName":"Jeju-do", - "localityName":"Jeju-si", - "organizationName":"Kakao Corp.", - "commonName":"*.tistory.com" -}, -"issuer":{ - "countryName":"US", - "organizationName":"DigiCert Inc", - "organizationalUnitName":"www.digicert.com", - "commonName":"Thawte TLS RSA CA G1" -}, -"notBefore":"2022-03-14 00:00:00", -"notAfter":"2023-03-31 23:59:59", -"expireDate":"219 Days", -"subjectAltName":{ - "DNS":[ - "*.tistory.com", - "tistory.com" - ] - } + "result": { + "expireDate": "181 Days", + "issuer": { + "commonName": "Thawte TLS RSA CA G1", + "countryName": "US", + "organizationName": "DigiCert Inc", + "organizationalUnitName": "www.digicert.com" + }, + "notAfter": "2023-03-31 23:59:59", + "notBefore": "2022-03-14 00:00:00", + "subject": { + "commonName": "*.tistory.com", + "countryName": "KR", + "localityName": "Jeju-si", + "organizationName": "Kakao Corp.", + "stateOrProvinceName": "Jeju-do" + }, + "subjectAltName": { + "DNS": [ + "*.tistory.com", + "tistory.com" + ] + } + }, + "status": { + "code": 0, + "msg": "SSL Certification Information" + } } ``` -- 2.1 항목 정보 설명 +##### 2.1 항목 정보 설명 +```text ++ status : 상태 정보 + - code : Code 정보 + - 0 : (정상) + - 1 : (에러) + - mgs : Status 메세지 내용 + + result : 결과 정보 - subject : 제목 이름 - countryName : 국가 또는 지역 - stateOrProvinceName : 주/도 @@ -73,9 +87,18 @@ $ python sosci.py -u https://happylie.tistory.com - expireDate : 현재부터 인증서 만료일 - subjectAltName : 주체 대체 이름 - DNS : DNS 정보 - -3. Certification Expire Date ``` -$ python sosci.py -u https://happylie.tistory.com -e -219 Days + +#### 3. Certification Expire Date +```bash +$ python sosci.py https://happylie.tistory.com -e +{ + "result": { + "expireDate": "181 Days" + }, + "status": { + "code": 0, + "msg": "SSL Expire Date" + } +} ``` \ No newline at end of file diff --git a/sosci.py b/sosci.py index 39ded47..8c18442 100644 --- a/sosci.py +++ b/sosci.py @@ -30,7 +30,6 @@ def __init__(self, host, sport): with ctx.wrap_socket(self.sock, server_hostname=host) as s: self.ret = s.getpeercert() except Exception as err: - print("A") sys.exit(0) def __del__(self): @@ -60,44 +59,81 @@ def __convert_dict2json(self, data): end_date = datetime.strptime(data['notAfter'], "%b %d %H:%M:%S %Y %Z") expire_date = self.__expire_date(end_date) ret = { - "subject": dict(i[0] for i in data['subject']), - "issuer": dict(i[0] for i in data['issuer']), - "notBefore": str(start_date), - "notAfter": str(end_date), - "expireDate": expire_date, - "subjectAltName": subjectaltname_data + "status": { + "code": 0, + "msg": "SSL Certification Information" + }, + "result": { + "subject": dict(i[0] for i in data['subject']), + "issuer": dict(i[0] for i in data['issuer']), + "notBefore": str(start_date), + "notAfter": str(end_date), + "expireDate": expire_date, + "subjectAltName": subjectaltname_data + } } - return json.dumps(ret) + return json.dumps(ret, indent=4, sort_keys=True) def run(self): return self.__convert_dict2json(self.ret) if __name__ == "__main__": - parser = argparse.ArgumentParser(prog='sosci.py', description='Search of SSL Certification Information(SoSCI)') + parser = argparse.ArgumentParser( + prog='sosci.py', description='Search of SSL Certification Information(SoSCI)', + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + if len(sys.argv) == 1: + ret = { + "status": { + "code": 1, + "msg": "Input the URL" + }, + "result": {} + } + print(json.dumps(ret, indent=4, sort_keys=True)) + sys.exit(0) + parser.add_argument('url', type=str, help='Check URL(HTTPS URL or Hostname)') + parser.add_argument('-e', '--expire', action='store_true', dest='exp', help='Certification Expire Date') + parser.add_argument('-v', '--version', action='version', version='sosci v1.1') try: - - parser.add_argument('-u', '--url', dest='url', type=str, help='Check URL(HTTPS URL or Hostname)') - parser.add_argument('-e', '--expire', dest='exp', action='store_false', help='Certification Expire Date') - parser.add_argument('-v', '--version', action='version', version='sosci v1.0') args = parser.parse_args() - if not args.url: - print('Input the URL') - sys.exit(0) up = UrlPaser().get_parser(args.url) if not up[0]: - print('URL is not valid') + ret = { + "status": { + "code": 1, + "msg": "URL is not valid" + }, + "result": {} + } + print(json.dumps(ret, indent=4, sort_keys=True)) sys.exit(0) - hostname = up[1] - port = up[2] - si = SSLInfo(hostname, port) + si = SSLInfo(up[1], up[2]) obj = si.run() if args.exp: - print(obj) + ret = { + "status": { + "code": 0, + "msg": "SSL Expire Date" + }, + "result": { + "expireDate": json.loads(obj)['result']['expireDate'] + } + } + print(json.dumps(ret, indent=4, sort_keys=True)) else: - print(json.loads(obj)['expireDate']) + print(obj) sys.exit(0) except Exception as err: - print("main:: {err}".format(err=err)) + print(err) + ret = { + "status": { + "code": 1, + "msg": "ArgumentParser Error" + }, + "result": {} + } + print(json.dumps(ret, indent=4, sort_keys=True)) sys.exit(0) diff --git a/util/url_parser.py b/util/url_parser.py index e6cc0f1..9f0f2d1 100644 --- a/util/url_parser.py +++ b/util/url_parser.py @@ -2,14 +2,10 @@ # -*- coding: utf-8 -*- from urllib.parse import urlparse from urllib.request import urlopen -from urllib.error import HTTPError from urllib.error import URLError class UrlPaser: - def __init__(self): - self.a = "" - @staticmethod def __url_check(url): try: @@ -18,9 +14,10 @@ def __url_check(url): if status_code != 200: return False return True - except HTTPError as err: - return False except URLError as err: + allow_code = [401, 402, 403, 404, 405] + if err.code in allow_code: + return True return False def get_parser(self, data):