SimpleChatTC:SimpleProxy: once in a bluemoon transformed bearer
instead of using the shared bearer token as is, hash it with current year and use the hash. keep /aum path out of auth check. in future bearer token could be transformed more often, as well as with additional nounce/dynamic token from server got during initial /aum handshake as also running counter and so ... NOTE: All these circus not good enough, given that currently the simpleproxy.py handshakes work over http. However these skeletons put in place, for future, if needed. TODO: There is a once in a bluemoon race when the year transitions between client generating the request and server handling the req. But other wise year transitions dont matter bcas client always creates fresh token, and server checks for year change to genrate fresh token if required.
This commit is contained in:
parent
0552ff9098
commit
84403973cd
|
|
@ -32,6 +32,7 @@ gMe = {
|
|||
'--port': 3128,
|
||||
'--config': '/dev/null',
|
||||
'--debug': False,
|
||||
'bearer.transformed.year': "",
|
||||
'server': None
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +47,22 @@ gConfigType = {
|
|||
gConfigNeeded = [ '--allowed.domains', '--bearer.insecure' ]
|
||||
|
||||
|
||||
def bearer_transform():
|
||||
"""
|
||||
Transform the raw bearer token to the network handshaked token,
|
||||
if and when needed.
|
||||
"""
|
||||
global gMe
|
||||
year = str(time.gmtime().tm_year)
|
||||
if gMe['bearer.transformed.year'] == year:
|
||||
return
|
||||
import hashlib
|
||||
s256 = hashlib.sha256(year.encode('utf-8'))
|
||||
s256.update(gMe['--bearer.insecure'].encode('utf-8'))
|
||||
gMe['--bearer.transformed'] = s256.hexdigest()
|
||||
gMe['bearer.transformed.year'] = year
|
||||
|
||||
|
||||
class ProxyHandler(http.server.BaseHTTPRequestHandler):
|
||||
"""
|
||||
Implements the logic for handling requests sent to this server.
|
||||
|
|
@ -75,6 +92,7 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler):
|
|||
Simple Bearer authorization
|
||||
ALERT: For multiple reasons, this is a very insecure implementation.
|
||||
"""
|
||||
bearer_transform()
|
||||
authline = self.headers['Authorization']
|
||||
if authline == None:
|
||||
return { 'AllOk': False, 'Msg': "No auth line" }
|
||||
|
|
@ -83,7 +101,7 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler):
|
|||
return { 'AllOk': False, 'Msg': "Invalid auth line" }
|
||||
if authlineA[0] != 'Bearer':
|
||||
return { 'AllOk': False, 'Msg': "Invalid auth type" }
|
||||
if authlineA[1] != gMe['--bearer.insecure']:
|
||||
if authlineA[1] != gMe['--bearer.transformed']:
|
||||
return { 'AllOk': False, 'Msg': "Invalid auth" }
|
||||
return { 'AllOk': True, 'Msg': "Auth Ok" }
|
||||
|
||||
|
|
@ -93,17 +111,21 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler):
|
|||
"""
|
||||
print(f"\n\n\nDBUG:ProxyHandler:GET:{self.address_string()}:{self.path}")
|
||||
print(f"DBUG:PH:Get:Headers:{self.headers}")
|
||||
acGot = self.auth_check()
|
||||
if not acGot['AllOk']:
|
||||
self.send_error(400, f"WARN:{acGot['Msg']}")
|
||||
return
|
||||
pr = urllib.parse.urlparse(self.path)
|
||||
print(f"DBUG:ProxyHandler:GET:{pr}")
|
||||
match pr.path:
|
||||
case '/urlraw':
|
||||
handle_urlraw(self, pr)
|
||||
acGot = self.auth_check()
|
||||
if not acGot['AllOk']:
|
||||
self.send_error(400, f"WARN:{acGot['Msg']}")
|
||||
else:
|
||||
handle_urlraw(self, pr)
|
||||
case '/urltext':
|
||||
handle_urltext(self, pr)
|
||||
acGot = self.auth_check()
|
||||
if not acGot['AllOk']:
|
||||
self.send_error(400, f"WARN:{acGot['Msg']}")
|
||||
else:
|
||||
handle_urltext(self, pr)
|
||||
case '/aum':
|
||||
handle_aum(self, pr)
|
||||
case _:
|
||||
|
|
|
|||
|
|
@ -89,7 +89,12 @@ remember to
|
|||
content like head, scripts, styles, headers, footers, ... Be careful when accessing web through this and
|
||||
use it only with known safe sites.
|
||||
|
||||
* it allows one to specify a white list of allowed.domains, look into local.tools/simpleproxy.json
|
||||
* look into local.tools/simpleproxy.json for specifying
|
||||
|
||||
* the white list of allowed.domains
|
||||
* the shared bearer token between server and client ui
|
||||
|
||||
|
||||
|
||||
### using the front end
|
||||
|
||||
|
|
@ -228,6 +233,10 @@ It is attached to the document object. Some of these can also be updated using t
|
|||
|
||||
* proxyUrl - specify the address for the running instance of bundled local.tools/simpleproxy.py
|
||||
|
||||
* 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.
|
||||
|
||||
* 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.
|
||||
|
||||
* toolCallResponseTimeoutMS - specifies the time (in msecs) for which the logic should wait for a tool call to respond
|
||||
|
|
@ -419,7 +428,8 @@ The bundled simple proxy
|
|||
* tools/server/public_simplechat/local.tools/simpleproxy.py
|
||||
|
||||
* it provides for a basic white list of allowed domains to access, to be specified by the end user.
|
||||
This should help limit web access to a safe set of sites determined by the end user.
|
||||
This should help limit web access to a safe set of sites determined by the end user. There is also
|
||||
a provision for shared bearer token to be specified by the end user.
|
||||
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -27,6 +27,13 @@ function get_gme() {
|
|||
}
|
||||
|
||||
|
||||
function bearer_transform() {
|
||||
let data = `${new Date().getUTCFullYear()}${get_gme().tools.proxyAuthInsecure}`
|
||||
return crypto.subtle.digest('sha-256', new TextEncoder().encode(data)).then(ab=>{
|
||||
return Array.from(new Uint8Array(ab)).map(b=>b.toString(16).padStart(2,'0')).join('')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper http get logic wrt the bundled SimpleProxy server,
|
||||
* which helps execute a given proxy dependent tool call.
|
||||
|
|
@ -43,10 +50,11 @@ function get_gme() {
|
|||
* @param {string} qkey
|
||||
* @param {string} qvalue
|
||||
*/
|
||||
function proxyserver_get_1arg(toolcallid, toolname, obj, path, qkey, qvalue) {
|
||||
async function proxyserver_get_1arg(toolcallid, toolname, obj, path, qkey, qvalue) {
|
||||
if (gToolsWorker.onmessage != null) {
|
||||
let newUrl = `${get_gme().tools.proxyUrl}/${path}?${qkey}=${qvalue}`
|
||||
fetch(newUrl, { headers: { 'Authorization': `Bearer ${get_gme().tools.proxyAuthInsecure}` }}).then(resp => {
|
||||
let btoken = await bearer_transform()
|
||||
fetch(newUrl, { headers: { 'Authorization': `Bearer ${btoken}` }}).then(resp => {
|
||||
if (!resp.ok) {
|
||||
throw new Error(`${resp.status}:${resp.statusText}`);
|
||||
}
|
||||
|
|
@ -70,9 +78,7 @@ function proxyserver_get_1arg(toolcallid, toolname, obj, path, qkey, qvalue) {
|
|||
* @param {Object<string, Object<string, any>>} tcs
|
||||
*/
|
||||
async function proxyserver_tc_setup(tag, tcPath, tcName, tcsData, tcs) {
|
||||
await fetch(`${get_gme().tools.proxyUrl}/aum?url=${tcPath}.jambudweepe.akashaganga.multiverse.987654321123456789`, {
|
||||
headers: { 'Authorization': `Bearer ${get_gme().tools.proxyAuthInsecure}` }
|
||||
}).then(resp=>{
|
||||
await fetch(`${get_gme().tools.proxyUrl}/aum?url=${tcPath}.jambudweepe.akashaganga.multiverse.987654321123456789`).then(resp=>{
|
||||
if (resp.statusText != 'bharatavarshe') {
|
||||
console.log(`WARN:ToolWeb:${tag}:Dont forget to run the bundled local.tools/simpleproxy.py to enable me`)
|
||||
return
|
||||
|
|
|
|||
Loading…
Reference in New Issue