def logProtectedCall(result, path, args, user, allowed=True): """This should be called when a protected call was attempted, successful or not. It logs the attempt and its results in the audit_trail database. This audit trail can be used for several things- listing recently updated metadata (perhaps for a 'whats new?' page) or detecting and recovering from malicious use of keys. """ # Store the first argument separately so we can relatively efficiently search for it if args: main_param = str(args[0]) else: main_param = None # Get the user's UID. If it hasn't even been looked up successfully, # this is just a failed operation on a nonexistent user and it's not worth logging. uid = user.getCachedUid() if uid is None: return Database.pool.runOperation( "INSERT INTO audit_trail (timestamp, uid, action_domain, action_name," " main_param, params, allowed, results)" " VALUES(%d, %d, 'protected_call', %s, %s, '%s', %d, '%s')" % ( time.time(), uid, Database.quote(".".join(path), 'text'), Database.quote(main_param, 'text'), Database.quoteBlob(cPickle.dumps(args)), allowed, Database.quoteBlob(cPickle.dumps(result)))) return result
def _grant(self, cursor, *capabilities): uid = self._getUid(cursor) for capability in capabilities: rep = repr(capability) print rep cursor.execute("INSERT IGNORE INTO capabilities (uid, cap_md5, cap_repr)" " VALUES(%d, %s, %s)" % ( uid, Database.quote(hashlib.md5(rep).hexdigest(), 'char'), Database.quote(rep, 'text')))
def _createUser(self, cursor): """Create a new user, optionally setting the given parameters. Returns the new user ID. """ log.msg("Creating new user %r" % self._full_name) self.newUser = True cursor.execute("INSERT INTO users (secret_key, creation_time, full_name, email, login_name) " "VALUES (%s, %d, %s, %s, %s)" % ( Database.quote(createRandomKey(), 'varchar'), time.time(), Database.quote(self._full_name, 'text'), Database.quote(self._email, 'text'), Database.quote(self._login_name, 'varchar'))) cursor.execute("SELECT LAST_INSERT_ID()") return int(cursor.fetchone()[0])
def _getUidFromEmail(self, cursor, name): """Find a user by email address""" cursor.execute("SELECT uid FROM users WHERE email = %s" % Database.quote(name, 'text')) row = cursor.fetchone() if row: return int(row[0]) else: raise NoSuchUser("No such email address: %r" % name)
def _getUidFromLoginName(self, cursor, name): """Find a user by login name""" cursor.execute("SELECT uid FROM users WHERE login_name = %s" % Database.quote(name, 'text')) row = cursor.fetchone() if row: return int(row[0]) else: raise NoSuchUser("No such login name: %r" % name)
def _getUidFromKey(self, cursor, key): """Find a user by their key""" cursor.execute("SELECT uid FROM users WHERE secret_key = %s" % Database.quote(key.strip(), 'varchar')) row = cursor.fetchone() if row: return int(row[0]) else: raise NoSuchUser("No user found matching the given key")
def _getUidFromFullName(self, cursor, name): """Find a user by full name""" if name is None: cursor.execute("SELECT uid FROM users WHERE full_name is NULL") else: cursor.execute("SELECT uid FROM users WHERE full_name = %s" % Database.quote(name, 'text')) row = cursor.fetchone() if row: return int(row[0]) else: raise NoSuchUser("No such name: %r" % name)
def _createTestQuery(self, uid, capabilities): """Create an SQL query that returns something nonzero if a uid matches any of a list of capabilities. If the capabilities list is empty, this creates a query that always has a nonzero result. """ if capabilities: return "SELECT 1 FROM capabilities WHERE uid = %d AND (%s) LIMIT 1" % ( uid, " OR ".join(["cap_md5 = " + Database.quote(hashlib.md5(repr(c)).hexdigest(), 'char') for c in capabilities]), ) else: return "SELECT 1"
def dbStore(self, ruleset): """Store a ruleset persistently in our SQL database""" # Delete the old ruleset, if there was one result = defer.Deferred() d = Database.pool.runOperation("DELETE FROM rulesets WHERE uri = %s" % Database.quote(ruleset.uri, 'text')) # If we need to insert a new ruleset, do that after the delete finishes if ruleset.isEmpty(): d.addCallback(result.callback) else: d.addCallback(self._insertRuleset, result, ruleset) d.addErrback(result.errback) return result
# place, note the ID of the last converted message and add # a "WHERE id > foo" clause to the stats_messages query. # # -- Micah Dowty # import os import sys from cia.LibCIA import XML, Database sys.path[0] = os.path.join(sys.path[0], "..") from cia.LibCIA.Stats.Target import StatsTarget Database.init(serverCursor=True) cursor = Database.pool.connect().cursor() # Make sure we're starting with version 3 cursor.execute("SELECT value FROM meta WHERE name = 'version'") if cursor.fetchall()[0][0] != "6": raise Exception("This script must only be run on version 6 databases") # To avoid spending all our time reading buffer headers, cache frequently used targets targetCache = {} targetHits = {} targetCacheMax = 128 rowsProcessed = 0 prevId = 0
""" import os import re import xmlrpclib import shutil import sys import time from cia.tools import RandomMessage sys.path[0] = os.path.join(sys.path[0], "..") from cia.LibCIA import Database Database.init({"db": None}) dbcursor = Database.pool.connect().cursor() def readStatements(filename): """Return a sequence of SQL statements from the given file""" lines = [] for line in open(filename).xreadlines(): line = line.strip() if not line.startswith("--"): lines.append(line) fulltext = " ".join(lines) for statement in fulltext.split(";"): statement = statement.strip() if statement: yield statement
def _insertRuleset(self, none, result, ruleset): """Callback used by store() to insert a new or modified ruleset into the SQL database""" d = Database.pool.runOperation("INSERT INTO rulesets (uri, xml) values(%s, %s)" % ( Database.quote(ruleset.uri, 'text'), Database.quote(ruleset.get_source(), 'text'))) d.addCallback(result.callback) d.addErrback(result.errback)
# Back up your database before running this, as failure to # finish could cause all security data to be lost! # # -- Micah Dowty # import os import md5 import sys import time sys.path[0] = os.path.join(sys.path[0], "..") from cia.LibCIA import Database Database.init() cursor = Database.pool.connect().cursor() # Make sure we're starting with version 3 cursor.execute("SELECT value FROM meta WHERE name = 'version'") if cursor.fetchone()[0] != "3": raise Exception("This script must only be run on version 3 databases") # Read in all security data from the old capabilities table... # Each key gets a list of capabilities, but only one owner. cursor.execute("SELECT * FROM capabilities") key_owner = {} key_ownerMail = {} key_capabilities = {} while True: row = cursor.fetchone()