diff --git a/copyparty/__main__.py b/copyparty/__main__.py index be5c3b98..c86f6c30 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -1336,6 +1336,7 @@ def add_safety(ap): ap2.add_argument("--no-robots", action="store_true", help="adds http and html headers asking search engines to not index anything (volflag=norobots)") ap2.add_argument("--logout", metavar="H", type=float, default=8086.0, help="logout clients after \033[33mH\033[0m hours of inactivity; [\033[32m0.0028\033[0m]=10sec, [\033[32m0.1\033[0m]=6min, [\033[32m24\033[0m]=day, [\033[32m168\033[0m]=week, [\033[32m720\033[0m]=month, [\033[32m8760\033[0m]=year)") ap2.add_argument("--ban-pw", metavar="N,W,B", type=u, default="9,60,1440", help="more than \033[33mN\033[0m wrong passwords in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; disable with [\033[32mno\033[0m]") + ap2.add_argument("--ban-pwc", metavar="N,W,B", type=u, default="5,60,1440", help="more than \033[33mN\033[0m password-changes in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; disable with [\033[32mno\033[0m]") ap2.add_argument("--ban-404", metavar="N,W,B", type=u, default="50,60,1440", help="hitting more than \033[33mN\033[0m 404's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; only affects users who cannot see directory listings because their access is either g/G/h") ap2.add_argument("--ban-403", metavar="N,W,B", type=u, default="9,2,1440", help="hitting more than \033[33mN\033[0m 403's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes; [\033[32m1440\033[0m]=day, [\033[32m10080\033[0m]=week, [\033[32m43200\033[0m]=month") ap2.add_argument("--ban-422", metavar="N,W,B", type=u, default="9,2,1440", help="hitting more than \033[33mN\033[0m 422's in \033[33mW\033[0m minutes = ban for \033[33mB\033[0m minutes (invalid requests, attempted exploits ++)") diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 9d12facb..02e56a22 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -2912,6 +2912,7 @@ class HttpCli(object): ok, msg = self.asrv.chpw(self.conn.hsrv.broker, self.uname, pwd) if ok: + self.cbonk(self.conn.hsrv.gpwc, pwd, "pw", "too many password changes") ok, msg = self.get_pwd_cookie(pwd) if ok: msg = "new password OK" diff --git a/copyparty/httpsrv.py b/copyparty/httpsrv.py index 2e5cc69e..56638003 100644 --- a/copyparty/httpsrv.py +++ b/copyparty/httpsrv.py @@ -123,6 +123,7 @@ class HttpSrv(object): self.nm = NetMap([], []) self.ssdp: Optional["SSDPr"] = None self.gpwd = Garda(self.args.ban_pw) + self.gpwc = Garda(self.args.ban_pwc) self.g404 = Garda(self.args.ban_404) self.g403 = Garda(self.args.ban_403) self.g422 = Garda(self.args.ban_422, False) diff --git a/copyparty/svchub.py b/copyparty/svchub.py index e7c293cc..751fd566 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -168,6 +168,7 @@ class SvcHub(object): # for non-http clients (ftp, tftp) self.bans: dict[str, int] = {} self.gpwd = Garda(self.args.ban_pw) + self.gpwc = Garda(self.args.ban_pwc) self.g404 = Garda(self.args.ban_404) self.g403 = Garda(self.args.ban_403) self.g422 = Garda(self.args.ban_422, False) diff --git a/tests/util.py b/tests/util.py index 147c3b64..1f732920 100644 --- a/tests/util.py +++ b/tests/util.py @@ -164,7 +164,7 @@ class Cfg(Namespace): ex = "ah_alg bname chmod_f chpw_db doctitle df exit favico idp_h_usr ipa html_head lg_sba lg_sbf log_fk md_sba md_sbf name og_desc og_site og_th og_title og_title_a og_title_v og_title_i shr tcolor textfiles unlist vname xff_src zipmaxt R RS SR" ka.update(**{k: "" for k in ex.split()}) - ex = "ban_403 ban_404 ban_422 ban_pw ban_url spinner" + ex = "ban_403 ban_404 ban_422 ban_pw ban_pwc ban_url spinner" ka.update(**{k: "no" for k in ex.split()}) ex = "ext_th grp on403 on404 xac xad xar xau xban xbc xbd xbr xbu xiu xm"