Skip to content
Snippets Groups Projects
Commit 84c23d84 authored by Michal Kostenec's avatar Michal Kostenec
Browse files

Authorization updated

Mapping id updated
Category 'test' supported
Filtering by parent category
parent dcedb1ad
No related branches found
No related tags found
No related merge requests found
......@@ -193,25 +193,25 @@ class X509Authenticator(NoAuthenticator):
def authorize(self, env, client, method, event, args):
# Authorize for debug
if (method == 'getDebug'):
return client if client[0]['debug'] == 1 else None
cl = None
service = event['Node'][0]['Name']
test = 'Test' in event['Category']
for i in range(len(client)):
if client[i]['service'] == service:
cl = client[i]
for clx in client:
if clx['service'] == service:
cl = clx
break
if cl is None:
return None
# logging.debug(cl)
# logging.debug(method)
# logging.debug(service)
# return True if (method == 'getEvents' and cl['read'])
# Authorize for sending events
if ((method == 'sendEvents' and cl['write'] == 1) or
(method == 'getDebug' and cl['debug'] == 1) or
(method == 'sendEvents' and cl['test'] == 1 and service == 'Test')):
(method == 'sendEvents' and cl['test'] == 1 and test)):
return cl
return None
......@@ -275,7 +275,7 @@ class MySQL(Object):
def get_client_by_name(self, name):
format_strings = ','.join(['%s'] * len(name))
self.crs.execute("SELECT `id`, `hostname`, `service`, `identity`, `read`, `write`, `debug`, `test` FROM `clients2` WHERE `valid` = 1 AND `hostname` IN (%s)" % format_strings, tuple(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 `clients3` 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()
return row if row else None
......@@ -319,17 +319,22 @@ class MySQL(Object):
sqlwhere = []
sqltemp = {}
if cat is not None and nocat is not None:
raise Error("Unrealizable conditions. Choose cat or nocat option.", 500, method='getEvents',
exc=sys.exc_info(), detail={'cat': cat, 'nocat' : nocat})
if cat is not None or nocat is not None:
if cat is not None:
sqltemp['cat'] = generateDynamicQuery(self, "Category", "category_id IN (%s)", json.loads(cat))
parent_cats = []
sqltemp['cat'] = generateDynamicQuery(self, "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:
sqltemp['cat'] = generateDynamicQuery(self, "Category", "category_id NOT IN (%s)", json.loads(nocat))
parent_cats = []
sqltemp['cat'] = generateDynamicQuery(self, "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)
sqlwhere.append("e.id IN (SELECT event_id FROM event_category_mapping4 WHERE %s)" % sqltemp['cat'])
if tag is not None and notag is not None:
......@@ -369,12 +374,20 @@ class MySQL(Object):
#sqlwhere = sqlwhere[:-4]
and_op = "" if not sqlwhere_string else "AND"
# logging.debug("SELECT e.id, e.data FROM clients2 cl RIGHT JOIN events4 e ON cl.id = e.client_id WHERE e.id > %s AND %s %s e.valid = 1 LIMIT %s" % (str(id), sqlwhere_string, and_op, str(count)))
logging.debug("SELECT e.id, e.data FROM clients2 cl RIGHT JOIN events4 e ON cl.id = e.client_id WHERE e.id > %s AND %s %s e.valid = 1 LIMIT %s" % (str(id), sqlwhere_string, and_op, str(count)))
self.crs.execute("SELECT e.id, e.data FROM clients2 cl RIGHT JOIN events4 e ON cl.id = e.client_id WHERE e.id > %s AND %s %s e.valid = 1 LIMIT %s" % (str(id), sqlwhere_string, and_op, str(count)))
row = self.crs.fetchall()
if row:
maxid = max(r['id'] for r in row)
else:
maxid = self.getLastEventId()
# logging.debug("MAX ID = %s", str(maxid))
return {
"lastid": row[-1]['id'] if row else str(id),
"lastid": maxid,
# "lastid": row[-1]['id'] if row else str(id),
"events": [row[i]['data'] for i in range(len(row))]
}
......@@ -409,7 +422,31 @@ class MySQL(Object):
return errs
def map_id (self, section, key):
def insertLastReceivedId(self, client, id):
logging.debug("INSERT INTO last_events(client_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client[0]['id']), id))
self.crs.execute("INSERT INTO last_events(client_id, event_id, timestamp) VALUES(%s, %s, NOW())" % (str(client[0]['id']), id))
def getLastEventId(self):
self.crs.execute("SELECT MAX(id) as id FROM events4")
row = self.crs.fetchone()
return row['id'] if row['id'] is not None else 0
def getLastReceivedId(self, client):
logging.debug("IN getLastReceivedId")
client_id = client[0]['id']
logging.debug("getLastReceivedId (client_id) = %s", str(client_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']))
return row['id'] if row is not None else 0
def map_id (self, section, key, strict = False):
# Should by placed in config file
data = {}
data['Tag'] = {
......@@ -429,41 +466,51 @@ class MySQL(Object):
"Other" : 99
}
data['Category'] = {
data['Category'] = {
"Abusive" : 100,
"Abusive.Spam" : 101,
"Abusive.Harassment" : 102,
"Abusive.Child" : 103,
"Abusive.Sexual" : 104,
"Abusive.Violence" : 105,
"Malware" : 200,
"Malware.Virus" : 201,
"Malware.Worm" : 202,
"Malware.Trojan" : 203,
"Malware.Spyware" : 204,
"Malware.Dialer" : 205,
"Malware.Rootkit" : 206,
"Recon.Scanning" : 3,
"Recon.Scanning" : 301,
"Recon.Sniffing" : 302,
"Recon.SocialEngineering" : 303,
"Recon.Searching" : 304,
"Attempt" : 400,
"Attempt.Exploit" : 401,
"Attempt.Login" : 402,
"Attempt.NewSignature" : 403,
"Intrusion" : 500,
"Intrusion.AdminCompromise" : 501,
"Intrusion.UserCompromise" : 502,
"Intrusion.AppCompromise" : 503,
"Intrusion.Botnet" : 504,
"Availability" : 600,
"Availability.DoS" : 601,
"Availability.DDoS" : 602,
"Availability.Sabotage" : 603,
"Availability.Outage" : 604,
"Information" : 700,
"Information.UnauthorizedAccess" : 701,
"Information.UnauthorizedModification" : 702,
"Fraud" : 800,
"Fraud.UnauthorizedUsage" : 801,
"Fraud.Copyright" : 802,
"Fraud.Masquerade" : 803,
"Fraud.Phishing" : 804,
"Fraud.Scam" : 805,
"Vulnerable" : 900,
"Vulnerable.Open" : 901,
"Anomaly" : 1000,
"Anomaly.Traffic" : 1001,
"Anomaly.Connection" : 1002,
"Anomaly.Protocol" : 1003,
......@@ -477,16 +524,27 @@ class MySQL(Object):
try:
return data[section][key]
except:
return data[section]['Other']
#Return 0 for strict mode (searching), otherwise map everything else to 'Other'
return 0 if strict else data[section]['Other']
def generateDynamicQuery(self, section, query_string, variables, parent_cats = []):
variables_id = []
# parent_cats = []
def generateDynamicQuery(self, section, query_string, variables):
variables_id = [self.map_id(section, v) for v in variables]
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
return temp_string % tuple(variables_id)
def expose(meth):
meth.exposed = True
return meth
......@@ -627,6 +685,10 @@ class WardenHandler(Object):
@expose
def getDebug(self, _env, _client):
auth = self.auth.authorize(_env, _client, 'getDebug', None, None)
if not auth:
raise Error("I'm watching YOU. (Authorization)", 403, method='getDebug', detail={"client": _client})
return {
"environment": _env,
"database": self.db.get_debug()
......@@ -656,6 +718,27 @@ class WardenHandler(Object):
except (ValueError, TypeError):
id=0
if id == 0:
try:
id = self.db.getLastReceivedId(_client)
# logging.debug("Last received ID for %s is %s" % (_client['hostname'], str(id)))
except Exception, e:
logging.error(e)
id = 0
if id == 0:
try:
id = self.db.getLastEventId()
except Exception as e:
raise Error("Last event id receiving error", 500, detail={"client": _client})
self.db.insertLastReceivedId(_client, id)
return {
"lastid": id,
"events": []
}
try:
count = int(count)
except (ValueError, TypeError):
......@@ -669,6 +752,9 @@ class WardenHandler(Object):
logging.info("getEvents(%d, %d, %s, %s, %s, %s, %s, %s): sending %d events" % (
id, count, cat, nocat, tag, notag, group, nogroup, len(res["events"])))
self.db.insertLastReceivedId(_client, res['lastid'])
logging.debug("lastid inserting: %s" % {'lastid': res['lastid'], 'client' : _client})
return res
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment