diff --git a/warden3/warden_server/warden3.0-alpha.sql b/warden3/warden_server/warden3.0-alpha.sql index ab668c7d0d836b39dadb310e59d28d07704b49ef..3afc10405707311dd74c5b6a6b901264701fb7d1 100644 --- a/warden3/warden_server/warden3.0-alpha.sql +++ b/warden3/warden_server/warden3.0-alpha.sql @@ -176,11 +176,11 @@ CREATE TABLE IF NOT EXISTS `event_tag_mapping` ( CREATE TABLE IF NOT EXISTS `last_events` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `service_id` int(11) NOT NULL, + `client_id` int(11) NOT NULL, `event_id` int(11) NOT NULL, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), - KEY `service_id` (`service_id`,`event_id`) + KEY `client_id` (`client_id`,`event_id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; -- -------------------------------------------------------- diff --git a/warden3/warden_server/warden_server.py b/warden3/warden_server/warden_server.py index 4be435506b28d84c2b892e38c0558afe8775125f..d1701e572779f9b2b77503f3758b375d37a3ac97 100755 --- a/warden3/warden_server/warden_server.py +++ b/warden3/warden_server/warden_server.py @@ -193,32 +193,42 @@ class X509Authenticator(NoAuthenticator): def authorize(self, env, client, method, event, args): - logging.debug("authorize: Client: " + str(client)) - # Authorize for debug if (method == 'getDebug'): - return client if client[0]['debug'] == 1 else None - - cl = None - identity = event['Node'][0]['Name'] - test = 'Test' in event['Category'] - - logging.debug("Event identity: " + identity) + if not client["debug"]: + logging.info("Auth failed: client does not have debug enabled") + return None + return client - for clx in client: - if clx['identity'] == identity: - cl = clx - break + try: + identity = event['Node'][0]['Name'].lower() + except KeyError: + # Event does not bear valid Node attribute + logging.info("Auth failed: event does not bear valid Node attribute") + return None - if cl is None: + try: + service = client["services"][identity] + except KeyError: + # We are unable to pair service in message to service in db + logging.info("Auth failed: '%s' from event not found in services for client %i" % (identity, client["id"])) return None + + client["service"] = service # Authorize for sending events - if ((method == 'sendEvents' and cl['write'] == 1) or - (method == 'sendEvents' and cl['test'] == 1 and test)): - return cl - - return None + if (method == "sendEvents"): + if not (service["write"] or service["test"]): + logging.info("Auth failed: service %i (%s) is not allowed to write or test" % (service["service_id"], identity)) + return None + + test = 'Test' in event.get('Category', []) + if not test: + logging.info("Auth failed: service %i (%s) does not send Test category in event" % (service["service_id"], identity)) + return None + + return client + class NoValidator(Object): @@ -280,10 +290,26 @@ class MySQL(Object): def get_client_by_name(self, name): format_strings = ','.join(['%s'] * len(name)) self.crs.execute("SELECT cl.`id`, cl.`hostname`, s.`service`, s.`service_id`, s.`identity`, cl.`read`, s.`write`, s.`test`, cl.`debug` FROM `clients` cl LEFT JOIN `services` s ON cl.`id` = s.`client_id` WHERE cl.`valid` = 1 AND s.`valid` = 1 AND `hostname` IN (%s)" % format_strings, tuple(name)) - row = self.crs.fetchall() - logging.debug("Client/service info: " + str(row)) - - return row if row else None + rows = self.crs.fetchall() + logging.debug("Client/service info: " + str(rows)) + if not rows: + return None + + client = {} + for n in ["id", "hostname", "read", "debug"]: + client[n] = rows[0][n] + + services = {} + for row in rows: + service = {} + for n in ["service", "service_id", "identity", "write", "test"]: + service[n] = row[n] + services[row["identity"]] = service + + client["services"] = services + + logging.debug("Client/service formatted info: " + str(client)) + return client def get_debug(self): @@ -331,12 +357,12 @@ class MySQL(Object): if cat is not None or nocat is not None: if cat is not None: parent_cats = [] - sqltemp['cat'] = generateDynamicQuery(self, "Category", "category_id IN (%s)", json.loads(cat), parent_cats) + sqltemp['cat'] = self.generateDynamicQuery("Category", "category_id IN (%s)", json.loads(cat), parent_cats) for pcats in parent_cats: sqltemp['cat'] += " %s category_id DIV %s = 1 " % (("OR" if sqltemp['cat'] else ""), pcats) if nocat is not None: parent_cats = [] - sqltemp['cat'] = generateDynamicQuery(self, "Category", "category_id NOT IN (%s)", json.loads(nocat), parent_cats) + sqltemp['cat'] = self.generateDynamicQuery("Category", "category_id NOT IN (%s)", json.loads(nocat), parent_cats) for pcats in parent_cats: sqltemp['cat'] += " %s category_id DIV %s = 1 " % (("OR" if sqltemp['cat'] else ""), pcats) @@ -348,9 +374,9 @@ class MySQL(Object): if tag is not None or notag is not None: if tag is not None: - sqltemp['tag'] = generateDynamicQuery(self, "Tag", "tag_id IN (%s)", json.loads(tag)) + sqltemp['tag'] = self.generateDynamicQuery("Tag", "tag_id IN (%s)", json.loads(tag)) if notag is not None: - sqltemp['tag'] = generateDynamicQuery(self, "Tag", "tag_id NOT IN (%s)", json.loads(notag)) + sqltemp['tag'] = self.generateDynamicQuery("Tag", "tag_id NOT IN (%s)", json.loads(notag)) sqlwhere.append("e.id IN (SELECT event_id FROM event_tag_mapping WHERE %s)" % sqltemp['tag']) @@ -402,8 +428,8 @@ class MySQL(Object): for event in events: try: - # logging.debug("INSERT INTO events (detected,received,service_id,data) VALUES ('%s', NOW(), '%s', '%s')" % (event['DetectTime'], client['id'], self.con.escape_string(str(event)))) - self.crs.execute("INSERT INTO events (detected,received,service_id,data) VALUES ('%s', NOW(), '%s', '%s')" % (event['DetectTime'], client['service_id'], self.con.escape_string(str(event)))) + # logging.debug("INSERT INTO events (detected,received,service_id,data) VALUES ('%s', NOW(), '%s', '%s')" % (event['DetectTime'], client["service"]["service_id"], self.con.escape_string(str(event)))) + self.crs.execute("INSERT INTO events (detected,received,service_id,data) VALUES ('%s', NOW(), '%s', '%s')" % (event['DetectTime'], client["service"]["service_id"], self.con.escape_string(str(event)))) lastid = self.crs.lastrowid # logging.debug(str(lastid)) for cat in event['Category']: @@ -427,8 +453,8 @@ class MySQL(Object): return errs def insertLastReceivedId(self, client, id): - logging.debug("INSERT INTO last_events(service_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client[0]['service_id']), id)) - self.crs.execute("INSERT INTO last_events(service_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client[0]['service_id']), id)) + logging.debug("INSERT INTO last_events(client_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client["id"]), id)) + self.crs.execute("INSERT INTO last_events(client_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client["id"]), id)) def getLastEventId(self): self.crs.execute("SELECT MAX(id) as id FROM events") @@ -437,12 +463,11 @@ class MySQL(Object): return row['id'] if row['id'] is not None else 0 def getLastReceivedId(self, client): - logging.debug("IN getLastReceivedId") - service_id = client[0]['service_id'] - logging.debug("getLastReceivedId (service_id) = %s", str(service_id)) + client_id = client["id"] + logging.debug("getLastReceivedId (client_id) = %s", str(client_id)) - logging.debug("SELECT MAX(event_id) as id FROM last_events WHERE service_id = %s" % (str(service_id))) - self.crs.execute("SELECT MAX(event_id) as id FROM last_events WHERE service_id = %s" % (str(service_id))) + logging.debug("SELECT MAX(event_id) as id FROM last_events WHERE client_id = %s" % (str(client_id))) + self.crs.execute("SELECT MAX(event_id) as id FROM last_events WHERE client_id = %s" % (str(client_id))) row = self.crs.fetchone() logging.debug("getLastReceivedId - %s" % str(row['id'])) @@ -532,22 +557,24 @@ class MySQL(Object): return 0 if strict else data[section]['Other'] -def generateDynamicQuery(self, section, query_string, variables, parent_cats = []): - variables_id = [] - # parent_cats = [] - - for v in variables: - mapped_id = self.map_id(section, v, True) - if mapped_id % 100 != 0: - variables_id.append(mapped_id) - else: - parent_cats.append(mapped_id) - - # variables_id = [self.map_id(section, v) for v in variables if self.map_id(section, v) % 100 != 0] - format_strings = ','.join(['\'%s\''] * len(variables_id)) - temp_string = query_string % format_strings + def generateDynamicQuery(self, section, query_string, variables, parent_cats = []): + variables_id = [] + # parent_cats = [] + + for v in variables: + mapped_id = self.map_id(section, v, True) + if mapped_id % 100 != 0: + variables_id.append(mapped_id) + else: + parent_cats.append(mapped_id) - return temp_string % tuple(variables_id) + # variables_id = [self.map_id(section, v) for v in variables if self.map_id(section, v) % 100 != 0] + format_strings = ','.join(['\'%s\''] * len(variables_id)) + temp_string = query_string % format_strings + + return temp_string % tuple(variables_id) + + def expose(meth): meth.exposed = True