add --ssl-ver (ssl/tls versions to allow)

This commit is contained in:
ed 2021-02-11 21:24:17 +00:00
parent 6c957c4923
commit 3365b1c355
3 changed files with 74 additions and 7 deletions

View file

@ -8,6 +8,7 @@ __copyright__ = 2019
__license__ = "MIT"
__url__ = "https://github.com/9001/copyparty/"
import re
import os
import time
import shutil
@ -85,6 +86,51 @@ def ensure_cert():
# printf 'NO\n.\n.\n.\n.\ncopyparty-insecure\n.\n' | faketime '2000-01-01 00:00:00' openssl req -x509 -sha256 -newkey rsa:2048 -keyout insecure.pem -out insecure.pem -days $((($(printf %d 0x7fffffff)-$(date +%s --date=2000-01-01T00:00:00Z))/(60*60*24))) -nodes && ls -al insecure.pem && openssl x509 -in insecure.pem -text -noout
def configure_ssl(al):
import ssl
def terse_sslver(txt):
txt = txt.lower()
for c in ["_", "v", "."]:
txt = txt.replace(c, "")
return txt.replace("tls10", "tls1")
# oh man i love openssl
# check this out
# hold my beer
ptn = re.compile(r"^OP_NO_(TLS|SSL)v")
sslver = terse_sslver(al.ssl_ver).split(",")
flags = [k for k in ssl.__dict__ if ptn.match(k)]
# SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv1_2 TLSv1_3
if "help" in sslver:
avail = [terse_sslver(x[6:]) for x in flags]
avail = " ".join(sorted(avail) + ["all"])
print("\navailable ssl/tls versions:\n " + avail)
return
al.ssl_flags_en = 0
al.ssl_flags_de = 0
for flag in sorted(flags):
ver = terse_sslver(flag[6:])
num = getattr(ssl, flag)
if ver in sslver:
al.ssl_flags_en |= num
else:
al.ssl_flags_de |= num
if sslver == ["all"]:
x = al.ssl_flags_en
al.ssl_flags_en = al.ssl_flags_de
al.ssl_flags_de = x
for k in ["ssl_flags_en", "ssl_flags_de"]:
num = getattr(al, k)
print("{}: {:8x} ({})".format(k, num, num))
# think i need that beer now
def main():
time.strptime("19970815", "%Y%m%d") # python#7980
if WINDOWS:
@ -133,6 +179,9 @@ def main():
"save,get" dumps to file and returns the page like a GET
"print,get" prints the data in the log and returns GET
(leave out the ",get" to return an error instead)
see "--ssl-ver help" for available ssl/tls versions,
default is what python considers safe, usually >= TLS1
"""
),
)
@ -155,6 +204,7 @@ def main():
ap.add_argument("-nid", action="store_true", help="no info disk-usage")
ap.add_argument("--no-sendfile", action="store_true", help="disable sendfile")
ap.add_argument("--urlform", type=str, default="print,get", help="how to handle url-forms")
ap.add_argument("--ssl-ver", type=str, help="ssl/tls versions to allow")
al = ap.parse_args()
# fmt: on
@ -168,6 +218,9 @@ def main():
except:
raise Exception("invalid value for -p")
if al.ssl_ver:
configure_ssl(al)
SvcHub(al).run()

View file

@ -134,6 +134,16 @@ class HttpCli(object):
uparam["raw"] = True
uparam["dots"] = True
if hasattr(self.s, "cipher"):
self.ssl_suf = "".join(
[
" \033[3{}m{}".format(c, s)
for c, s in zip([6, 3, 6], self.s.cipher())
]
)
else:
self.ssl_suf = ""
try:
if self.mode in ["GET", "HEAD"]:
return self.handle_get() and self.keepalive
@ -211,7 +221,7 @@ class HttpCli(object):
logmsg += " [\033[36m" + rval + "\033[0m]"
self.log(logmsg)
self.log(logmsg + self.ssl_suf)
# "embedded" resources
if self.vpath.startswith(".cpr"):
@ -245,7 +255,7 @@ class HttpCli(object):
return self.tx_browser()
def handle_options(self):
self.log("OPTIONS " + self.req)
self.log("OPTIONS " + self.req + self.ssl_suf)
self.send_headers(
None,
204,
@ -258,7 +268,7 @@ class HttpCli(object):
return True
def handle_put(self):
self.log("PUT " + self.req)
self.log("PUT " + self.req + self.ssl_suf)
if self.headers.get("expect", "").lower() == "100-continue":
try:
@ -269,7 +279,7 @@ class HttpCli(object):
return self.handle_stash()
def handle_post(self):
self.log("POST " + self.req)
self.log("POST " + self.req + self.ssl_suf)
if self.headers.get("expect", "").lower() == "100-continue":
try:

View file

@ -109,9 +109,13 @@ class HttpConn(object):
self.log_src = self.log_src.replace("[36m", "[35m")
try:
self.s = ssl.wrap_socket(
self.s, server_side=True, certfile=self.cert_path
)
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ctx.load_cert_chain(self.cert_path)
if self.args.ssl_ver:
ctx.options &= ~self.args.ssl_flags_en
ctx.options |= self.args.ssl_flags_de
# print(repr(ctx.options))
self.s = ctx.wrap_socket(self.s, server_side=True)
except Exception as ex:
em = str(ex)