From c4e0c031072e8621033897215f0e2f2f2d25c8f2 Mon Sep 17 00:00:00 2001 From: hanishkvc Date: Thu, 4 Dec 2025 13:16:30 +0530 Subject: [PATCH] SimpleSallap:SimpleProxy: Enable https mode --- .../server/public_simplechat/docs/details.md | 10 ++++- .../local.tools/simpleproxy.py | 38 ++++++++++++++++--- .../local.tools/test-gen-self-signed.sh | 3 ++ tools/server/public_simplechat/readme.md | 1 + 4 files changed, 45 insertions(+), 7 deletions(-) create mode 100755 tools/server/public_simplechat/local.tools/test-gen-self-signed.sh diff --git a/tools/server/public_simplechat/docs/details.md b/tools/server/public_simplechat/docs/details.md index 022aaffe86..7ff53e7860 100644 --- a/tools/server/public_simplechat/docs/details.md +++ b/tools/server/public_simplechat/docs/details.md @@ -109,6 +109,8 @@ remember to * the white list of allowed.domains * review and update this to match your needs. * the shared bearer token between simpleproxy server and client ui + * the public certificate and private key files to enable https mode + * sec.certfile and sec.keyfile * other builtin tool / function calls like datetime, calculator, javascript runner, DataStore, external ai dont require the simpleproxy.py helper. @@ -294,7 +296,7 @@ It is attached to the document object. Some of these can also be updated using t * proxyAuthInsecure - shared token between simpleproxy.py server and client ui, for accessing service provided by it. - * Shared token is currently hashed with the current year and inturn handshaked over the network. In future if required one could also include a dynamic token provided by simpleproxy server during /aum handshake and running counter or so into hashed token. ALERT: However do remember that currently the handshake occurs over http and not https, so others can snoop the network and get token. Per client ui running counter and random dynamic token can help mitigate things to some extent, if required in future. + * Shared token is currently hashed with the current year and inturn handshaked over the network. In future if required one could also include a dynamic token provided by simpleproxy server during /aum handshake and running counter or so into hashed token. ALERT: However do remember that currently by default handshake occurs over http and not https, so others can snoop the network and get token. Per client ui running counter and random dynamic token can help mitigate things to some extent, if required in future. Remember to enable https mode by specifying a valid public certificate and private key. * searchUrl - specify the search engine's search url template along with the tag SEARCHWORDS in place where the search words should be substituted at runtime. @@ -570,6 +572,12 @@ The bundled simple proxy a provision for shared bearer token to be specified by the end user. One could even control what schemes are supported wrt the urls. +* by default runs in http mode. If valid sec.keyfile and sec.certfile options are specified, logic + will run in https mode. + * Remember to also update tools->proxyUrl wrt the chat session settings. + * the new url will be used for subsequent tool handshakes, however remember that the list of + tool calls supported wont get updated, till the client web ui is refreshed/reloaded. + * it tries to mimic the client/browser making the request to it by propogating header entries like user-agent, accept and accept-language from the got request to the generated request during proxying so that websites will hopefully respect the request rather than blindly rejecting it as coming from diff --git a/tools/server/public_simplechat/local.tools/simpleproxy.py b/tools/server/public_simplechat/local.tools/simpleproxy.py index fb55482cb3..2f83bbe214 100644 --- a/tools/server/public_simplechat/local.tools/simpleproxy.py +++ b/tools/server/public_simplechat/local.tools/simpleproxy.py @@ -22,8 +22,10 @@ import sys import http.server import urllib.parse import time -import urlvalidator as uv +import ssl +import traceback from typing import Callable +import urlvalidator as uv import pdfmagic as mPdf import webmagic as mWeb import debug as mDebug @@ -43,7 +45,9 @@ gConfigType = { '--debug': 'bool', '--allowed.schemes': 'list', '--allowed.domains': 'list', - '--bearer.insecure': 'str' + '--bearer.insecure': 'str', + '--sec.keyfile': 'str', + '--sec.certfile': 'str' } gConfigNeeded = [ '--allowed.schemes', '--allowed.domains', '--bearer.insecure' ] @@ -131,7 +135,7 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler): """ Handle GET requests """ - print(f"\n\n\nDBUG:ProxyHandler:GET:{self.address_string()}:{self.path}") + print(f"DBUG:ProxyHandler:GET:{self.address_string()}:{self.path}") print(f"DBUG:PH:Get:Headers:{self.headers}") pr = urllib.parse.urlparse(self.path) print(f"DBUG:ProxyHandler:GET:{pr}") @@ -158,6 +162,10 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler): self.send_response(200) self.send_headers_common() + def handle(self) -> None: + print(f"\n\n\nDBUG:ProxyHandler:Handle:RequestFrom:{self.client_address}") + return super().handle() + def handle_aum(ph: ProxyHandler, pr: urllib.parse.ParseResult): """ @@ -265,12 +273,30 @@ def process_args(args: list[str]): uv.validator_setup(gMe['--allowed.schemes'], gMe['--allowed.domains']) - -def run(): +def setup_server(): + """ + Helps setup a http/https server + """ try: gMe['serverAddr'] = ('', gMe['--port']) gMe['server'] = http.server.HTTPServer(gMe['serverAddr'], ProxyHandler) - print(f"INFO:Run:Starting on {gMe['serverAddr']}") + if gMe.get('--sec.keyfile') and gMe.get('--sec.certfile'): + sslCtxt = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + sslCtxt.load_cert_chain(certfile=gMe['--sec.certfile'], keyfile=gMe['--sec.keyfile']) + sslCtxt.minimum_version = ssl.TLSVersion.MAXIMUM_SUPPORTED + sslCtxt.maximum_version = ssl.TLSVersion.MAXIMUM_SUPPORTED + gMe['server'].socket = sslCtxt.wrap_socket(gMe['server'].socket, server_side=True) + print(f"INFO:SetupServer:Starting on {gMe['serverAddr']}:Https mode") + else: + print(f"INFO:SetupServer:Starting on {gMe['serverAddr']}:Http mode") + except Exception as exc: + print(f"ERRR:SetupServer:{traceback.format_exc()}") + raise RuntimeError(f"SetupServer:{exc}") from exc + + +def run(): + try: + setup_server() gMe['server'].serve_forever() except KeyboardInterrupt: print("INFO:Run:Shuting down...") diff --git a/tools/server/public_simplechat/local.tools/test-gen-self-signed.sh b/tools/server/public_simplechat/local.tools/test-gen-self-signed.sh new file mode 100755 index 0000000000..53183fbd61 --- /dev/null +++ b/tools/server/public_simplechat/local.tools/test-gen-self-signed.sh @@ -0,0 +1,3 @@ +openssl req -new -x509 -days 365 -noenc -out /tmp/test-cert.crt -keyout /tmp/test-priv.key -subj '/C=IN/ST=TEST/O=AnveshikaSallap/OU=SimpleProxyTEST/CN=127.0.0.1' -addext "subjectAltName = DNS:localhost, IP:127.0.0.1" +openssl x509 -in /tmp/test-cert.crt -text -noout +#openssl s_client -connect 127.0.0.1:3128 -showcerts diff --git a/tools/server/public_simplechat/readme.md b/tools/server/public_simplechat/readme.md index e33e0e2c11..4c74221158 100644 --- a/tools/server/public_simplechat/readme.md +++ b/tools/server/public_simplechat/readme.md @@ -31,6 +31,7 @@ cd tools/server/public_simplechat/local.tools; python3 ./simpleproxy.py --config - `--debug True` enables debug mode which captures internet handshake data - port defaults to 3128, can be changed from simpleproxy.json, if needed +- add sec.keyfile and sec.certfile to simpleproxy.json, for https mode ### Client