mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
more ssl options
This commit is contained in:
parent
75c73f7ba7
commit
aaf9d53be9
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -56,5 +56,9 @@
|
||||||
// things you may wanna edit:
|
// things you may wanna edit:
|
||||||
//
|
//
|
||||||
"python.pythonPath": "/usr/bin/python3",
|
"python.pythonPath": "/usr/bin/python3",
|
||||||
|
"python.formatting.blackArgs": [
|
||||||
|
"-t",
|
||||||
|
"py27"
|
||||||
|
],
|
||||||
//"python.linting.enabled": true,
|
//"python.linting.enabled": true,
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@ __url__ = "https://github.com/9001/copyparty/"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
import shutil
|
import shutil
|
||||||
import filecmp
|
import filecmp
|
||||||
|
@ -20,7 +21,13 @@ from textwrap import dedent
|
||||||
from .__init__ import E, WINDOWS, VT100
|
from .__init__ import E, WINDOWS, VT100
|
||||||
from .__version__ import S_VERSION, S_BUILD_DT, CODENAME
|
from .__version__ import S_VERSION, S_BUILD_DT, CODENAME
|
||||||
from .svchub import SvcHub
|
from .svchub import SvcHub
|
||||||
from .util import py_desc
|
from .util import py_desc, align_tab
|
||||||
|
|
||||||
|
HAVE_SSL = True
|
||||||
|
try:
|
||||||
|
import ssl
|
||||||
|
except:
|
||||||
|
HAVE_SSL = False
|
||||||
|
|
||||||
|
|
||||||
class RiceFormatter(argparse.HelpFormatter):
|
class RiceFormatter(argparse.HelpFormatter):
|
||||||
|
@ -86,9 +93,7 @@ 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
|
# 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):
|
def configure_ssl_ver(al):
|
||||||
import ssl
|
|
||||||
|
|
||||||
def terse_sslver(txt):
|
def terse_sslver(txt):
|
||||||
txt = txt.lower()
|
txt = txt.lower()
|
||||||
for c in ["_", "v", "."]:
|
for c in ["_", "v", "."]:
|
||||||
|
@ -107,7 +112,7 @@ def configure_ssl(al):
|
||||||
avail = [terse_sslver(x[6:]) for x in flags]
|
avail = [terse_sslver(x[6:]) for x in flags]
|
||||||
avail = " ".join(sorted(avail) + ["all"])
|
avail = " ".join(sorted(avail) + ["all"])
|
||||||
print("\navailable ssl/tls versions:\n " + avail)
|
print("\navailable ssl/tls versions:\n " + avail)
|
||||||
return
|
sys.exit(0)
|
||||||
|
|
||||||
al.ssl_flags_en = 0
|
al.ssl_flags_en = 0
|
||||||
al.ssl_flags_de = 0
|
al.ssl_flags_de = 0
|
||||||
|
@ -131,6 +136,31 @@ def configure_ssl(al):
|
||||||
# think i need that beer now
|
# think i need that beer now
|
||||||
|
|
||||||
|
|
||||||
|
def configure_ssl_ciphers(al):
|
||||||
|
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||||
|
if al.ssl_ver:
|
||||||
|
ctx.options &= ~al.ssl_flags_en
|
||||||
|
ctx.options |= al.ssl_flags_de
|
||||||
|
|
||||||
|
is_help = al.ciphers == "help"
|
||||||
|
|
||||||
|
if al.ciphers:
|
||||||
|
try:
|
||||||
|
ctx.set_ciphers(al.ciphers)
|
||||||
|
except:
|
||||||
|
if not is_help:
|
||||||
|
print("\n\033[1;31mfailed to set ciphers\033[0m\n")
|
||||||
|
|
||||||
|
if not hasattr(ctx, "get_ciphers"):
|
||||||
|
print("cannot read cipher list: openssl or python too old")
|
||||||
|
else:
|
||||||
|
ciphers = [x["description"] for x in ctx.get_ciphers()]
|
||||||
|
print("\n ".join(["\nenabled ciphers:"] + align_tab(ciphers) + [""]))
|
||||||
|
|
||||||
|
if is_help:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
time.strptime("19970815", "%Y%m%d") # python#7980
|
time.strptime("19970815", "%Y%m%d") # python#7980
|
||||||
if WINDOWS:
|
if WINDOWS:
|
||||||
|
@ -142,7 +172,8 @@ def main():
|
||||||
print(f.format(S_VERSION, CODENAME, S_BUILD_DT, desc))
|
print(f.format(S_VERSION, CODENAME, S_BUILD_DT, desc))
|
||||||
|
|
||||||
ensure_locale()
|
ensure_locale()
|
||||||
ensure_cert()
|
if HAVE_SSL:
|
||||||
|
ensure_cert()
|
||||||
|
|
||||||
ap = argparse.ArgumentParser(
|
ap = argparse.ArgumentParser(
|
||||||
formatter_class=RiceFormatter,
|
formatter_class=RiceFormatter,
|
||||||
|
@ -204,9 +235,14 @@ def main():
|
||||||
ap.add_argument("-nid", action="store_true", help="no info disk-usage")
|
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("--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("--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")
|
|
||||||
ap.add_argument("--https-only", action="store_true", help="disable plaintext")
|
ap2 = ap.add_argument_group('SSL/TLS options')
|
||||||
ap.add_argument("--http-only", action="store_true", help="disable ssl/tls")
|
ap2.add_argument("--http-only", action="store_true", help="disable ssl/tls")
|
||||||
|
ap2.add_argument("--https-only", action="store_true", help="disable plaintext")
|
||||||
|
ap2.add_argument("--ssl-ver", type=str, help="ssl/tls versions to allow")
|
||||||
|
ap2.add_argument("--ciphers", metavar="LIST", help="set allowed ciphers")
|
||||||
|
ap2.add_argument("--ssl-dbg", action="store_true", help="dump some tls info")
|
||||||
|
ap2.add_argument("--ssl-log", metavar="PATH", help="log master secrets")
|
||||||
al = ap.parse_args()
|
al = ap.parse_args()
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
|
@ -220,8 +256,14 @@ def main():
|
||||||
except:
|
except:
|
||||||
raise Exception("invalid value for -p")
|
raise Exception("invalid value for -p")
|
||||||
|
|
||||||
if al.ssl_ver:
|
if HAVE_SSL:
|
||||||
configure_ssl(al)
|
if al.ssl_ver:
|
||||||
|
configure_ssl_ver(al)
|
||||||
|
|
||||||
|
if al.ciphers:
|
||||||
|
configure_ssl_ciphers(al)
|
||||||
|
else:
|
||||||
|
print("\033[33m ssl module does not exist; cannot enable https\033[0m\n")
|
||||||
|
|
||||||
SvcHub(al).run()
|
SvcHub(al).run()
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,15 @@ from __future__ import print_function, unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import ssl
|
|
||||||
import time
|
import time
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
HAVE_SSL = True
|
||||||
|
try:
|
||||||
|
import ssl
|
||||||
|
except:
|
||||||
|
HAVE_SSL = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import jinja2
|
import jinja2
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -107,7 +112,7 @@ class HttpConn(object):
|
||||||
self.sr = None
|
self.sr = None
|
||||||
if self.args.https_only:
|
if self.args.https_only:
|
||||||
is_https = True
|
is_https = True
|
||||||
elif self.args.http_only:
|
elif self.args.http_only or not HAVE_SSL:
|
||||||
is_https = False
|
is_https = False
|
||||||
else:
|
else:
|
||||||
is_https = self._detect_https()
|
is_https = self._detect_https()
|
||||||
|
@ -125,7 +130,28 @@ class HttpConn(object):
|
||||||
ctx.options &= ~self.args.ssl_flags_en
|
ctx.options &= ~self.args.ssl_flags_en
|
||||||
ctx.options |= self.args.ssl_flags_de
|
ctx.options |= self.args.ssl_flags_de
|
||||||
# print(repr(ctx.options))
|
# print(repr(ctx.options))
|
||||||
|
|
||||||
|
if self.args.ssl_log:
|
||||||
|
try:
|
||||||
|
ctx.keylog_filename = self.args.ssl_log
|
||||||
|
except:
|
||||||
|
self.log("keylog failed; openssl or python too old")
|
||||||
|
|
||||||
|
if self.args.ciphers:
|
||||||
|
ctx.set_ciphers(self.args.ciphers)
|
||||||
|
|
||||||
self.s = ctx.wrap_socket(self.s, server_side=True)
|
self.s = ctx.wrap_socket(self.s, server_side=True)
|
||||||
|
if self.args.ssl_dbg and hasattr(self.s, "shared_ciphers"):
|
||||||
|
overlap = [y[::-1] for y in self.s.shared_ciphers()]
|
||||||
|
lines = [str(x) for x in (["TLS cipher overlap:"] + overlap)]
|
||||||
|
self.log("\n".join(lines))
|
||||||
|
for k, v in [
|
||||||
|
["compression", self.s.compression()],
|
||||||
|
["ALPN proto", self.s.selected_alpn_protocol()],
|
||||||
|
["NPN proto", self.s.selected_npn_protocol()],
|
||||||
|
]:
|
||||||
|
self.log("TLS {}: {}".format(k, v or "nah"))
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
em = str(ex)
|
em = str(ex)
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ def ren_open(fname, *args, **kwargs):
|
||||||
with open(fname, *args, **kwargs) as f:
|
with open(fname, *args, **kwargs) as f:
|
||||||
yield {"orz": [f, fname]}
|
yield {"orz": [f, fname]}
|
||||||
return
|
return
|
||||||
|
|
||||||
orig_name = fname
|
orig_name = fname
|
||||||
bname = fname
|
bname = fname
|
||||||
ext = ""
|
ext = ""
|
||||||
|
@ -632,10 +632,10 @@ def sendfile_kern(lower, upper, f, s):
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
# print("sendfile: " + repr(ex))
|
# print("sendfile: " + repr(ex))
|
||||||
n = 0
|
n = 0
|
||||||
|
|
||||||
if n <= 0:
|
if n <= 0:
|
||||||
return upper - ofs
|
return upper - ofs
|
||||||
|
|
||||||
ofs += n
|
ofs += n
|
||||||
# print("sendfile: ok, sent {} now, {} total, {} remains".format(n, ofs - lower, upper - ofs))
|
# print("sendfile: ok, sent {} now, {} total, {} remains".format(n, ofs - lower, upper - ofs))
|
||||||
|
|
||||||
|
@ -718,6 +718,22 @@ def py_desc():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def align_tab(lines):
|
||||||
|
rows = []
|
||||||
|
ncols = 0
|
||||||
|
for ln in lines:
|
||||||
|
row = [x for x in ln.split(" ") if x]
|
||||||
|
ncols = max(ncols, len(row))
|
||||||
|
rows.append(row)
|
||||||
|
|
||||||
|
lens = [0] * ncols
|
||||||
|
for row in rows:
|
||||||
|
for n, col in enumerate(row):
|
||||||
|
lens[n] = max(lens[n], len(col))
|
||||||
|
|
||||||
|
return ["".join(x.ljust(y + 2) for x, y in zip(row, lens)) for row in rows]
|
||||||
|
|
||||||
|
|
||||||
class Pebkac(Exception):
|
class Pebkac(Exception):
|
||||||
def __init__(self, code, msg=None):
|
def __init__(self, code, msg=None):
|
||||||
super(Pebkac, self).__init__(msg or HTTPCODE[code])
|
super(Pebkac, self).__init__(msg or HTTPCODE[code])
|
||||||
|
|
Loading…
Reference in a new issue