Commit dcff0b99 by Luciano Barletta

simplified the system, better controls, tested

1 parent 203709fc
import sqlite3
import ipdb
from enums import Table, States, Services, Datatypes
class DBconnection:
......@@ -8,21 +9,21 @@ class DBconnection:
states = [States.queued,States.delivered]
structure = {
Table.id : "integer PRIMARY KEY"
Table.file : "text"
Table.serv : "text"
Table.dest : "text"
Table.type : "text"
Table.id : "integer PRIMARY KEY",
Table.path : "text",
Table.file : "text",
Table.serv : "text",
Table.dest : "text",
Table.type : "text",
Table.state : "text"
}
def __init__(self,db):
ipdb.set_trace()
self.db = db
query = "CREATE TABLE IF NOT EXISTS msg("
for column in DBconnection.structure:
query += column + " " + DBconnection.structure[column] + ","
query[-1] = ")"
query = query.strip(",") + ")"
# main table
self.query(query)
# delivered messages that were informed
......@@ -48,15 +49,15 @@ class DBconnection:
def insert(self,table,insertions):
if not table in DBconnection.tables:
return "La tabla " + table + " no existe o no está contemplada"
query = "INSERT INTO " table + "("
query = "INSERT INTO " + table + "("
values = " VALUES("
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"
query += column + ","
values += insertions[column] + ","
query[-1] = ")"
values[-1] = ")"
values += "'" + insertions[column] + "',"
query = query.strip(",") + ")"
values = values.strip(",") + ")"
con = sqlite3.connect(self.db)
cursor = con.cursor()
cursor.execute(query + values)
......@@ -67,6 +68,10 @@ class DBconnection:
return id
def check(self,column,data):
if column == Table.file:
return True
if column == Table.path:
return True
if column == Table.serv:
return Services.validate(data)
if column == Table.dest and len(data) <= 13:
......@@ -85,6 +90,6 @@ class DBconnection:
i = 0
for column in DBconnection.structure:
dictrow[column] = row[i]
i = i + 1
i += 1
dictarray.append(dictrow)
return dictarray
......@@ -3,75 +3,72 @@ from flask import Flask, render_template, json, request, url_for
from werkzeug.datastructures import FileStorage
import os
import ipdb
from process_message import Process
from process import Process
import time, threading
from python_arptable import get_arp_table
import random
from enums import States, Table
app = Flask(__name__)
retry_timer = 10
last_file = {}
prefix_lenght = 16
filename = {}
@app.route('/')
def main():
return render_template('index.html')
@app.route('/init', methods = ['GET', 'POST'])
def init():
mac = mac_from_ip(request.remote_addr)
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")
@app.route('/key', methods = ['GET', 'POST'])
def key():
f = open("rsa_key.pub", "r")
key = f.read()
f.close()
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'])
def data():
dir = mac_from_ip(request.remote_addr)
if not os.path.exists(dir):
return "Debe llamar a /init primero"
prefix = newprefix()
key = request.files.get('key')
if key != None:
key.save(dir + "/key")
request.files['data'].save(dir + "/" + request.files['data'].filename)
last_file[dir] = request.files['data'].filename
return ""
key.save(prefix + "_key")
request.files['data'].save(prefix)
filename[prefix] = request.files['data'].filename
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'])
def msg():
process = Process('messages.db')
dir = mac_from_ip(request.remote_addr)
if not os.path.exists(dir):
return "Debe llamar a /init primero"
prefix = request.values['id']
if not os.path.exists(prefix):
return "El id de la data es invalido"
# 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
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
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
os.system("rm " + dir + "/key")
os.system("rm " + prefix + "_key")
query = {
'file' : dir + "/" + last_file[dir],
'path' : prefix,
'file' : filename.pop(prefix),
'serv' : request.values['serv'],
'dest' : request.values['dest'],
'type' : request.values['type']
......@@ -83,8 +80,12 @@ def msg():
def cons():
process = Process('messages.db')
id_query = request.form['id']
query_state = process.lookup(id_query)
return query_state
row = process.lookup(id_query)
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():
process = Process('messages.db')
......@@ -92,6 +93,9 @@ def attempt():
threading.Timer(retry_timer, attempt).start()
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
attempt()
app.run("0.0.0.0")
\ No newline at end of file
class Table:
id = "id"
path = "path"
file = "file"
serv = "serv"
dest = "dest"
......
......@@ -19,22 +19,24 @@ class Process:
if not serviceFactory(query[Table.serv]).validate(query[Table.type]):
return "El servicio '" + query[Table.serv] + "' no puede enviar el tipo '" + query[Table.type] + "'"
entities = {
Table.path : query[Table.path],
Table.file : query[Table.file],
Table.dest : query[Table.dest],
Table.serv : query[Table.serv],
Table.type : query[Table.type],
Table.state : query[Table.state]
Table.state : States.queued
}
id = self.conn.insert("msg",entities)
return str(id)
return id
# tries to send all messages available
def send(self):
rows = self.conn.query("SELECT * FROM msg WHERE state = ?",(States.queued,))
for query in DBconnection.parseToTable(rows):
# 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],))
continue
serv = serviceFactory(query[Table.serv])
success = serv.send(query)
if success:
......@@ -52,6 +54,7 @@ class Process:
if row[Table.state] == States.delivered:
self.conn.query("DELETE FROM msg WHERE id = ?",(id,))
entities = {
Table.path : row[Table.path],
Table.file : row[Table.file],
Table.serv : row[Table.serv],
Table.dest : row[Table.dest],
......@@ -59,4 +62,4 @@ class Process:
Table.state : row[Table.state],
}
self.conn.insert("history",entities)
return row[Table.state]
\ No newline at end of file
return row
\ No newline at end of file
......@@ -28,15 +28,14 @@ class Wpp1(ServiceBase):
server = "https://archivos.hgtsa.com.ar/"
def send(self,data):
file_path = data[Table.file]
if data[Table.type] == Datatypes.text:
f = open(file_path)
f = open(data[Table.path])
text = f.read()
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})
return result.json()['success']
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})
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!