mirror of
https://github.com/tildeclub/makeuser.git
synced 2026-05-30 07:00:19 +00:00
improve data leaks
This commit is contained in:
185
znccreate.py
185
znccreate.py
@@ -1,75 +1,152 @@
|
||||
#!/usr/bin/python3.8
|
||||
# Script created/contributed by ~jmjl
|
||||
|
||||
import socket, ssl, json, time, sys
|
||||
import json
|
||||
import socket
|
||||
import ssl
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
CONFIG_FILE = "/root/.znc-conf/znc-config.json"
|
||||
|
||||
|
||||
def error_exit(message):
|
||||
print(f"{sys.argv[0]}: {message}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def usage():
|
||||
print(
|
||||
"usage:\n"
|
||||
f" {sys.argv[0]} <username> <password> [Key=Value ...]\n"
|
||||
f" {sys.argv[0]} <username> --password-stdin [Key=Value ...]",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
|
||||
def loadconf(cfgfile):
|
||||
with open(cfgfile, 'r') as f:
|
||||
with open(cfgfile, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
def send(msg):
|
||||
s.send(f"{msg}\n".encode('utf-8'))
|
||||
|
||||
cfg = loadconf("/root/.znc-conf/znc-config.json")
|
||||
def read_password_from_stdin():
|
||||
password = sys.stdin.readline()
|
||||
|
||||
readbuffer = ""
|
||||
s = socket.socket()
|
||||
if cfg.get('tls') == 'yes':
|
||||
ctx = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
|
||||
s = ctx.wrap_socket(s)
|
||||
if password == "":
|
||||
error_exit("no password received on stdin")
|
||||
|
||||
s.connect((cfg['srv'], int(cfg['port'])))
|
||||
send("NICK bot")
|
||||
send("USER bot 0 * :A bot to make users")
|
||||
password = password.rstrip("\r\n")
|
||||
|
||||
# Parse optional key=value settings after username/password.
|
||||
# Example: MaxNetworks=3 MaxClients=5
|
||||
cli_settings = {}
|
||||
for arg in sys.argv[3:]:
|
||||
if '=' in arg:
|
||||
k, v = arg.split('=', 1)
|
||||
k = k.strip()
|
||||
v = v.strip()
|
||||
if k:
|
||||
cli_settings[k] = v
|
||||
if password == "":
|
||||
error_exit("empty password received on stdin")
|
||||
|
||||
# Also allow defaults from config, but CLI wins.
|
||||
# In /root/.znc-conf/znc-config.json you may add:
|
||||
# { ..., "default_user_settings": { "MaxNetworks": "3" } }
|
||||
default_settings = cfg.get("default_user_settings", {}) or {}
|
||||
return password
|
||||
|
||||
while True:
|
||||
readbuffer += s.recv(2048).decode('utf-8', errors='ignore')
|
||||
temp = str.split(readbuffer, "\n")
|
||||
readbuffer = temp.pop()
|
||||
|
||||
for line in temp:
|
||||
line = line.rstrip("\r")
|
||||
parts = line.split()
|
||||
def parse_args(argv):
|
||||
if len(argv) < 3:
|
||||
usage()
|
||||
error_exit("not enough arguments")
|
||||
|
||||
if len(parts) < 2:
|
||||
continue
|
||||
user = argv[1]
|
||||
|
||||
# Authenticate when ZNC asks for PASS (ERR_PASSWDMISMATCH 464).
|
||||
if parts[1] == '464':
|
||||
send(f"PASS {cfg['user']}:{cfg['password']}")
|
||||
if not user:
|
||||
error_exit("username cannot be empty")
|
||||
|
||||
# On welcome (001), create user and apply settings.
|
||||
# (Preserves your original hostname check.)
|
||||
if parts[0][1:] == 'irc.znc.in' and parts[1] == '001':
|
||||
user = sys.argv[1]
|
||||
pswd = sys.argv[2]
|
||||
if argv[2] == "--password-stdin":
|
||||
password = read_password_from_stdin()
|
||||
settings_args = argv[3:]
|
||||
else:
|
||||
password = argv[2]
|
||||
settings_args = argv[3:]
|
||||
|
||||
# Create user (unchanged)
|
||||
send(f"PRIVMSG *controlpanel :AddUser {user} {pswd}")
|
||||
if not password:
|
||||
error_exit("password cannot be empty")
|
||||
|
||||
# Merge defaults + CLI, CLI overrides
|
||||
effective = dict(default_settings)
|
||||
effective.update(cli_settings)
|
||||
cli_settings = {}
|
||||
|
||||
# Apply settings like: set MaxNetworks <user> <val>
|
||||
for key, val in effective.items():
|
||||
send(f"PRIVMSG *controlpanel :set {key} {user} {val}")
|
||||
# Parse optional key=value settings after username/password.
|
||||
# Example:
|
||||
# MaxNetworks=3 MaxClients=5
|
||||
for arg in settings_args:
|
||||
if "=" in arg:
|
||||
key, value = arg.split("=", 1)
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
|
||||
print(f"Maken znc user {user}")
|
||||
sys.exit(0)
|
||||
if key:
|
||||
cli_settings[key] = value
|
||||
|
||||
return user, password, cli_settings
|
||||
|
||||
|
||||
def send(sock, msg):
|
||||
sock.send(f"{msg}\n".encode("utf-8"))
|
||||
|
||||
|
||||
def main():
|
||||
user, pswd, cli_settings = parse_args(sys.argv)
|
||||
|
||||
cfg = loadconf(CONFIG_FILE)
|
||||
|
||||
# Also allow defaults from config, but CLI wins.
|
||||
# In /root/.znc-conf/znc-config.json you may add:
|
||||
# {
|
||||
# ...,
|
||||
# "default_user_settings": {
|
||||
# "MaxNetworks": "3"
|
||||
# }
|
||||
# }
|
||||
default_settings = cfg.get("default_user_settings", {}) or {}
|
||||
|
||||
readbuffer = ""
|
||||
|
||||
sock = socket.socket()
|
||||
|
||||
if cfg.get("tls") == "yes":
|
||||
ctx = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
|
||||
sock = ctx.wrap_socket(sock)
|
||||
|
||||
sock.connect((cfg["srv"], int(cfg["port"])))
|
||||
|
||||
send(sock, "NICK bot")
|
||||
send(sock, "USER bot 0 * :A bot to make users")
|
||||
|
||||
while True:
|
||||
readbuffer += sock.recv(2048).decode("utf-8", errors="ignore")
|
||||
temp = str.split(readbuffer, "\n")
|
||||
readbuffer = temp.pop()
|
||||
|
||||
for line in temp:
|
||||
line = line.rstrip("\r")
|
||||
parts = line.split()
|
||||
|
||||
if len(parts) < 2:
|
||||
continue
|
||||
|
||||
# Authenticate when ZNC asks for PASS (ERR_PASSWDMISMATCH 464).
|
||||
if parts[1] == "464":
|
||||
send(sock, f"PASS {cfg['user']}:{cfg['password']}")
|
||||
|
||||
# On welcome (001), create user and apply settings.
|
||||
# Preserves your original hostname check.
|
||||
if parts[0][1:] == "irc.znc.in" and parts[1] == "001":
|
||||
# Create user.
|
||||
send(sock, f"PRIVMSG *controlpanel :AddUser {user} {pswd}")
|
||||
|
||||
# Merge defaults + CLI, CLI overrides.
|
||||
effective = dict(default_settings)
|
||||
effective.update(cli_settings)
|
||||
|
||||
# Apply settings like:
|
||||
# set MaxNetworks <user> <val>
|
||||
for key, val in effective.items():
|
||||
send(sock, f"PRIVMSG *controlpanel :set {key} {user} {val}")
|
||||
|
||||
print(f"Maken znc user {user}")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user