def update_local_acoin_interval(onAcoinInterval=None, onNewIntervalCallback=None): """updates the local cache of the acoin interval and schedules the next update""" #get current and next interval info... sql, inj = get_current_acoin_interval_sql() d = db.read(sql, inj) d.addCallback(check_acoin_interval, onAcoinInterval, onNewIntervalCallback) d.addErrback(err)
def unpack_and_mint(self, msg): """unpacks the request retreiving the number of coins packed and the total value desired. Verification: values must be positive! """ self.number, msg = Basic.read_short(msg) value, msg = Basic.read_int(msg) log_msg('REQUEST:: %s %s' % (self.number, self.hexId), 0) if not BankUtil.is_positive_integer(self.number): raise ValueError('number of coins must be greater than 0!') if value != ACOIN_VALUE or not BankUtil.is_positive_integer(value): raise ValueError('coins must have a positive, integer value') self.bill = 0 self.signatures = "" for i in range(0, self.number): #TODO: move to a worker pool or something sig = Globals.ACOIN_KEY.decrypt(msg[:Globals.ACOIN_KEY_BYTES], False) self.signatures += struct.pack('!%ss' % (Globals.ACOIN_KEY_BYTES), sig) msg = msg[Globals.ACOIN_KEY_BYTES:] self.bill += value #TODO: move this constraint to postgres to get rid of any potential race conditions sql = "SELECT balance FROM Accounts WHERE Username = %s" inj = (self.user, ) d = db.read(sql, inj) return d
def unpack_and_mint(self, msg): """unpacks the request retreiving the number of coins packed and the total value desired. Verification: values must be positive! """ self.number, msg = Basic.read_short(msg) value, msg = Basic.read_int(msg) log_msg('REQUEST:: %s %s'%(self.number, self.hexId), 0) if not BankUtil.is_positive_integer(self.number): raise ValueError('number of coins must be greater than 0!') if value != ACOIN_VALUE or not BankUtil.is_positive_integer(value): raise ValueError('coins must have a positive, integer value') self.bill = 0 self.signatures = "" for i in range(0, self.number): #TODO: move to a worker pool or something sig = Globals.ACOIN_KEY.decrypt(msg[:Globals.ACOIN_KEY_BYTES], False) self.signatures += struct.pack('!%ss'%(Globals.ACOIN_KEY_BYTES), sig) msg = msg[Globals.ACOIN_KEY_BYTES:] self.bill += value #TODO: move this constraint to postgres to get rid of any potential race conditions sql = "SELECT balance FROM Accounts WHERE Username = %s" inj = (self.user,) d = db.read(sql, inj) return d
def sym_decrypt(self, msg): """this is disgusting because we use two different systems for symmetric encryption type 0 uses SmmetricKey while type 1 uses EncryptedDatagram quirks: 0 must also update the nonce stored in the db 1 performs heavy crypto and has non symmetric client/server side encryption/decryption""" if not self.symKey: msgType, msg = Basic.read_byte(msg) if msgType is 0: #get the tor fingerprint so we know how to decrypt the message (binId,), msg = Basic.read_message('!20s', msg) #convert the tor fingerprint back into hex self.hexId = binascii.hexlify(binId).upper() #get the symmetric key out of the database: sql = "SELECT Owner, Public_Key, Msgnum, auth_blob FROM Relays WHERE Tor_Id = %s" inj = (self.hexId,) d = db.read(sql, inj) #get the sym key from the db and decrypt the msg d.addCallback(self.fetch_sym_key, msg) #update the message number in the database d.addCallback(self.update_db) elif msgType is 1: self.symKey = EncryptedDatagram.ServerSymKey(Globals.GENERIC_KEY) d = threads.deferToThread(self.get_sym_key_value, msg) else: raise Exception("Unknown msgType: %s" % (msgType)) else: raise Exception('Passing more than one message per tcp connection is currently not supported') return d
def sym_decrypt(self, msg): """this is disgusting because we use two different systems for symmetric encryption type 0 uses SmmetricKey while type 1 uses EncryptedDatagram quirks: 0 must also update the nonce stored in the db 1 performs heavy crypto and has non symmetric client/server side encryption/decryption""" if not self.symKey: msgType, msg = Basic.read_byte(msg) if msgType is 0: #get the tor fingerprint so we know how to decrypt the message (binId, ), msg = Basic.read_message('!20s', msg) #convert the tor fingerprint back into hex self.hexId = binascii.hexlify(binId).upper() #get the symmetric key out of the database: sql = "SELECT Owner, Public_Key, Msgnum, auth_blob FROM Relays WHERE Tor_Id = %s" inj = (self.hexId, ) d = db.read(sql, inj) #get the sym key from the db and decrypt the msg d.addCallback(self.fetch_sym_key, msg) #update the message number in the database d.addCallback(self.update_db) elif msgType is 1: self.symKey = EncryptedDatagram.ServerSymKey( Globals.GENERIC_KEY) d = threads.deferToThread(self.get_sym_key_value, msg) else: raise Exception("Unknown msgType: %s" % (msgType)) else: raise Exception( 'Passing more than one message per tcp connection is currently not supported' ) return d
def check_for_timeout(self): """if there is a timeout, raises an exception to trigger the bad_info errback sets: self.timeout """ #check to see if the account has a login timeout on it sql = "SELECT timeout, escalation FROM badlogin WHERE username = %s AND active = true" inj = (self.username,) return db.read(sql, inj)
def generate_timeout(self, reason=None): """ Called by an unsuccessful login attempt- either by an incorrect username/pw or if the user is locked out because of a previous attempt. In the case of the former- log the attempt into the db. sets: self.timeout @return: deferred """ self.successful = False #will trap either err or reraise anything else preserving the traceback if self.timeout: log_msg('User login disallowed: currently locked out!', 1) self.generate_reply() return log_msg('User login failed- %s!'%(reason), 1) #see if this is the first successive active error sql = "SELECT escalation, timeout FROM badlogin WHERE username = %s AND active = true" inj = (self.username,) d = db.read(sql, inj) d.addCallback(self.flush_timeout_to_db) d.addCallback(self.generate_reply) d.addErrback(self.err)
def get_balance(self, result): sql = "SELECT Balance FROM Accounts WHERE Username = %s" inj = (self.user,) d = db.read(sql, inj) return d
import psycopg2 as cyborg def hashify(username, pw): """hashes the pw with a salt of the username""" print username, pw h = Crypto.Hash.SHA256.new(username) h.update(pw) #take salted hash return(h.digest()) print "you will need to close anything with an open connection (ie apache) to the database to change table structures!" sql = 'alter table accounts add column hash bytea' db.write(sql) sql = "Select username, password from accounts" a = db.read(sql, tup = None, fetch='fetchall') tup=[] sql = [] for item in a: username = item[0] pw = item[1] pw = hashify(username, pw) sql.append("update accounts set hash = %s where username = %s") tup.append((cyborg.Binary(pw), username)) print "writing" db.write(sql, tup) sql = ['alter table accounts drop column password','alter table rename column hash to password'] db.write(sql)
def get_balance(self, result): sql = "SELECT Balance FROM Accounts WHERE Username = %s" inj = (self.user, ) d = db.read(sql, inj) return d
def update_db2(self, returned=None): """generate session auth stuff and also see if the relay is known to exist""" symKey = SymmetricKey.SymmetricKey() self.authBlob = symKey.pack() d = db.read("SELECT Owner, Public_Key FROM Relays WHERE Tor_Id = %s",(self.hexId,)) return d
def get_password_from_db(self): """gets the password form the db which is also an implicit check to see if the account exists""" #check to see if the account exists d = db.read("SELECT password, balance FROM Accounts WHERE Username = %s",(self.username,)) d.addCallback(self.does_account_exist_and_do_passwords_match) d.addErrback(self.err)