Skip to content

Commit e2c129c

Browse files
committed
SFN has been removed from the spec. Tests and docs updated.
1 parent 12c14f2 commit e2c129c

File tree

5 files changed

+117
-142
lines changed

5 files changed

+117
-142
lines changed

docs/index.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ The project is licensed under the MIT licence.
6666
Changelog
6767
=========
6868

69+
04 Jul 2017
70+
* Released v0.3.0
71+
* SFN was removed from the spec, so removed from the code
72+
* Tests and docs updated
73+
6974
03 Jul 2017
7075
* Released v0.2.0
7176
* Added SFN check; SFN is now required with every request

sqrlserver/request.py

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,13 @@ class Request(object):
4343
Args:
4444
key (bytes) : 32-byte encryption key. Must be the same as
4545
what you used to encrypt the nut.
46-
sfn (string) : Advertised Server Friendly Name. If sfn is passed
47-
in ``params`` and doesn't match what you pass, the request
48-
will be aborted.
4946
5047
params (dict) : All the query parameters from the query string
5148
and POST body.
5249
5350
The following parameters must exist:
5451
5552
- nut
56-
- sfn
5753
- server
5854
- client
5955
- ids
@@ -93,7 +89,7 @@ class Request(object):
9389
_known_opts = ['sqrlonly', 'hardlock', 'cps', 'suk']
9490
_supported_opts = ['sqrlonly', 'hardlock', 'cps', 'suk']
9591

96-
def __init__(self, key, sfn, params, **kwargs):
92+
def __init__(self, key, params, **kwargs):
9793
self.ipaddr = ipaddress.ip_address('0.0.0.0')
9894
if 'ipaddr' in kwargs:
9995
try:
@@ -130,7 +126,6 @@ def __init__(self, key, sfn, params, **kwargs):
130126
self._response = Response()
131127
self.params = dict(params)
132128
self.key = key
133-
self.sfn = sfn
134129
self.admin = False
135130

136131
#set initial state
@@ -499,7 +494,6 @@ def finalize(self, **kwargs):
499494
#add to response object
500495
r.addParam('nut', nutstr)
501496
r.addParam('qry', qry)
502-
r.addParam('sfn', depad(urlsafe_b64encode(self.sfn.encode('utf-8')).decode('utf-8')))
503497

504498
#return response object
505499
return r
@@ -522,7 +516,7 @@ def _check_well_formedness(self):
522516
"""
523517

524518
#required params
525-
for req in ['nut', 'sfn', 'client', 'server', 'ids']:
519+
for req in ['nut', 'client', 'server', 'ids']:
526520
if req not in self.params:
527521
return False
528522

@@ -572,7 +566,6 @@ def _check_validity(self):
572566
573567
``sigs`` : One or more signatures were invalid.
574568
``hmac`` : The HMAC didn't match.
575-
``sfn`` : The SFN doesn't match what you advertise
576569
``nut`` : The nut failed fundamental decryption checks.
577570
``ip`` : The ip addresses didn't match. Request confirmation.
578571
``time`` : The nut is stale. Request confirmation.
@@ -604,30 +597,25 @@ def _check_validity(self):
604597
errs.append('hmac')
605598

606599
if validmac:
607-
validsfn = True
608-
if self.params['sfn'] != depad(urlsafe_b64encode(self.sfn.encode('utf-8')).decode('utf-8')):
609-
validsfn = False
610-
errs.append('sfn')
611-
if validsfn:
612-
# Validate nut
613-
validnut = True
614-
nut = Nut(self.key)
615-
try:
616-
nut = nut.load(self.params['nut']).validate(self.ipaddr, self.ttl, maxcounter=self.maxcounter, mincounter=self.mincounter)
617-
except nacl.exceptions.CryptoError:
618-
validnut = False
619-
if not validnut:
620-
errs.append('nut')
621-
622-
if validnut:
623-
if not nut.ipmatch:
624-
errs.append('ip')
625-
else:
626-
self._response.tifOn(0x04)
627-
if not nut.fresh:
628-
errs.append('time')
629-
if not nut.countersane:
630-
errs.append('counter')
600+
# Validate nut
601+
validnut = True
602+
nut = Nut(self.key)
603+
try:
604+
nut = nut.load(self.params['nut']).validate(self.ipaddr, self.ttl, maxcounter=self.maxcounter, mincounter=self.mincounter)
605+
except nacl.exceptions.CryptoError:
606+
validnut = False
607+
if not validnut:
608+
errs.append('nut')
609+
610+
if validnut:
611+
if not nut.ipmatch:
612+
errs.append('ip')
613+
else:
614+
self._response.tifOn(0x04)
615+
if not nut.fresh:
616+
errs.append('time')
617+
if not nut.countersane:
618+
errs.append('counter')
631619

632620
return errs
633621

sqrlserver/url.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,15 @@ class Url(object):
1212
client will contact to authenticate. Includes the username,
1313
password, domain, and port. See RFC 3986, Jan 2005, section
1414
3.2 (https://tools.ietf.org/html/rfc3986#section-3.2)
15-
sfn (string) : The "server friendly name" the SQRL client will
16-
use to identify you to the user.
1715
secure (bool) : If True, uses the ``sqrl`` scheme, otherwise
1816
it uses ``qrl``. Defaults to True.
1917
2018
Returns:
2119
Url : The initial Url object
2220
"""
2321

24-
def __init__(self, authority, sfn, secure=True):
22+
def __init__(self, authority, secure=True):
2523
self.authority = authority
26-
self.sfn = sfn
2724
self.secure = secure
2825

2926
def generate(self, path, **kwargs):
@@ -92,7 +89,6 @@ def generate(self, path, **kwargs):
9289
query = kwargs['query']
9390
if ( ('ext' in kwargs) and (kwargs['ext'] is not None) and (kwargs['ext'] > 0) ):
9491
query.insert(0, ('x', kwargs['ext']))
95-
query.insert(0, ('sfn', depad(urlsafe_b64encode(self.sfn.encode('utf-8')).decode('utf-8'))))
9692
query.insert(0, ('nut', nutstr))
9793

9894
#build

0 commit comments

Comments
 (0)