commit 53852868aa01b3554a678072a02176fdf1d65adf
Author: Nathan Coad
Date: Wed Dec 10 13:38:11 2025 +1100
initial commit
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..94a8f6a
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,21 @@
+FROM python:3.12-slim
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ ca-certificates \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN ln -sf /usr/local/bin/python3 /usr/bin/python3
+
+WORKDIR /app
+
+COPY . /app/
+RUN mkdir -p /app/cgi-bin \
+ && cp /app/*.py /app/*.cgi /app/cgi-bin/ \
+ && cp /app/words.txt /app/cgi-bin/ \
+ && cp /app/*.html /app/cgi-bin/
+
+RUN chmod +x /app/index.cgi
+RUN chmod +x /app/cgi-bin/*.py /app/cgi-bin/*.cgi || true
+
+EXPOSE 8000
+CMD ["python", "-m", "http.server", "8000", "--cgi"]
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..31e60c1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+Code from https://untroubled.org/pwgen/ppgen.cgi modified to work as a docker container.
+
+Wordlist from https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt
\ No newline at end of file
diff --git a/common.py b/common.py
new file mode 100644
index 0000000..4d29941
--- /dev/null
+++ b/common.py
@@ -0,0 +1,69 @@
+import cgitb
+cgitb.enable()
+
+import cgi
+import os
+import sys
+
+def bool(s):
+ try: return int(s)
+ except ValueError: pass
+ return s == 'on'
+
+def commafy(s):
+ s = str(int(s))
+ o = ''
+ while len(s) > 3:
+ o = ',' + s[-3:] + o
+ s = s[:-3]
+ return s + o
+
+def escape(s):
+ return str(s).replace('&', '&').replace('<', '<').replace('>', '>')
+
+def form_get(form, name, default, conv=str):
+ try:
+ item = form[name]
+ except KeyError:
+ return default
+ if item.file:
+ print("Uploads are not allowed!")
+ sys.exit(1)
+ if type(item.value) is not type(''):
+ print("Multiple values are not allowed!")
+ sys.exit(1)
+ try:
+ value = conv(item.value)
+ except:
+ print("'%s' failed to convert" % name)
+ sys.exit(1)
+ return value
+
+class EvalDict:
+ def __init__(self, values):
+ self.values = values
+ def __getitem__(self, key):
+ return escape(eval(key, self.values))
+
+def row(a,b,bold=0):
+ pre = post = ''
+ if bold:
+ pre = ''
+ post = ''
+ print('| %s: | %s%s%s |
' % (
+ a, pre, b, post ))
+def table_start(): print('
')
+def table_end(): print('
')
+
+def dumpfile(filename, dict=None):
+ # Always resolve relative to this file's directory
+ here = os.path.dirname(__file__)
+ path = os.path.join(here, filename)
+
+ with open(path, encoding="utf-8") as f:
+ data = f.read()
+
+ if dict is not None:
+ data = data % dict
+
+ sys.stdout.write(data)
diff --git a/footer.html b/footer.html
new file mode 100644
index 0000000..545302b
--- /dev/null
+++ b/footer.html
@@ -0,0 +1,20 @@
+
+
+Notes:
+
+- No data generated by this page is stored on the server at any point.
+In other words, we aren't recording your passwords.
+
+- The data used to generate the passwords is derived from Linux's
+/dev/urandom secure data source, and is carefully masked to prevent
+biasing or truncation.
+
+- Unless this form is accessed via a secure session (ie HTTPS or a
+tunnel), the password will be susceptible to being sniffed as it is
+being transmitted. Use the appropriate precautions.
+
+
+
+
+