Skip to content

Commit

Permalink
Disabled validation for now until there's more time to figure out ran…
Browse files Browse the repository at this point in the history
…dom variables for windows, it works on windows for now
  • Loading branch information
pstjuste committed Feb 1, 2012
1 parent 22b9652 commit eb1f493
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 88 deletions.
30 changes: 20 additions & 10 deletions src/jsoncert.py
Expand Up @@ -44,16 +44,6 @@ def __init__(self, content, pubkey=None, privkey=None):
self.as_dict['sig'] = base64.urlsafe_b64encode(sigdata)
self.keyid64 = base64.urlsafe_b64encode(self.keyid)

@staticmethod
def generate(bits, kvpairs):
if 'key' in kvpairs:
raise Exception('key already present in certificate attributes')
if 'sig' in kvpairs:
raise Exception('sig already present in certificate attributes')
rng = SecureRandom()
(pub, priv) = genkeypair(rng, bits)
return JsonCert(kvpairs, pub, priv)

def sign_object(self, obj):
if not self.privkey:
raise Exception("Certificate has no private key, cannot sign")
Expand All @@ -69,6 +59,16 @@ def unsign_object(self, obj):
unsigned = rsa_cbc_d(self.pubkey, signed)
return self.deserialize(unsigned)

@staticmethod
def generate(bits, kvpairs):
if 'key' in kvpairs:
raise Exception('key already present in certificate attributes')
if 'sig' in kvpairs:
raise Exception('sig already present in certificate attributes')
rng = SecureRandom()
(pub, priv) = genkeypair(rng, bits)
return JsonCert(kvpairs, pub, priv)

@staticmethod
def key_to_str(key):
return "rsa:%s,%s" % (int_to_b64(key[0]),int_to_b64(key[1]))
Expand Down Expand Up @@ -106,6 +106,16 @@ def getcert():

return cert

@staticmethod
def cal_hash(uid, msg, txtime, postid):
shash = hashlib.sha1()
tohash = str(uid) + msg + str(txtime) + str(postid)
#tohash is potentially unicode, if msg is, so we need to convert
#back to bytes, to do this, we use utf-8:
tohash = tohash.encode('utf-8')
shash.update(tohash)
return shash.hexdigest()


class JsonCertTest(unittest.TestCase):

Expand Down
10 changes: 4 additions & 6 deletions src/litter.py
Expand Up @@ -29,7 +29,7 @@ class MulticastServer(threading.Thread):
@staticmethod
def get_ip(ifname):
"""Retreives the ip address of an interface (Linux only)"""
ip = ""
ip = ifname
if os.name != "nt":
import fcntl
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
Expand All @@ -38,9 +38,7 @@ def get_ip(ifname):
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
else:
ip =([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2]
if not ip.startswith("127.")][0])

return ip

@staticmethod
Expand Down Expand Up @@ -126,7 +124,7 @@ def do_POST(self):
self.process_file(self.path)
except Exception as ex:
self.send_error(400, str(ex))
logging.exception(ex);
logging.exception(ex)

def process_request(self, request):
"""Extract json from request and queues it for processing"""
Expand Down Expand Up @@ -268,7 +266,7 @@ def main():
devs = []
name = socket.gethostname()
port = "8080"
debug_input = True
debug_input = False

try:
opts, args = getopt.getopt(sys.argv[1:], "i:n:p:")
Expand Down
69 changes: 14 additions & 55 deletions src/litterstore.py
Expand Up @@ -4,7 +4,6 @@
import time
import sys
import random
import hashlib
import socket
import unittest
import logging
Expand All @@ -25,30 +24,7 @@ def __str__(self):
class LitterStore:
"""Handles storage and processes requests"""

