171 lines
5.1 KiB
Python
Executable File
171 lines
5.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
from bottle import get,post,request,Bottle,run,template
|
|
import threading,time,json,zlib,gnupg,socket,psutil,os,sys,requests
|
|
from queue import Queue
|
|
|
|
|
|
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")
|
|
|
|
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"}
|
|
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('/usr/bin/gpg',gnupghome='/home/pi/.gnupg')
|
|
try:
|
|
gpgkey=gpg.list_keys(keys=parameter['gpg_keyid'])[0]
|
|
except:
|
|
gpgkey=[]
|
|
|
|
try:
|
|
servergpgkey=gpg.list_keys(keys=parameter['server_keyid'])[0]
|
|
except:
|
|
servergpgkey=[]
|
|
|
|
measdata={}
|
|
count_tickets=0
|
|
last_ticket_time=0
|
|
|
|
_HASH="hash"
|
|
_SIGNEDGPG="signed_gpg"
|
|
_PAYLOAD="payload"
|
|
_MEASURES="measures"
|
|
_BEGINSIGNATURE="-----BEGIN PGP SIGNATURE-----"
|
|
_BEGINMESSAGE="-----BEGIN PGP SIGNED MESSAGE-----"
|
|
_BEGINHASH="Hash:"
|
|
|
|
def sql_insert(q):
|
|
measdata={}
|
|
server_last_transmit=0
|
|
while True:
|
|
if q.empty():
|
|
time.sleep(0.1)
|
|
# 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")}
|
|
if ('fingerprint' not in servergpgkey) and ('fingerprint' in gpgkey):
|
|
json_out={"signed_data":gpg.sign(json.dumps(measdata),keyid=gpgkey['keyid']).data.decode("utf-8")}
|
|
print("http://"+hostname+":"+str(port)+"/data/"+gpgkey['keyid'])
|
|
try:
|
|
_r=requests.post("http://"+hostname+":"+str(port)+"/data/"+gpgkey['keyid'],json=json.dumps(json_out))
|
|
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
|
|
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
|
|
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():
|
|
print(request.remote_addr in parameter['allowed_ip'])
|
|
return template('main.tpl',server=socket.gethostname(),cpupercent=psutil.cpu_percent(),countticket=count_tickets,tickettime=last_ticket_time,measdata=measdata)
|
|
|
|
@app.post('/data/<hash_id:int>')
|
|
def dataimport(hash_id):
|
|
# print(hash_id)
|
|
timestart=time.time()
|
|
# 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)
|
|
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))
|
|
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)
|
|
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:
|
|
last_ticket_time=time.time()-timestart
|
|
count_tickets=count_tickets+1
|
|
print(last_ticket_time)
|
|
q.put(json.loads(signed_in[0]),block=False)
|
|
else:
|
|
print("malformed signed packet")
|
|
print(json_in)
|
|
else:
|
|
print("could not verify gpg signature")
|
|
print(json_in)
|
|
else:
|
|
print("wrong id")
|
|
else:
|
|
print("json has no hash field")
|
|
print(json_in)
|
|
else:
|
|
print("not allowed client address")
|
|
|
|
|
|
|
|
q=Queue(maxsize=0)
|
|
|
|
sql_worker=threading.Thread(target=sql_insert,args=(q,))
|
|
sql_worker.setDaemon(True)
|
|
sql_worker.start()
|
|
|
|
|
|
run(app,host="",port=8080)
|