class Query(): def __init__(self, api=None): self.apiurl = api if not api: self.api = API() def _query(self, url): r = requests.get(urllib.parse.urljoin(self.apiurl, url), headers={ 'Version': '2.0', 'Accept': '*/json' }) data = json.loads(r.text) if r.status_code is 200 and data['status'] == 'success': return data['data'] elif (r.status_code is 404 and data['status'] == 'success' and data['reason'] == 'cve not found'): return None else: return False def cve(self, cveid): if self.apiurl: cve = self._query("api/cve/%s" % str(cveid)) return cve and CVE.fromDict(cve) or None try: return self.api.api_cve(cveid) except: return None def cveforcpe(self, cpe): if self.apiurl: cpes = self._query("api/cvefor/%s" % str(cpe)) return cpes and [CVE.fromDict(x) for x in cpes] or cpes return self.api.api_cvesFor(cpe) def last(self, entries=None): if self.apiurl: url = "api/last" if entries: url = "%s/%s" % (url, str(entries)) cves = self._query(url) return cves and [CVE.fromDict(x) for x in cves] or cves return self.api.api_last(entries)[0] def browse(self, vendor=None): if self.apiurl: url = "api/browse" if vendor: url = "%s/%s" % (url, vendor) return self._query(url) return self.api.api_browse(vendor) def search(self, query): if self.apiurl: cves = self._query("api/search/%s" % str(query)) return cves and [CVE.fromDict(x) for x in cves['data']] or [] return self.api.api_text_search(query) or []
class IRCBot(irc.bot.SingleServerIRCBot): def __init__(self, channel, nickname, server, port, password=None, username=None, **kwargs): if not username: username = nickname irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, username, **kwargs) self.channel = channel self.api = API() def on_nicknameinuse(self, c, e): c.nick(c.get_nickname() + "_") def on_welcome(self, c, e): if args.v: print("Server welcomed us") for chan in self.channel: if not chan.startswith('#'): chan = ("#%s" % chan) if args.v: print("joining %s" % chan) c.join(chan) def on_privmsg(self, c, e): self.do_command(e, e.arguments[0]) def on_pubmsg(self, c, e): line = e.arguments[0] if line.startswith(args.t): self.do_command(e, line[len(args.t):]) return def reply(self, e, reply): if type(reply) in [dict, list]: #reply = json.dumps(reply, sort_keys=True, indent=4, default=json_util.default, ensure_ascii=True) reply = json.dumps(reply, sort_keys=True, ensure_ascii=True, default=json_util.default) else: reply = str(reply) if e.target == self.connection.nickname: target = e.source.nick else: target = e.target _list = reply.split('\n') chunk_size = 512 - 12 - len( e.target) # 512 - len("PRIVMSG") - len(" :") - CR/LF - target _list = [[x[i:i + chunk_size] for i in range(0, len(x), chunk_size)] for x in _list] _list = [item for sublist in _list for item in sublist] # flatten list for r in _list[:4]: self.connection.privmsg(target, r) def do_command(self, e, cmd): def last(option): limit = int(option) if option else 10 if limit > args.m or limit < 1: self.reply(e, "Request not in range 0-%d" % args.m) self.reply(e, self.api.api_last(limit)) def cve(option): if option is None: return "A cve-id must be specified" return self.api.api_cve(option) if not cmd: pass parts = cmd.split(' ', 1) cmd = parts[0] option = parts[1] if len(parts) == 2 else None if cmd == "die": self.die() elif cmd in ["last", "recent"]: self.reply(e, last(option)) elif cmd in ["get", "cve"]: self.reply(e, cve(option)) elif cmd in ["browse", "vendor"]: self.reply(e, self.api.api_browse(option)) elif cmd in ["search", "product"]: parts = option.split() if len(parts) < 2: return self.reply(e, "Usage: search <vendor> <product>") return self.reply(e, self.api.api_search(parts[0], parts[1])) elif cmd in ["cvetweet", "tweet"]: text = "" cves = [] if option.lower().startswith("cve-"): cves.append(cve(option)) else: cves = last(option) for t in cves: text += str(t['id']) + " , " + str( t['summary']) + " " + " , ".join(t['references']) + "\n" return self.reply(e, text) else: self.reply(e, "Not understood: " + cmd)
class IRCBot(irc.bot.SingleServerIRCBot): def __init__(self, channel, nickname, server, port, password=None, username=None, **kwargs): if not username: username=nickname irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, username, **kwargs) self.channel = channel self.api = API() def on_nicknameinuse(self, c, e): c.nick(c.get_nickname() + "_") def on_welcome(self, c, e): if args.v: print("Server welcomed us") for chan in self.channel: if not chan.startswith('#'):chan=("#%s"%chan) if args.v: print("joining %s"%chan) c.join(chan) def on_privmsg(self, c, e): self.do_command(e, e.arguments[0]) def on_pubmsg(self, c, e): line = e.arguments[0] if line.startswith(args.t): self.do_command(e, line[len(args.t):]) return def reply(self, e, reply): if type(reply) in [dict, list]: #reply = json.dumps(reply, sort_keys=True, indent=4, default=json_util.default, ensure_ascii=True) reply = json.dumps(reply, sort_keys=True, ensure_ascii=True, default=json_util.default) else: reply = str(reply) if e.target == self.connection.nickname: target=e.source.nick else: target=e.target _list = reply.split('\n') chunk_size = 512 - 12 - len(e.target) # 512 - len("PRIVMSG") - len(" :") - CR/LF - target _list = [[x[i:i+chunk_size] for i in range(0, len(x), chunk_size)] for x in _list] _list = [item for sublist in _list for item in sublist] # flatten list for r in _list[:4]: self.connection.privmsg(target, r) def do_command(self, e, cmd): def last(option): limit = int(option) if option else 10 if limit > args.m or limit < 1: self.reply(e, "Request not in range 0-%d" % args.m) self.reply(e, self.api.api_last(limit)) def cve(option): if option is None: return "A cve-id must be specified" return self.api.api_cve(option) if not cmd: pass parts = cmd.split(' ', 1) cmd = parts[0] option = parts[1] if len(parts) == 2 else None if cmd == "die": self.die() elif cmd in ["last", "recent"]: self.reply(e, last(option)) elif cmd in ["get", "cve"]: self.reply(e, cve(option)) elif cmd in ["browse", "vendor"]: self.reply(e, self.api.api_browse(option)) elif cmd in ["search", "product"]: parts = option.split() if len(parts) < 2: return self.reply(e, "Usage: search <vendor> <product>") return self.reply(e, self.api.api_search(parts[0], parts[1])) elif cmd in ["cvetweet", "tweet"]: text = "" cves = [] if option.lower().startswith("cve-"): cves.append(cve(option)) else: cves = last(option) for t in cves: text += str(t['id']) + " , " + str(t['summary']) + " " + " , ".join(t['references']) + "\n" return self.reply(e, text) else: self.reply(e, "Not understood: " + cmd)