@staticmethod
def cal_hash(uid, msg, txtime, postid):
shash = hashlib.sha1()
tohash = str(uid) + msg + str(txtime) + str(postid)
#tohash is potentially unicode, if msg is, so we need to convert
#back to bytes, to do this, we use utf-8:
tohash = tohash.encode('utf-8')
shash.update(tohash)
return shash.hexdigest()

@staticmethod
def sign_hash(hash_msg, cert):
return cert.sign_object(hash_msg)['signed']

@staticmethod
def unsign_hash(sign_msg, cert, keyid):
#json creates unicode which has to be converted to reg strings
obj = {'keyid':str(keyid),'signed':str(sign_msg)}
return cert.unsign_object(obj)

def __init__(self, uid=None, test=False):
self.__cert = JsonCert.getcert()
self.__certs = {}
self.__certs[self.__cert.keyid64] = self.__cert
self.__uid = uid if uid != None else socket.gethostname()
self.__con = sqlite3.connect(":memory:" if test else self.__uid + ".db")
self.__nextid = 1
Expand Down Expand Up @@ -77,7 +53,7 @@ def __db_call(self, action, params=None):
def __init_db(self):
self.__db_call("CREATE TABLE IF NOT EXISTS posts "
"(uid TEXT, postid INTEGER, msg TEXT, txtime NUM, "
"rxtime NUM, hashid TEXT, keyid TEXT, PRIMARY KEY(hashid ASC))")
"rxtime NUM, sig TEXT, PRIMARY KEY(sig ASC))")

self.__db_call("CREATE TABLE IF NOT EXISTS friends "
"(uid TEXT, fid TEXT, txtime NUM, PRIMARY KEY(uid, fid))")
Expand All @@ -100,44 +76,38 @@ def __update_time(self, uid, fid, txtime=0):
msg = "UPDATE friends SET txtime = ? WHERE uid == ? and fid == ?"
self.__db_call(msg, (txtime, uid, fid))

def __post(self, msg, uid=None, txtime=None, postid=-1, hashid=None,
keyid=None):
def __post(self, msg, uid=None, txtime=None, rxtime=None, postid=-1,
sig=None):

logging.debug('POST : %s %s %s %s %s' %
(msg,uid,txtime,postid,hashid))
(msg,uid,txtime,postid,sig))

rxtime = 0
rxtime = time.time()

if uid == None:
uid = self.__uid
txtime = time.time()
txtime = rxtime
postid = self.__nextid
self.__nextid += 1
hashid = self.sign_hash(self.cal_hash(uid, msg, txtime, postid),
self.__cert)
keyid = self.__cert.keyid64
sig = str(random.random())

post = (uid, postid, txtime, rxtime, msg, hashid, keyid)
post = (uid, postid, txtime, rxtime, msg, sig)

if len(msg) > 140:
raise StoreError("message too long")

if postid == -1:
raise StoreError("Invalid postid: " + str(postid))

unsigned_hash = self.unsign_hash(hashid, self.__certs[keyid], keyid)
if unsigned_hash != self.cal_hash(uid, msg, txtime, postid):
raise StoreError("hashid mismatch: " + str(post))

self.__db_call("INSERT INTO posts (uid, postid, txtime, "
"rxtime, msg, hashid, keyid) VALUES (?, ?, ?, ?, ?, ?, ?)", post)
"rxtime, msg, sig) VALUES (?, ?, ?, ?, ?, ?)", post)

self.__update_time(self.__uid, uid, txtime)

return post

def __get(self, uid=None, begin=0, until=sys.maxint, limit=10):
pref = "SELECT msg, uid, txtime, postid, hashid, keyid FROM posts WHERE "
pref = "SELECT msg, uid, txtime, rxtime, postid, sig FROM posts WHERE "
msg = ()

if uid == None:
Expand Down Expand Up @@ -258,11 +228,6 @@ def __get_headers(self, request, meth=None):

return headers

def __add_cert(self, obj):
kvpairs = { 'key':str(obj['key']),'sig':str(obj['sig'])}
new_cert = JsonCert(kvpairs)
self.__certs[new_cert.keyid64] = new_cert

def process(self, request):

logging.debug('PROCESS : %s' % (request,))
Expand All @@ -271,34 +236,28 @@ def process(self, request):
meth = request.get('m', None)
headers = request.get('headers', {})

if 'cert' in request:
self.__add_cert(request['cert'])

if 'posts' in request:
for post in request['posts']:
try:
self.__post(*post)
except StoreError as err:
if str(err) != "column hashid is not unique":
if str(err) != "column sig is not unique":
logging.exception(err)

if 'query' in request:
meth = request['query']['m']

if meth == 'get':
begin = request['begin']
limit = request['limit']
result['posts'] = self.__get(begin=begin,limit=limit)
result['posts'] = self.__get(limit=limit)
elif meth == 'gen_push':
result['posts'] = self.__get(self.__uid, limit=1)
result['cert'] = self.__cert.as_dict
elif meth == 'gen_pull':
result['query'] = self.__gen_pull()
elif meth == 'pull':
uid = request['query']['uid']
friends = request['query']['friends']
result['posts'] = self.__pull(uid, friends)
result['cert'] = self.__cert.as_dict
elif meth == 'gen_gap':
result['query'] = self.__gen_pull()
elif meth == 'gap':
Expand Down Expand Up @@ -342,7 +301,7 @@ def test(self):

request = {'m':'gen_push'}
result = self.litter_a.process(request)
self.assertEqual(len(result['posts']),2)
self.assertEqual(len(result['posts']),1)

request = {'m':'gen_pull'}
result = self.litter_b.process(request)
Expand All @@ -363,7 +322,7 @@ def test(self):
request = {'m':'get','begin':0,'limit':10}
result = self.litter_b.process(request)
self.assertEqual(result['headers'], None)
self.assertEqual(len(result['posts']),2)
self.assertEqual(len(result['posts']),1)
self.assertEqual(result['posts'][0][1],'usera')


Expand Down
30 changes: 13 additions & 17 deletions src/web/litter.js
Expand Up @@ -20,8 +20,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

var txtime = 0;

$(document).ready(init);

function init() {
Expand Down Expand Up @@ -70,15 +68,15 @@ function loadPost() {
}

function messageCount() {
var msg = $(this).val();
var count = 140 - msg.length;
var elem = $("#countid").html(count + " characters left");
if (msg.length > 139) {
elem.css({"color" : "#FF0000"});
}
else {
elem.css({"color" : "black"});
}
var msg = $(this).val();
var count = 140 - msg.length;
var elem = $("#countid").html(count + " characters left");
if (msg.length > 139) {
elem.css({"color" : "#FF0000"});
}
else {
elem.css({"color" : "black"});
}
}

function loadResults(state) {
Expand All @@ -87,8 +85,9 @@ function loadResults(state) {
result['msg'] = state[i][0]
result['uid'] = state[i][1]
result['txtime'] = state[i][2]
result['postid'] = state[i][3]
result['hashid'] = state[i][4]
result['rxtime'] = state[i][3]
result['postid'] = state[i][4]
result['hashid'] = state[i][5]
addResult(result);
}
}
Expand All @@ -113,9 +112,6 @@ function addResult(result) {
return;
}

if (txtime < result.txtime) {
txtime = result.txtime;
}
// time is returned in seconds, needs to be in milliseconds
var date = new Date(result.txtime * 1000);

Expand Down Expand Up @@ -189,7 +185,7 @@ function updateUrl(msg) {
}

function getState() {
var ob = { "m" : "get", "begin" : txtime, "limit" : 10 }
var ob = { "m" : "get", "limit" : 10 }
$.ajax({type: "POST", url: "/api", dataType: 'json',
data : {'json' : JSON.stringify(ob)}, success: processState});
}
Expand Down

0 comments on commit eb1f493

Please sign in to comment.