Commit dcff0b99 by Luciano Barletta

simplified the system, better controls, tested

1 parent 203709fc
import sqlite3 import sqlite3
import ipdb
from enums import Table, States, Services, Datatypes from enums import Table, States, Services, Datatypes
class DBconnection: class DBconnection:
...@@ -8,21 +9,21 @@ class DBconnection: ...@@ -8,21 +9,21 @@ class DBconnection:
states = [States.queued,States.delivered] states = [States.queued,States.delivered]
structure = { structure = {
Table.id : "integer PRIMARY KEY" Table.id : "integer PRIMARY KEY",
Table.file : "text" Table.path : "text",
Table.serv : "text" Table.file : "text",
Table.dest : "text" Table.serv : "text",
Table.type : "text" Table.dest : "text",
Table.type : "text",
Table.state : "text" Table.state : "text"
} }
def __init__(self,db): def __init__(self,db):
ipdb.set_trace()
self.db = db self.db = db
query = "CREATE TABLE IF NOT EXISTS msg(" query = "CREATE TABLE IF NOT EXISTS msg("
for column in DBconnection.structure: for column in DBconnection.structure:
query += column + " " + DBconnection.structure[column] + "," query += column + " " + DBconnection.structure[column] + ","
query[-1] = ")" query = query.strip(",") + ")"
# main table # main table
self.query(query) self.query(query)
# delivered messages that were informed # delivered messages that were informed
...@@ -48,15 +49,15 @@ class DBconnection: ...@@ -48,15 +49,15 @@ class DBconnection:
def insert(self,table,insertions): def insert(self,table,insertions):
if not table in DBconnection.tables: if not table in DBconnection.tables:
return "La tabla " + table + " no existe o no está contemplada" return "La tabla " + table + " no existe o no está contemplada"
query = "INSERT INTO " table + "(" query = "INSERT INTO " + table + "("
values = " VALUES(" values = " VALUES("
for column in insertions: for column in insertions:
if not check(column,insertions[column]): if not self.check(column,insertions[column]):
return "El dato '" + insertions[column] + "' no es valido" return "El dato '" + insertions[column] + "' no es valido"
query += column + "," query += column + ","
values += insertions[column] + "," values += "'" + insertions[column] + "',"
query[-1] = ")" query = query.strip(",") + ")"
values[-1] = ")" values = values.strip(",") + ")"
con = sqlite3.connect(self.db) con = sqlite3.connect(self.db)
cursor = con.cursor() cursor = con.cursor()
cursor.execute(query + values) cursor.execute(query + values)
...@@ -67,6 +68,10 @@ class DBconnection: ...@@ -67,6 +68,10 @@ class DBconnection:
return id return id
def check(self,column,data): def check(self,column,data):
if column == Table.file:
return True
if column == Table.path:
return True
if column == Table.serv: if column == Table.serv:
return Services.validate(data) return Services.validate(data)
if column == Table.dest and len(data) <= 13: if column == Table.dest and len(data) <= 13:
...@@ -85,6 +90,6 @@ class DBconnection: ...@@ -85,6 +90,6 @@ class DBconnection:
i = 0 i = 0
for column in DBconnection.structure: for column in DBconnection.structure:
dictrow[column] = row[i] dictrow[column] = row[i]
i = i + 1 i += 1
dictarray.append(dictrow) dictarray.append(dictrow)
return dictarray return dictarray
...@@ -3,75 +3,72 @@ from flask import Flask, render_template, json, request, url_for ...@@ -3,75 +3,72 @@ from flask import Flask, render_template, json, request, url_for
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
import os import os
import ipdb import ipdb
from process_message import Process from process import Process
import time, threading import time, threading
from python_arptable import get_arp_table from python_arptable import get_arp_table
import random
from enums import States, Table
app = Flask(__name__) app = Flask(__name__)
retry_timer = 10 retry_timer = 10
last_file = {} prefix_lenght = 16
filename = {}
@app.route('/') @app.route('/')
def main(): def main():
return render_template('index.html') return render_template('index.html')
@app.route('/init', methods = ['GET', 'POST']) @app.route('/key', methods = ['GET', 'POST'])
def init(): def key():
mac = mac_from_ip(request.remote_addr) f = open("rsa_key.pub", "r")
if mac == None:
return "Error de inicializacion, no se pudo conseguir la MAC"
if not os.path.exists(mac):
os.mkdir(mac)
return key(mac)
def key(dir):
os.system("openssl genrsa -out " + dir + "/rsa_key.pri 2048") # private key
os.system("openssl rsa -in " + dir + "/rsa_key.pri -out " + dir + "/rsa_key.pub -outform PEM -pubout") # public key
f = open(dir + "/rsa_key.pub", "r")
key = f.read() key = f.read()
f.close() f.close()
return key return key
def mac_from_ip(ip):
os.system("ping " + ip + " -c1")
for i in get_arp_table():
if i['IP address'] == ip:
return i['HW address']
return None
@app.route('/data', methods = ['POST']) @app.route('/data', methods = ['POST'])
def data(): def data():
dir = mac_from_ip(request.remote_addr) prefix = newprefix()
if not os.path.exists(dir):
return "Debe llamar a /init primero"
key = request.files.get('key') key = request.files.get('key')
if key != None: if key != None:
key.save(dir + "/key") key.save(prefix + "_key")
request.files['data'].save(dir + "/" + request.files['data'].filename) request.files['data'].save(prefix)
last_file[dir] = request.files['data'].filename filename[prefix] = request.files['data'].filename
return "" return prefix
def newprefix():
prefix = ""
i = 0
while i < prefix_lenght:
range = random.randrange(3)
if range == 0:
prefix += chr(random.randrange(48,58))
if range == 1:
prefix += chr(random.randrange(65,91))
if range == 2:
prefix += chr(random.randrange(97,123))
i += 1
return prefix
@app.route('/msg', methods = ['POST']) @app.route('/msg', methods = ['POST'])
def msg(): def msg():
process = Process('messages.db') process = Process('messages.db')
dir = mac_from_ip(request.remote_addr) prefix = request.values['id']
if not os.path.exists(dir): if not os.path.exists(prefix):
return "Debe llamar a /init primero" return "El id de la data es invalido"
# symetric key was sent, decrypt data # symetric key was sent, decrypt data
if os.path.exists(dir + "/key"): if os.path.exists(prefix + "_key"):
# decrypt random key with stored private key and store in host folder # decrypt random key with stored private key and store in host folder
os.system("openssl rsautl -decrypt -inkey " + dir + "/rsa_key.pri -in " + dir + "/key -out " + dir + "/key") os.system("openssl rsautl -decrypt -inkey rsa_key.pri -in " + prefix + "_key -out " + prefix + "_key")
# decrypt JSON with decrypted random key and store in dir folder # decrypt JSON with decrypted random key and store in dir folder
os.system("openssl enc -d -aes-256-cbc -in " + dir + "/" + last_file[dir] + " -out " + dir + "/" + last_file[dir] + " -pass file:" + dir + "/key") os.system("openssl enc -d -aes-256-cbc -in " + prefix + " -out " + prefix + " -pass file:" + prefix + "_key")
# delete key # delete key
os.system("rm " + dir + "/key") os.system("rm " + prefix + "_key")
query = { query = {
'file' : dir + "/" + last_file[dir], 'path' : prefix,
'file' : filename.pop(prefix),
'serv' : request.values['serv'], 'serv' : request.values['serv'],
'dest' : request.values['dest'], 'dest' : request.values['dest'],
'type' : request.values['type'] 'type' : request.values['type']
...@@ -83,8 +80,12 @@ def msg(): ...@@ -83,8 +80,12 @@ def msg():
def cons(): def cons():
process = Process('messages.db') process = Process('messages.db')
id_query = request.form['id'] id_query = request.form['id']
query_state = process.lookup(id_query) row = process.lookup(id_query)
return query_state if type(row) == str: # error message
return row
if row[Table.state] == States.delivered:
os.system("rm " + row[Table.path])
return str(row[Table.state])
def attempt(): def attempt():
process = Process('messages.db') process = Process('messages.db')
...@@ -92,6 +93,9 @@ def attempt(): ...@@ -92,6 +93,9 @@ def attempt():
threading.Timer(retry_timer, attempt).start() threading.Timer(retry_timer, attempt).start()
if __name__ == "__main__": if __name__ == "__main__":
# generate keys
os.system("openssl genrsa -out rsa_key.pri 4096") # private key
os.system("openssl rsa -in rsa_key.pri -out rsa_key.pub -outform PEM -pubout") # public key
# starts attempt daemon # starts attempt daemon
attempt() attempt()
app.run("0.0.0.0") app.run("0.0.0.0")
\ No newline at end of file \ No newline at end of file
class Table: class Table:
id = "id" id = "id"
path = "path"
file = "file" file = "file"
serv = "serv" serv = "serv"
dest = "dest" dest = "dest"
......
...@@ -19,22 +19,24 @@ class Process: ...@@ -19,22 +19,24 @@ class Process:
if not serviceFactory(query[Table.serv]).validate(query[Table.type]): if not serviceFactory(query[Table.serv]).validate(query[Table.type]):
return "El servicio '" + query[Table.serv] + "' no puede enviar el tipo '" + query[Table.type] + "'" return "El servicio '" + query[Table.serv] + "' no puede enviar el tipo '" + query[Table.type] + "'"
entities = { entities = {
Table.path : query[Table.path],
Table.file : query[Table.file], Table.file : query[Table.file],
Table.dest : query[Table.dest], Table.dest : query[Table.dest],
Table.serv : query[Table.serv], Table.serv : query[Table.serv],
Table.type : query[Table.type], Table.type : query[Table.type],
Table.state : query[Table.state] Table.state : States.queued
} }
id = self.conn.insert("msg",entities) id = self.conn.insert("msg",entities)
return str(id) return id
# tries to send all messages available # tries to send all messages available
def send(self): def send(self):
rows = self.conn.query("SELECT * FROM msg WHERE state = ?",(States.queued,)) rows = self.conn.query("SELECT * FROM msg WHERE state = ?",(States.queued,))
for query in DBconnection.parseToTable(rows): for query in DBconnection.parseToTable(rows):
# if file doesn't exist, erase the message request, it can't be read anyway # if file doesn't exist, erase the message request, it can't be read anyway
if not os.path.exists(query[Table.file]): if not os.path.exists(query[Table.path]):
self.conn.query("DELETE FROM msg WHERE id = ?",(query[Table.id],)) self.conn.query("DELETE FROM msg WHERE id = ?",(query[Table.id],))
continue
serv = serviceFactory(query[Table.serv]) serv = serviceFactory(query[Table.serv])
success = serv.send(query) success = serv.send(query)
if success: if success:
...@@ -52,6 +54,7 @@ class Process: ...@@ -52,6 +54,7 @@ class Process:
if row[Table.state] == States.delivered: if row[Table.state] == States.delivered:
self.conn.query("DELETE FROM msg WHERE id = ?",(id,)) self.conn.query("DELETE FROM msg WHERE id = ?",(id,))
entities = { entities = {
Table.path : row[Table.path],
Table.file : row[Table.file], Table.file : row[Table.file],
Table.serv : row[Table.serv], Table.serv : row[Table.serv],
Table.dest : row[Table.dest], Table.dest : row[Table.dest],
...@@ -59,4 +62,4 @@ class Process: ...@@ -59,4 +62,4 @@ class Process:
Table.state : row[Table.state], Table.state : row[Table.state],
} }
self.conn.insert("history",entities) self.conn.insert("history",entities)
return row[Table.state]
\ No newline at end of file \ No newline at end of file
return row
\ No newline at end of file \ No newline at end of file
...@@ -28,15 +28,14 @@ class Wpp1(ServiceBase): ...@@ -28,15 +28,14 @@ class Wpp1(ServiceBase):
server = "https://archivos.hgtsa.com.ar/" server = "https://archivos.hgtsa.com.ar/"
def send(self,data): def send(self,data):
file_path = data[Table.file]
if data[Table.type] == Datatypes.text: if data[Table.type] == Datatypes.text:
f = open(file_path) f = open(data[Table.path])
text = f.read() text = f.read()
f.close() f.close()
result = requests.get(url = Wpp1.URL + Wpp1.URLmode[data[Table.type]],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data[Table.dest],'text':text}) result = requests.get(url = Wpp1.URL + Wpp1.URLmode[data[Table.type]],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data[Table.dest],'text':text})
return result.json()['success'] return result.json()['success']
else: else:
path = requests.post(url = Wpp1.server, files = { 'data' : (str(data[Table.id]),open(file_path,'rb')) }) path = requests.post(url = Wpp1.server, files = { 'data' : (str(data[Table.file]),open(data[Table.path],'rb')) })
result = requests.get(url = Wpp1.URL + Wpp1.URLmode[data[Table.type]],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data[Table.dest],'url':Wpp1.server + path.text}) result = requests.get(url = Wpp1.URL + Wpp1.URLmode[data[Table.type]],params = {'token':Wpp1.token,'uid':Wpp1.uid,'to':data[Table.dest],'url':Wpp1.server + path.text})
return result.json()['success'] return result.json()['success']
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!