Permalink
Browse files

Merge pull request #1 from Leberwurscht/master

add security features in spec and cleanup code
  • Loading branch information...
jcarbaugh committed Apr 4, 2012
2 parents b893ca3 + 4bf4fa9 commit d37e3f71a3975985d67ab1992015d736b8551b14
Showing with 35 additions and 24 deletions.
  1. +35 −24 pywebfinger.py
View
@@ -17,69 +17,80 @@
'http://webfinger.info/rel/service', # deprecated on 09/17/2009
)
-class WebFingerExpection(Exception):
+class WebFingerException(Exception):
pass
class WebFingerResponse(object):
-
- def __init__(self, xrd):
+
+ def __init__(self, xrd, insecure):
+ self.insecure = insecure
self._xrd = xrd
-
+
def __getattr__(self, name):
if name in RELS:
return self._xrd.find_link(RELS[name], attr='href')
return getattr(self._xrd, name)
class WebFingerClient(object):
-
- def __init__(self, host, secure=False):
+
+ def __init__(self, host, timeout=None):
self._host = host
- self._secure = secure
self._opener = urllib2.build_opener(urllib2.HTTPRedirectHandler())
self._opener.addheaders = [('User-agent', 'python-webfinger')]
-
+
+ self._timeout = timeout
+
def _hm_hosts(self, xrd):
return [e.value for e in xrd.elements if e.name == 'hm:Host']
-
+
def xrd(self, url, raw=False):
- conn = self._opener.open(url)
+ conn = self._opener.open(url, timeout=self._timeout)
response = conn.read()
conn.close()
return response if raw else XRD.parse(response)
-
- def hostmeta(self):
- protocol = "https" if self._secure else "http"
+
+ def hostmeta(self, protocol):
hostmeta_url = "%s://%s/.well-known/host-meta" % (protocol, self._host)
return self.xrd(hostmeta_url)
-
+
def finger(self, username):
-
- hm = self.hostmeta()
+ try:
+ hm = self.hostmeta('https')
+ insecure = False
+ except (urllib2.URLError, urllib2.HTTPError):
+ hm = self.hostmeta('http')
+ insecure = True
+
hm_hosts = self._hm_hosts(hm)
-
+
if self._host not in hm_hosts:
- raise WebFingerExpection("hostmeta host did not match account host")
-
+ raise WebFingerException("hostmeta host did not match account host")
+
template = hm.find_link(WEBFINGER_TYPES, attr='template')
+ if not template.startswith('https://'):
+ insecure = True
xrd_url = template.replace('{uri}',
urllib.quote_plus('acct:%s@%s' % (username, self._host)))
-
- return WebFingerResponse(self.xrd(xrd_url))
-def finger(identifier, secure=False):
+ data = self.xrd(xrd_url)
+ return WebFingerResponse(data, insecure)
+
+def finger(identifier, timeout=None):
if identifier.startswith('acct:'):
(acct, identifier) = identifier.split(':', 1)
(username, host) = identifier.split('@')
- client = WebFingerClient(host, secure)
+ client = WebFingerClient(host, timeout=timeout)
return client.finger(username)
# example main method
if __name__ == '__main__':
import sys
- wf = finger(sys.argv[1], True)
+ wf = finger(sys.argv[1])
print "Avatar: ", wf.avatar
print "HCard: ", wf.hcard
print "OpenID: ", wf.open_id
print "Profile:", wf.profile
print "XFN: ", wf.find_link('http://gmpg.org/xfn/11', attr='href')
+ if wf.insecure:
+ print "Warning: Data was retrieved over an insecure connection"

0 comments on commit d37e3f7

Please sign in to comment.