mirror of
https://github.com/9001/copyparty.git
synced 2026-06-18 20:22:27 -06:00
use ${ENV} syntax for env-vars;
only expand environment-variables of the form ${ENV}
by default, crash on startup if the old $ENV syntax is found,
explaning that the old syntax can be enabled with an option
This commit is contained in:
parent
b31f29024a
commit
cbd82b654a
|
|
@ -2542,6 +2542,7 @@ buggy feature? rip it out by setting any of the following environment variables
|
|||
| -------------------- | ------------ |
|
||||
| `PRTY_NO_CTYPES` | do not use features from external libraries such as kernel32 |
|
||||
| `PRTY_NO_DB_LOCK` | do not lock session/shares-databases for exclusive access |
|
||||
| `PRTY_NO_ENVEXPAND` | do not expand environment-variables in configs and args |
|
||||
| `PRTY_NO_IFADDR` | disable ip/nic discovery by poking into your OS with ctypes |
|
||||
| `PRTY_NO_IMPRESO` | do not try to load js/css files using `importlib.resources` |
|
||||
| `PRTY_NO_IPV6` | disable some ipv6 support (should not be necessary since windows 2000) |
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
# and copyparty replaces %Y-%m%d with Year-MonthDay, so the
|
||||
# full path will be something like /var/log/copyparty/2023-1130.txt
|
||||
# (note: enable compression by adding .xz at the end)
|
||||
# q, lo: $LOGS_DIRECTORY/%Y-%m%d.log
|
||||
# q, lo: ${LOGS_DIRECTORY}/%Y-%m%d.log
|
||||
|
||||
# p: 80,443,3923 # listen on 80/443 as well (requires CAP_NET_BIND_SERVICE)
|
||||
# i: 127.0.0.1 # only allow connections from localhost (reverse-proxies)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# and copyparty replaces %Y-%m%d with Year-MonthDay, so the
|
||||
# full path will be something like /var/log/copyparty/2023-1130.txt
|
||||
# (note: enable compression by adding .xz at the end)
|
||||
q, lo: $LOGS_DIRECTORY/%Y-%m%d.log
|
||||
q, lo: ${LOGS_DIRECTORY}/%Y-%m%d.log
|
||||
|
||||
# enable version-checker by uncommenting one of the 'vc-url' lines below; this will
|
||||
# periodically check if your copyparty version has a known security vulnerability,
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ from .util import (
|
|||
b64enc,
|
||||
ctypes,
|
||||
dedent,
|
||||
expand_osenv_c,
|
||||
expand_osenv_cs,
|
||||
expand_osenv_noop,
|
||||
expand_osenv_s,
|
||||
has_resource,
|
||||
load_resource,
|
||||
min_ex,
|
||||
|
|
@ -427,9 +431,22 @@ def configure_ssl_ciphers(al: argparse.Namespace) -> None:
|
|||
sys.exit(0)
|
||||
|
||||
|
||||
def expand_cvars(argv) -> list[str]:
|
||||
n = 0
|
||||
for v in argv:
|
||||
if "=" in v:
|
||||
a, b = v.split("=", 1)
|
||||
v = "%s=%s" % (a, os.path.expanduser(expand_osenv_c(b)))
|
||||
else:
|
||||
v = os.path.expanduser(expand_osenv_c(v))
|
||||
argv[n] = v
|
||||
n += 1
|
||||
return argv
|
||||
|
||||
|
||||
def args_from_cfg(cfg_path: str) -> list[str]:
|
||||
lines: list[str] = []
|
||||
expand_config_file(None, lines, cfg_path, "")
|
||||
expand_config_file(None, expand_osenv_c, lines, cfg_path, "")
|
||||
lines = upgrade_cfg_fmt(None, argparse.Namespace(vc=False), lines, "")
|
||||
|
||||
ret: list[str] = []
|
||||
|
|
@ -453,10 +470,12 @@ def args_from_cfg(cfg_path: str) -> list[str]:
|
|||
else:
|
||||
ret.append(prefix + k + "=" + v)
|
||||
|
||||
return ret
|
||||
return expand_cvars(ret)
|
||||
|
||||
|
||||
def expand_cfg(argv) -> list[str]:
|
||||
argv = expand_cvars(argv)
|
||||
|
||||
if CFG_DEF:
|
||||
supp = args_from_cfg(CFG_DEF[0])
|
||||
argv = argv[:1] + supp + argv[1:]
|
||||
|
|
@ -1197,6 +1216,7 @@ def add_general(ap, nc, srvname):
|
|||
ap2.add_argument("--name-url", metavar="TXT", type=u, help="URL for server name hyperlink (displayed topleft in browser)")
|
||||
ap2.add_argument("--name-html", type=u, help=argparse.SUPPRESS)
|
||||
ap2.add_argument("--site", metavar="URL", type=u, default="", help="public URL to assume when creating links; example: [\033[32mhttps://example.com/\033[0m]")
|
||||
ap2.add_argument("--env-expand", metavar="N", type=int, default=-1, help="syntax to expect for environment-variables to expand in config-files; [\033[32m0\033[0m]=disable, [\033[32m1\033[0m]=$VAR (old syntax (scary)), [\033[32m2\033[0m]=${VAR} (new syntax (recommended))")
|
||||
ap2.add_argument("--mime", metavar="EXT=MIME", type=u, action="append", help="\033[34mREPEATABLE:\033[0m map file \033[33mEXT\033[0mension to \033[33mMIME\033[0mtype, for example [\033[32mjpg=image/jpeg\033[0m]")
|
||||
ap2.add_argument("--mimes", action="store_true", help="list default mimetype mapping and exit")
|
||||
ap2.add_argument("--rmagic", action="store_true", help="do expensive analysis to improve accuracy of returned mimetypes; will make file-downloads, rss, and webdav slower (volflag=rmagic)")
|
||||
|
|
@ -2179,6 +2199,15 @@ def main(argv: Optional[list[str]] = None) -> None:
|
|||
|
||||
quotecheck(al)
|
||||
|
||||
if al.env_expand == 2:
|
||||
al.shenvexp = expand_osenv_c
|
||||
elif al.env_expand == 1:
|
||||
al.shenvexp = expand_osenv_s
|
||||
elif al.env_expand == 0:
|
||||
al.shenvexp = expand_osenv_noop
|
||||
else:
|
||||
al.shenvexp = expand_osenv_cs
|
||||
|
||||
if al.chdir:
|
||||
os.chdir(al.chdir)
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ if HAVE_SQLITE3:
|
|||
if True: # pylint: disable=using-constant-test
|
||||
from collections.abc import Iterable
|
||||
|
||||
from typing import Any, Generator, Optional, Sequence, Union
|
||||
from typing import Any, Callable, Generator, Optional, Sequence, Union
|
||||
|
||||
from .util import NamedLogger, RootLogger
|
||||
|
||||
|
|
@ -541,13 +541,11 @@ class VFS(object):
|
|||
|
||||
hist = flags.get("hist")
|
||||
if hist and hist != "-":
|
||||
zs = "{}/{}".format(hist.rstrip("/"), name)
|
||||
flags["hist"] = os.path.expandvars(os.path.expanduser(zs))
|
||||
flags["hist"] = "%s/%s" % (hist.rstrip("/"), name)
|
||||
|
||||
dbp = flags.get("dbpath")
|
||||
if dbp and dbp != "-":
|
||||
zs = "{}/{}".format(dbp.rstrip("/"), name)
|
||||
flags["dbpath"] = os.path.expandvars(os.path.expanduser(zs))
|
||||
flags["dbpath"] = "%s/%s" % (dbp.rstrip("/"), name)
|
||||
|
||||
return flags
|
||||
|
||||
|
|
@ -1279,7 +1277,7 @@ class AuthSrv(object):
|
|||
daxs: dict[str, AXS],
|
||||
mflags: dict[str, dict[str, Any]],
|
||||
) -> tuple[str, str]:
|
||||
src = os.path.expandvars(os.path.expanduser(src))
|
||||
src = os.path.expanduser(self.args.shenvexp(src))
|
||||
src = absreal(src)
|
||||
dst = dst.strip("/")
|
||||
|
||||
|
|
@ -1372,7 +1370,7 @@ class AuthSrv(object):
|
|||
) -> None:
|
||||
self.line_ctr = 0
|
||||
|
||||
expand_config_file(self.log, cfg_lines, fp, "")
|
||||
expand_config_file(self.log, self.args.shenvexp, cfg_lines, fp, "")
|
||||
if self.args.vc:
|
||||
lns = ["{:4}: {}".format(n, s) for n, s in enumerate(cfg_lines, 1)]
|
||||
self.log("expanded config file (unprocessed):\n" + "\n".join(lns))
|
||||
|
|
@ -2174,7 +2172,7 @@ class AuthSrv(object):
|
|||
if vflag == "-":
|
||||
pass
|
||||
elif vflag:
|
||||
vflag = os.path.expandvars(os.path.expanduser(vflag))
|
||||
vflag = os.path.expanduser(self.args.shenvexp(vflag))
|
||||
vol.histpath = vol.dbpath = uncyg(vflag) if WINDOWS else vflag
|
||||
elif self.args.hist:
|
||||
for nch in range(len(hid)):
|
||||
|
|
@ -2209,7 +2207,7 @@ class AuthSrv(object):
|
|||
if vflag == "-":
|
||||
pass
|
||||
elif vflag:
|
||||
vflag = os.path.expandvars(os.path.expanduser(vflag))
|
||||
vflag = os.path.expanduser(self.args.shenvexp(vflag))
|
||||
vol.dbpath = uncyg(vflag) if WINDOWS else vflag
|
||||
elif self.args.dbpath:
|
||||
for nch in range(len(hid)):
|
||||
|
|
@ -3964,10 +3962,14 @@ def split_cfg_ln(ln: str) -> dict[str, Any]:
|
|||
|
||||
|
||||
def expand_config_file(
|
||||
log: Optional["NamedLogger"], ret: list[str], fp: str, ipath: str
|
||||
log: Optional["NamedLogger"],
|
||||
shenvexp: "Callable[[str], str]",
|
||||
ret: list[str],
|
||||
fp: str,
|
||||
ipath: str,
|
||||
) -> None:
|
||||
"""expand all % file includes"""
|
||||
fp = absreal(fp)
|
||||
fp = absreal(os.path.expanduser(shenvexp(fp)))
|
||||
if len(ipath.split(" -> ")) > 64:
|
||||
raise Exception("hit max depth of 64 includes")
|
||||
|
||||
|
|
@ -3998,7 +4000,7 @@ def expand_config_file(
|
|||
if fp2 in ipath:
|
||||
continue
|
||||
|
||||
expand_config_file(log, ret, fp2, ipath)
|
||||
expand_config_file(log, shenvexp, ret, fp2, ipath)
|
||||
|
||||
return
|
||||
|
||||
|
|
@ -4023,7 +4025,7 @@ def expand_config_file(
|
|||
fp2 = ln[1:].strip()
|
||||
fp2 = os.path.join(os.path.dirname(fp), fp2)
|
||||
ofs = len(ret)
|
||||
expand_config_file(log, ret, fp2, ipath)
|
||||
expand_config_file(log, shenvexp, ret, fp2, ipath)
|
||||
for n in range(ofs, len(ret)):
|
||||
ret[n] = pad + ret[n]
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from .util import (
|
|||
FFMPEG_URL,
|
||||
REKOBO_LKEY,
|
||||
VF_CAREFUL,
|
||||
expand_osenv_c,
|
||||
fsenc,
|
||||
gzip,
|
||||
min_ex,
|
||||
|
|
@ -86,7 +87,7 @@ class MParser(object):
|
|||
|
||||
while True:
|
||||
try:
|
||||
bp = os.path.expanduser(args)
|
||||
bp = os.path.expanduser(expand_osenv_c(args))
|
||||
if WINDOWS:
|
||||
bp = uncyg(bp)
|
||||
|
||||
|
|
|
|||
|
|
@ -1133,17 +1133,23 @@ class SvcHub(object):
|
|||
al.th_coversd_set = set(al.th_coversd)
|
||||
|
||||
for k in "c".split(" "):
|
||||
if self.args.env_expand in (0, 2):
|
||||
break
|
||||
|
||||
vl = getattr(al, k)
|
||||
if not vl:
|
||||
continue
|
||||
|
||||
vl = [os.path.expandvars(os.path.expanduser(x)) for x in vl]
|
||||
vl = [os.path.expanduser(self.args.shenvexp(x)) for x in vl]
|
||||
setattr(al, k, vl)
|
||||
|
||||
for k in "lo hist dbpath ssl_log".split(" "):
|
||||
if self.args.env_expand in (0, 2):
|
||||
break
|
||||
|
||||
vs = getattr(al, k)
|
||||
if vs:
|
||||
vs = os.path.expandvars(os.path.expanduser(vs))
|
||||
vs = os.path.expanduser(self.args.shenvexp(vs))
|
||||
setattr(al, k, vs)
|
||||
|
||||
for k in "idp_adm stats_u".split(" "):
|
||||
|
|
|
|||
|
|
@ -1562,6 +1562,43 @@ def dedent(txt: str) -> str:
|
|||
return "\n".join([ln[pad:] for ln in lns])
|
||||
|
||||
|
||||
def expand_osenv_noop(txt) -> str:
|
||||
return txt
|
||||
|
||||
|
||||
def _expand_osenv_c(txt) -> str:
|
||||
if "${" not in txt:
|
||||
return txt
|
||||
zsl = txt.split("${")
|
||||
ret = zsl[0]
|
||||
for v in zsl[1:]:
|
||||
if "}" not in v:
|
||||
raise Exception("missing '}' after %r in config-value %r" % (v, txt))
|
||||
a, b = v.split("}", 1)
|
||||
try:
|
||||
ret += os.environ[a] + b
|
||||
except:
|
||||
raise Exception("env-var %r not defined; config-value %r" % (a, txt))
|
||||
return ret
|
||||
|
||||
|
||||
if os.environ.get("PRTY_NO_ENVEXPAND"):
|
||||
expand_osenv_c = expand_osenv_noop
|
||||
expand_osenv_s = expand_osenv_noop
|
||||
else:
|
||||
expand_osenv_c = _expand_osenv_c
|
||||
expand_osenv_s = os.path.expandvars
|
||||
|
||||
|
||||
def expand_osenv_cs(txt) -> str:
|
||||
a = expand_osenv_c(txt)
|
||||
b = expand_osenv_s(txt)
|
||||
if a == b:
|
||||
return a
|
||||
t = "config-value %r is using the old syntax for environment-variables; choose one of the following options:\noption 1: update the config-value to the new syntax, ${VAR} instead of $VAR or %%VAR%%\noption 2: tell copyparty to allow the old syntax with global-option --env-expand 1 (risky)\noption 3: tell copyparty to only use the new syntax (and not expand this variable) with global-option --env-expand 2\noption 4: disable all environment-variable expansions with PRTY_NO_ENVEXPAND=1 or global-option --env-expand 0"
|
||||
raise Exception(t % (txt,))
|
||||
|
||||
|
||||
def rice_tid() -> str:
|
||||
tid = threading.current_thread().ident
|
||||
c = sunpack(b"B" * 5, spack(b">Q", tid)[-5:])
|
||||
|
|
@ -3847,7 +3884,7 @@ def _parsehook(
|
|||
|
||||
argv = cmd.split(",") if "," in cmd else [cmd]
|
||||
|
||||
argv[0] = os.path.expandvars(os.path.expanduser(argv[0]))
|
||||
argv[0] = os.path.expanduser(expand_osenv_c(argv[0]))
|
||||
|
||||
return areq, chk, imp, fork, sin, jtxt, wait, sp_ka, argv
|
||||
|
||||
|
|
@ -4190,7 +4227,7 @@ def loadpy(ap: str, hot: bool) -> Any:
|
|||
depending on what other inconveniently named files happen
|
||||
to be in the same folder
|
||||
"""
|
||||
ap = os.path.expandvars(os.path.expanduser(ap))
|
||||
ap = os.path.expanduser(expand_osenv_c(ap))
|
||||
mdir, mfile = os.path.split(absreal(ap))
|
||||
mname = mfile.rsplit(".", 1)[0]
|
||||
sys.path.insert(0, mdir)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ from copyparty.broker_thr import BrokerThr
|
|||
from copyparty.ico import Ico
|
||||
from copyparty.u2idx import U2idx
|
||||
from copyparty.up2k import Up2k
|
||||
from copyparty.util import FHC, CachedDict, Garda, Unrecv
|
||||
from copyparty.util import FHC, CachedDict, Garda, Unrecv, expand_osenv_c
|
||||
|
||||
init_E(E)
|
||||
|
||||
|
|
@ -195,6 +195,7 @@ class Cfg(Namespace):
|
|||
du_who="all",
|
||||
dk_salt="b" * 16,
|
||||
fk_salt="a" * 16,
|
||||
env_expand=2,
|
||||
fsnt="lin",
|
||||
grp_all="acct",
|
||||
idp_gsep=re.compile("[|:;+,]"),
|
||||
|
|
@ -217,6 +218,7 @@ class Cfg(Namespace):
|
|||
rw_edit="md",
|
||||
s_rd_sz=256 * 1024,
|
||||
s_wr_sz=256 * 1024,
|
||||
shenvexp=expand_osenv_c,
|
||||
shr_who="auth",
|
||||
sort="href",
|
||||
srch_hits=99999,
|
||||
|
|
|
|||
Loading…
Reference in a new issue