Work towards the security stuff described at

http://code.google.com/p/webfinger/wiki/WebFingerProtocol

The code now looks for the host-meta file via https. If it doesn't find it it
falls back to http, but causes the response's 'insecure' attribute to be set
to True.

The 'insecure' attribute also gets set to True if the user's XRD URL is not an
https:// url.

This doesn't do any checking of certificate validity, or check whether the XML
is signed.
pull/1/head
buttoj3 2011-04-11 12:12:16 +01:00
rodzic b893ca3fa8
commit 142bba7a6d
1 zmienionych plików z 20 dodań i 11 usunięć

Wyświetl plik

@ -22,7 +22,8 @@ class WebFingerExpection(Exception):
class WebFingerResponse(object):
def __init__(self, xrd):
def __init__(self, xrd, insecure):
self.insecure = insecure
self._xrd = xrd
def __getattr__(self, name):
@ -32,9 +33,8 @@ class WebFingerResponse(object):
class WebFingerClient(object):
def __init__(self, host, secure=False):
def __init__(self, host):
self._host = host
self._secure = secure
self._opener = urllib2.build_opener(urllib2.HTTPRedirectHandler())
self._opener.addheaders = [('User-agent', 'python-webfinger')]
@ -47,39 +47,48 @@ class WebFingerClient(object):
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")
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))
data = self.xrd(xrd_url)
return WebFingerResponse(data, insecure)
def finger(identifier, secure=False):
def finger(identifier):
if identifier.startswith('acct:'):
(acct, identifier) = identifier.split(':', 1)
(username, host) = identifier.split('@')
client = WebFingerClient(host, secure)
client = WebFingerClient(host)
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"