rasolar/pyweb.py

167 lines
4.9 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
2019-07-31 05:48:24 -07:00
from bottle import get,post,request,Bottle,run,template
import threading,time,json,zlib,gnupg,socket,psutil,os,sys,requests
from queue import Queue
2019-07-30 22:19:30 -07:00
2019-07-31 21:21:11 -07:00
pathname = os.path.dirname(sys.argv[0])
abspath=os.path.abspath(pathname)
configfile=abspath+"/config.json"
try:
cf=open(configfile,"r")
except:
cf=open(configfile+".template","r")
2019-07-31 21:21:11 -07:00
log_conf=json.load(cf)
cf.close()
parameter={"device":socket.gethostname(),"allowed_ip":{"127.0.0.1":"25A4CF79414F10FD"},"gpg_keyid":"25A4CF79414F10FD","server_transfer_wait":2,"server_keyid":"25A4CF79414F10FD"}
2019-07-31 21:21:11 -07:00
for n in parameter:
if n in log_conf:
parameter[n]=log_conf[n]
if "sqlserver" in log_conf:
hostname="banana"
if "host" in log_conf['sqlserver']:
hostname=log_conf['sqlserver']['host']
port=8081
# if "port" in log_conf['sqlserver']:
# port=int(log_conf['sqlserver']['port'])
gpg=gnupg.GPG()
try:
gpgkey=gpg.list_keys(keys=parameter['gpg_keyid'])[0]
except:
gpgkey=[]
try:
servergpgkey=gpg.list_keys(keys=parameter['server_keyid'])[0]
except:
servergpgkey=[]
2019-07-31 21:21:11 -07:00
2019-07-30 22:19:30 -07:00
measdata={}
2019-07-31 03:30:42 -07:00
_HASH="hash"
_SIGNEDGPG="signed_gpg"
_PAYLOAD="payload"
_MEASURES="measures"
2019-07-31 03:30:42 -07:00
_BEGINSIGNATURE="-----BEGIN PGP SIGNATURE-----"
_BEGINMESSAGE="-----BEGIN PGP SIGNED MESSAGE-----"
_BEGINHASH="Hash:"
2019-07-30 22:19:30 -07:00
def sql_insert(q):
2019-07-31 21:21:11 -07:00
measdata={}
server_last_transmit=0
2019-07-30 22:19:30 -07:00
while True:
if q.empty():
time.sleep(0.1)
2019-07-31 21:21:11 -07:00
# print("ping"+str(time.time()))
if (time.time()-server_last_transmit)>parameter['server_transfer_wait']:
if len(measdata)==0:
server_last_transmit=time.time()-parameter['server_transfer_wait']/2
else:
json_out={"data":measdata}
if ('fingerprint' in servergpgkey) and ('fingerprint' in gpgkey):
json_out={"encrypted_data":gpg.encrypt(json.dumps(measdata),servergpgkey['fingerprint'],sign=gpgkey['fingerprint']).data.decode("utf-8")}
2019-07-31 21:21:11 -07:00
if ('fingerprint' not in servergpgkey) and ('fingerprint' in gpgkey):
json_out={"signed_data":gpg.sign(json.dumps(measdata),key=gpgkey['fingerprint']).data.decode("utf-8")}
print("http://"+hostname+":"+str(port)+"/data/"+gpgkey['keyid'])
2019-07-31 21:21:11 -07:00
try:
_r=requests.post("http://"+hostname+":"+str(port)+"/data/"+gpgkey['keyid'],json=json.dumps(json_out))
2019-07-31 21:21:11 -07:00
except:
_r={"status_code":404}
print("could not send to server")
# print(json.dumps(json_out))
server_last_transmit=time.time()-parameter['server_transfer_wait']/2
2019-07-31 21:21:11 -07:00
else:
if _r.status_code==200:
measdata={}
server_last_transmit=time.time()
else:
print("could not send to server")
print(_r.status_code)
server_last_transmit=time.time()-parameter['server_transfer_wait']/2
2019-07-30 22:19:30 -07:00
else:
try:
indata=q.get()
if indata is not None:
q.task_done()
except Exception as e:
print("Error during queuing")
print(e)
else:
if indata['hash'] in measdata:
for i in indata['payload']['measures']:
measdata[indata['hash']]['measures'][i]=indata['payload']['measures'][i]
else:
measdata[indata['hash']]=indata['payload']
app=Bottle()
@app.get('/')
def approot():
2019-07-31 21:21:11 -07:00
print(request.remote_addr in parameter['allowed_ip'])
2019-07-31 05:48:24 -07:00
return template('main.tpl',server=socket.gethostname(),cpupercent=psutil.cpu_percent(),measdata=measdata)
2019-07-30 22:19:30 -07:00
@app.post('/data/<hash_id:int>')
def dataimport(hash_id):
# print(hash_id)
2019-07-31 03:30:42 -07:00
timestart=time.time()
2019-07-31 21:21:11 -07:00
# check if request comes from allowed ip
if request.remote_addr in parameter['allowed_ip']:
# check, if json is transmitted
try:
json_in=json.loads(request.json)
# print(json_in)
2019-07-31 21:21:11 -07:00
except:
print("no json")
else:
if _HASH in json_in:
if int(json_in[_HASH]) == hash_id:
bcorrect=False
if _PAYLOAD in json_in:
if _MEASURES in json_in[_PAYLOAD]:
print("unsigned "+str(time.time()-timestart))
2019-07-31 21:21:11 -07:00
q.put(json_in,block=False)
bcorrect=True
if _SIGNEDGPG in json_in:
# check if signature of data is correct and key is allowed for ip
vgpg=gpg.verify(json_in[_SIGNEDGPG])
print(time.time()-timestart)
2019-07-31 21:21:11 -07:00
if vgpg.valid and vgpg.key_id in parameter['allowed_ip'][request.remote_addr]:
signed_in=json_in[_SIGNEDGPG].split("\n")
signed_in[signed_in.index(_BEGINSIGNATURE):]=""
del signed_in[signed_in.index(_BEGINMESSAGE)]
del signed_in[signed_in.index("")]
for h in signed_in:
if _BEGINHASH in h:
del signed_in[signed_in.index(h)]
if len(signed_in)>0:
print(time.time()-timestart)
q.put(json.loads(signed_in[0]),block=False)
else:
print("malformed signed packet")
print(json_in)
2019-07-31 03:30:42 -07:00
else:
2019-07-31 21:21:11 -07:00
print("could not verify gpg signature")
2019-07-31 03:30:42 -07:00
print(json_in)
2019-07-31 21:21:11 -07:00
else:
print("wrong id")
2019-07-30 22:19:30 -07:00
else:
2019-07-31 21:21:11 -07:00
print("json has no hash field")
print(json_in)
else:
print("not allowed client address")
2019-07-30 22:19:30 -07:00
2019-07-31 03:30:42 -07:00
2019-07-31 21:21:11 -07:00
2019-07-30 22:19:30 -07:00
q=Queue(maxsize=0)
sql_worker=threading.Thread(target=sql_insert,args=(q,))
sql_worker.setDaemon(True)
sql_worker.start()
run(app,host="localhost",port=8080)