summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean B. Palmer <sbp@aldebaran.local>2011-09-05 17:46:17 +0100
committerSean B. Palmer <sbp@aldebaran.local>2011-09-05 17:46:17 +0100
commit2d3009ccb123bb34bf0d8b8b516a15c05240bf03 (patch)
tree28029457224da9cd91187e17f8b90cff5cb2de57
parent66edd833726d0a14400df65311999b1496b9f8cb (diff)
downloadbot-2d3009ccb123bb34bf0d8b8b516a15c05240bf03.tar.gz
bot-2d3009ccb123bb34bf0d8b8b516a15c05240bf03.tar.bz2
bot-2d3009ccb123bb34bf0d8b8b516a15c05240bf03.zip
Attempt to patch a possible message injection hole.
-rwxr-xr-xbot.py2
-rwxr-xr-xirc.py8
-rwxr-xr-xmodules/head.py12
-rwxr-xr-xmodules/oblique.py2
-rwxr-xr-xmodules/reload.py2
-rwxr-xr-xmodules/search.py96
-rwxr-xr-xmodules/tell.py1
-rwxr-xr-xmodules/wikipedia.py2
-rwxr-xr-xphenny4
9 files changed, 101 insertions, 28 deletions
diff --git a/bot.py b/bot.py
index 3886a87..453dbc4 100755
--- a/bot.py
+++ b/bot.py
@@ -55,6 +55,8 @@ class Phenny(irc.Bot):
for filename in filenames:
name = os.path.basename(filename)[:-3]
if name in excluded_modules: continue
+ # if name in sys.modules:
+ # del sys.modules[name]
try: module = imp.load_source(name, filename)
except Exception, e:
print >> sys.stderr, "Error loading %s: %s (in bot.py)" % (name, e)
diff --git a/irc.py b/irc.py
index a16c61b..7a4bed4 100755
--- a/irc.py
+++ b/irc.py
@@ -42,6 +42,9 @@ class Bot(asynchat.async_chat):
import threading
self.sending = threading.RLock()
+ # def push(self, *args, **kargs):
+ # asynchat.async_chat.push(self, *args, **kargs)
+
def __write(self, args, text=None):
# print '%r %r %r' % (self, args, text)
try:
@@ -148,7 +151,10 @@ class Bot(asynchat.async_chat):
self.sending.release()
return
- self.__write(('PRIVMSG', recipient), text)
+ def safe(input):
+ input = input.replace('\n', '')
+ return input.replace('\r', '')
+ self.__write(('PRIVMSG', safe(recipient)), safe(text))
self.stack.append((time.time(), text))
self.stack = self.stack[-10:]
diff --git a/modules/head.py b/modules/head.py
index 1008628..66e9eef 100755
--- a/modules/head.py
+++ b/modules/head.py
@@ -83,6 +83,18 @@ def f_title(self, origin, match, args):
uri = 'http://' + uri
uri = uri.replace('#!', '?_escaped_fragment_=')
+ localhost = [
+ 'http://localhost/', 'http://localhost:80/',
+ 'http://localhost:8080/', 'http://127.0.0.1/',
+ 'http://127.0.0.1:80/', 'http://127.0.0.1:8080/',
+ 'https://localhost/', 'https://localhost:80/',
+ 'https://localhost:8080/', 'https://127.0.0.1/',
+ 'https://127.0.0.1:80/', 'https://127.0.0.1:8080/',
+ ]
+ for s in localhost:
+ if uri.startswith(s):
+ return phenny.reply('Sorry, access forbidden.')
+
try:
redirects = 0
while True:
diff --git a/modules/oblique.py b/modules/oblique.py
index 6d6156c..7bd6718 100755
--- a/modules/oblique.py
+++ b/modules/oblique.py
@@ -81,7 +81,7 @@ def o(phenny, input):
return phenny.reply(msg)
if not o.services.has_key(command):
- return phenny.reply('Sorry, no such service. See %s' % o.serviceURI)
+ return phenny.reply('Service not found in %s' % o.serviceURI)
if hasattr(phenny.config, 'external'):
default = phenny.config.external.get('*')
diff --git a/modules/reload.py b/modules/reload.py
index 32e6796..dfd0e8e 100755
--- a/modules/reload.py
+++ b/modules/reload.py
@@ -19,6 +19,8 @@ def f_reload(phenny, input):
return phenny.reply('What?')
if (not name) or (name == '*'):
+ phenny.variables = None
+ phenny.commands = None
phenny.setup()
return phenny.reply('done')
diff --git a/modules/search.py b/modules/search.py
index c8f9a6a..bfc50bd 100755
--- a/modules/search.py
+++ b/modules/search.py
@@ -18,26 +18,26 @@ class Grab(web.urllib.URLopener):
def http_error_default(self, url, fp, errcode, errmsg, headers):
return web.urllib.addinfourl(fp, [headers, errcode], "http:" + url)
-def search(query):
+def google_ajax(query):
"""Search using AjaxSearch, and return its JSON."""
uri = 'http://ajax.googleapis.com/ajax/services/search/web'
- args = '?v=1.0&safe=off&q=' + web.urllib.quote(query.encode('utf-8'))
+ args = '?v=1.0&safe=off&q=' + web.urllib.quote(query)
handler = web.urllib._urlopener
web.urllib._urlopener = Grab()
bytes = web.get(uri + args)
web.urllib._urlopener = handler
return web.json(bytes)
-def result(query):
- results = search(query)
+def google_search(query):
+ results = google_ajax(query)
try: return results['responseData']['results'][0]['unescapedUrl']
except IndexError: return None
except TypeError:
print results
return False
-def count(query):
- results = search(query)
+def google_count(query):
+ results = google_ajax(query)
if not results.has_key('responseData'): return '0'
if not results['responseData'].has_key('cursor'): return '0'
if not results['responseData']['cursor'].has_key('estimatedResultCount'):
@@ -56,7 +56,8 @@ def g(phenny, input):
query = input.group(2)
if not query:
return phenny.reply('.g what?')
- uri = result(query)
+ query = query.encode('utf-8')
+ uri = google_search(query)
if uri:
phenny.reply(uri)
if not hasattr(phenny.bot, 'last_seen_uri'):
@@ -73,7 +74,8 @@ def gc(phenny, input):
query = input.group(2)
if not query:
return phenny.reply('.gc what?')
- num = formatnumber(count(query))
+ query = query.encode('utf-8')
+ num = formatnumber(google_count(query))
phenny.say(query + ': ' + num)
gc.commands = ['gc']
gc.priority = 'high'
@@ -93,7 +95,8 @@ def gcs(phenny, input):
results = []
for i, query in enumerate(queries):
query = query.strip('[]')
- n = int((formatnumber(count(query)) or '0').replace(',', ''))
+ query = query.encode('utf-8')
+ n = int((formatnumber(google_count(query)) or '0').replace(',', ''))
results.append((n, query))
if i >= 2: __import__('time').sleep(0.25)
if i >= 4: __import__('time').sleep(0.25)
@@ -105,6 +108,13 @@ gcs.commands = ['gcs', 'comp']
r_bing = re.compile(r'<h3><a href="([^"]+)"')
+def bing_search(query, lang='en-GB'):
+ query = web.urllib.quote(query)
+ base = 'http://www.bing.com/search?mkt=%s&q=' % lang
+ bytes = web.get(base + query)
+ m = r_bing.search(bytes)
+ if m: return m.group(1)
+
def bing(phenny, input):
"""Queries Bing for the specified input."""
query = input.group(2)
@@ -115,12 +125,9 @@ def bing(phenny, input):
if not query:
return phenny.reply('.bing what?')
- query = web.urllib.quote(query.encode('utf-8'))
- base = 'http://www.bing.com/search?mkt=%s&q=' % lang
- bytes = web.get(base + query)
- m = r_bing.search(bytes)
- if m:
- uri = m.group(1)
+ query = query.encode('utf-8')
+ uri = bing_search(query, lang)
+ if uri:
phenny.reply(uri)
if not hasattr(phenny.bot, 'last_seen_uri'):
phenny.bot.last_seen_uri = {}
@@ -129,24 +136,65 @@ def bing(phenny, input):
bing.commands = ['bing']
bing.example = '.bing swhack'
-r_ddg = re.compile(r'nofollow" class="[^"]+" href="(.*?)">')
+r_duck = re.compile(r'nofollow" class="[^"]+" href="(.*?)">')
-def ddg(phenny, input):
+def duck_search(query):
+ query = query.replace('!', '')
+ query = web.urllib.quote(query)
+ uri = 'http://duckduckgo.com/html/?q=%s&kl=uk-en' % query
+ bytes = web.get(uri)
+ m = r_duck.search(bytes)
+ if m: return web.decode(m.group(1))
+
+def duck(phenny, input):
query = input.group(2)
if not query: return phenny.reply('.ddg what?')
- query = web.urllib.quote(query.encode('utf-8'))
- uri = 'http://duckduckgo.com/html/?q=%s&kl=uk-en' % query
- bytes = web.get(uri)
- m = r_ddg.search(bytes)
- if m:
- uri = m.group(1)
+ query = query.encode('utf-8')
+ uri = duck_search(query)
+ if uri:
phenny.reply(uri)
if not hasattr(phenny.bot, 'last_seen_uri'):
phenny.bot.last_seen_uri = {}
phenny.bot.last_seen_uri[input.sender] = uri
else: phenny.reply("No results found for '%s'." % query)
-ddg.commands = ['ddg']
+duck.commands = ['duck', 'ddg']
+
+def search(phenny, input):
+ if not input.group(2):
+ return phenny.reply('.search for what?')
+ query = input.group(2).encode('utf-8')
+ gu = google_search(query) or '-'
+ bu = bing_search(query) or '-'
+ du = duck_search(query) or '-'
+
+ if (gu == bu) and (bu == du):
+ result = '%s (g, b, d)' % gu
+ elif (gu == bu):
+ result = '%s (g, b), %s (d)' % (gu, du)
+ elif (bu == du):
+ result = '%s (b, d), %s (g)' % (bu, gu)
+ elif (gu == du):
+ result = '%s (g, d), %s (b)' % (gu, bu)
+ else:
+ if len(gu) > 250: gu = '(extremely long link)'
+ if len(bu) > 150: bu = '(extremely long link)'
+ if len(du) > 150: du = '(extremely long link)'
+ result = '%s (g), %s (b), %s (d)' % (gu, bu, du)
+
+ phenny.reply(result)
+search.commands = ['search']
+
+def suggest(phenny, input):
+ if not input.group(2):
+ return phenny.reply("No query term.")
+ query = input.group(2).encode('utf-8')
+ uri = 'http://websitedev.de/temp-bin/suggest.pl?q='
+ answer = web.get(uri + web.urllib.quote(query).replace('+', '%2B'))
+ if answer:
+ phenny.say(answer)
+ else: phenny.reply('Sorry, no result.')
+suggest.commands = ['suggest']
if __name__ == '__main__':
print __doc__.strip()
diff --git a/modules/tell.py b/modules/tell.py
index 5e61007..d3ee609 100755
--- a/modules/tell.py
+++ b/modules/tell.py
@@ -122,6 +122,7 @@ def message(phenny, input):
tellee = input.nick
channel = input.sender
+ if not os: return
if not os.path.exists(phenny.tell_filename):
return
diff --git a/modules/wikipedia.py b/modules/wikipedia.py
index ba9ce0b..1a406b3 100755
--- a/modules/wikipedia.py
+++ b/modules/wikipedia.py
@@ -53,7 +53,7 @@ def search(term):
else: term = term.decode('utf-8')
term = term.replace('_', ' ')
- try: uri = search.result('site:en.wikipedia.org %s' % term)
+ try: uri = search.google_search('site:en.wikipedia.org %s' % term)
except IndexError: return term
if uri:
return uri[len('http://en.wikipedia.org/wiki/'):]
diff --git a/phenny b/phenny
index 3153f33..6cb0961 100755
--- a/phenny
+++ b/phenny
@@ -30,7 +30,9 @@ def create_default_config(fn):
channels = ['#example', '#test']
owner = 'yournickname'
- # password = 'yourserverpassword'
+ # password is the NickServ password, serverpass is the server password
+ # password = 'example'
+ # serverpass = 'serverpass'
# These are people who will be able to use admin.py's functions...
admins = [owner, 'someoneyoutrust']