...
 
Commits (8)
......@@ -181,13 +181,14 @@ class CaucaseSSLWSGIRequestHandler(CaucaseWSGIRequestHandler):
def log_message(self, format, *args):
# Note: compared to BaseHTTPHandler, logs the client certificate serial as
# user name.
sys.stderr.write(
"%s - %s [%s] %s\n" % (
print(
"%s - %s [%s] %s" % (
self.client_address[0],
self.ssl_client_cert_serial,
self.log_date_time_string(),
format % args,
)
),
file=sys.stderr,
)
# pylint: enable=redefined-builtin
......@@ -284,7 +285,7 @@ def getSSLContext(
x509.CertificateSigningRequestBuilder(
subject_name=x509.Name([
x509.NameAttribute(
oid=x509.oid.NameOID.COMMON_NAME,
oid=x509.oid.NameOID.ORGANIZATIONAL_UNIT_NAME,
value=hostname_dnsname,
),
]),
......@@ -308,8 +309,8 @@ def getSSLContext(
Extension(
x509.SubjectAlternativeName([
x509.DNSName(hostname_dnsname)
if hostname_ip_address is None
else x509.IPAddress(hostname_ip_address),
if hostname_ip_address is None else
x509.IPAddress(hostname_ip_address)
]),
critical=True,
),
......@@ -662,12 +663,13 @@ def main(argv=None, until=utils.until):
if host in known_host_set:
continue
known_host_set.add(host)
sys.stderr.write(
'Listening on [%s]:%i-%i\n' % (
print(
'Listening on [%s]:%i-%i' % (
host,
http_port,
https_port,
),
file=sys.stderr,
)
http_list.append(
make_server(
......@@ -780,7 +782,7 @@ def main(argv=None, until=utils.until):
except utils.SleepInterrupt:
pass
finally:
sys.stderr.write('Exiting\n')
print('Exiting', file=sys.stderr)
for server in itertools.chain(http_list, https_list):
server.server_close()
server.shutdown()
......
......@@ -1423,11 +1423,14 @@ class CaucaseTest(unittest.TestCase):
getCertificateSigningRequest = _placeholder
getCertificate = _placeholder
server_name = u'caucase.example.com'
server_http_port = 8000
server_https_port = server_http_port + 1
application = wsgi.Application(
DummyCAU(),
None,
'http://caucase.example.com:8000',
'https://caucase.example.com:8001',
'http://%s:%i' % (server_name, server_http_port),
'https://%s:%i' % (server_name, server_https_port),
wsgi.CORSTokenManager(),
)
def request(environ):
......@@ -1436,9 +1439,8 @@ class CaucaseTest(unittest.TestCase):
"""
environ.setdefault('wsgi.errors', sys.stderr)
environ.setdefault('wsgi.url_scheme', 'http')
name, port = self._server_netloc.split(':')
environ.setdefault('SERVER_NAME', name)
environ.setdefault('SERVER_PORT', port)
environ.setdefault('SERVER_NAME', server_name)
environ.setdefault('SERVER_PORT', str(server_http_port))
start_response_list = []
body = list(application(
environ,
......@@ -1458,14 +1460,17 @@ class CaucaseTest(unittest.TestCase):
return int(status), reason, header_dict, b''.join(body)
UNAUTHORISED_STATUS = 401
HATEOAS_HTTP_PREFIX = u"http://caucase.example.com:8000/base/path"
HATEOAS_HTTPS_PREFIX = u"https://caucase.example.com:8001/base/path"
HATEOAS_HTTP_PREFIX = u"http://%s:%i/base/path" % (
server_name,
server_http_port,
)
HATEOAS_HTTPS_PREFIX = u"https://%s:%i/base/path" % (
server_name,
server_https_port,
)
root_hateoas_request = request({
'SCRIPT_NAME': '/base/path',
'REQUEST_METHOD': 'GET',
'wsgi.url_scheme': 'http',
'SERVER_NAME': 'caucase.example.com',
'SERVER_PORT': '8000',
})
self.maxDiff = None
self.assertEqual(root_hateoas_request[0], 200)
......@@ -1489,9 +1494,6 @@ class CaucaseTest(unittest.TestCase):
'SCRIPT_NAME': '/base/path',
'PATH_INFO': '/cau/',
'REQUEST_METHOD': 'GET',
'wsgi.url_scheme': 'http',
'SERVER_NAME': 'caucase.example.com',
'SERVER_PORT': '8000',
})
self.assertEqual(cau_hateoas_request[0], 200)
self.assertEqual(cau_hateoas_request[2]['Content-Type'], 'application/hal+json')
......@@ -1655,37 +1657,37 @@ class CaucaseTest(unittest.TestCase):
'PATH_INFO': '/cau/crt/renew',
'REQUEST_METHOD': 'PUT',
'CONTENT_TYPE': 'application/json',
'wsgi.input': StringIO('{'),
'wsgi.input': StringIO(u'{'),
})[0], 400)
self.assertEqual(request({
'PATH_INFO': '/cau/crt/revoke',
'REQUEST_METHOD': 'PUT',
'CONTENT_TYPE': 'application/json',
'wsgi.input': StringIO('{"digest": null}'),
'wsgi.input': StringIO(u'{"digest": null}'),
})[0], UNAUTHORISED_STATUS)
self.assertEqual(request({
'PATH_INFO': '/cau/crt/revoke',
'REQUEST_METHOD': 'PUT',
'CONTENT_TYPE': 'application/json',
'wsgi.input': StringIO('{"digest":"sha256","payload":""}'),
'wsgi.input': StringIO(u'{"digest":"sha256","payload":""}'),
})[0], 400)
self.assertEqual(request({
'PATH_INFO': '/cau/crt/a',
'REQUEST_METHOD': 'PUT',
'CONTENT_TYPE': 'text/plain',
'wsgi.input': StringIO(''),
'wsgi.input': StringIO(u''),
})[0], 400)
self.assertEqual(request({
'PATH_INFO': '/cau/crt/123',
'REQUEST_METHOD': 'PUT',
'CONTENT_TYPE': 'text/plain',
'wsgi.input': StringIO(''),
'wsgi.input': StringIO(u''),
})[0], UNAUTHORISED_STATUS)
self.assertEqual(request({
'PATH_INFO': '/cau/crt/123',
'REQUEST_METHOD': 'PUT',
'CONTENT_TYPE': 'text/plain',
'wsgi.input': StringIO('foo'),
'wsgi.input': StringIO(u'foo'),
})[0], 400)
self.assertEqual(request({
'PATH_INFO': '/cau/crt/123',
......@@ -1781,7 +1783,7 @@ class CaucaseTest(unittest.TestCase):
self.assertEqual(
header_dict['WWW-Authenticate'],
'cors url=' + quote(
'https://localhost:8000/cors?' +
'https://%s:%i/cors?' % (server_name, server_https_port) +
urlencode([('origin', cross_origin)]) +
'{&return}',
),
......@@ -1870,7 +1872,7 @@ class CaucaseTest(unittest.TestCase):
'PATH_INFO': '/cors',
'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'wsgi.input': StringIO(urlencode(input_dict)),
'wsgi.input': StringIO(utils.toUnicode(urlencode(input_dict))),
}
base_request_reader_dict.update(kw)
return base_request_reader_dict
......@@ -2565,8 +2567,12 @@ class CaucaseTest(unittest.TestCase):
self._stopServer()
os.unlink(self._server_key)
os.unlink(self._server_db)
self._server_netloc = '[::1]:8000'
self._caucase_url = 'http://' + self._server_netloc
netloc = '[::1]'
port = urlparse.urlparse(self._caucase_url).port
if port:
netloc += ':%s' % port
self._server_netloc = netloc
self._caucase_url = 'http://' + netloc
self._startServer()
user_key_path = self._createFirstUser()
service_key = self._createAndApproveCertificate(
......@@ -2584,7 +2590,7 @@ class CaucaseTest(unittest.TestCase):
x509.CRLDistributionPoints,
).value
uri, = distribution_point.full_name
self.assertEqual(uri.value, u'http://[::1]:8000/cas/crl')
self.assertEqual(uri.value, self._caucase_url + u'/cas/crl')
def testServerFilePermissions(self):
"""
......
......@@ -455,7 +455,7 @@ def toUnicode(value, encoding='ascii'):
def toBytes(value, encoding='ascii'):
"""
Convert valye to bytes object, if it is not already.
Convert value to bytes object, if it is not already.
"""
return value if isinstance(value, bytes) else value.encode(encoding)
......
......@@ -78,8 +78,6 @@ CORS_COOKIE_ORIGIN_KEY = 'o' # Prevent an origin from stealing another's token.
A_YEAR_IN_SECONDS = 60 * 60 * 24 * 365 # Roughly a year
toHTTPS = lambda url: urlunparse(('https', ) + urlparse(url)[1:])
def _getStatus(code):
return '%i %s' % (code, httplib.responses[code])
......@@ -726,8 +724,7 @@ class Application(object):
header_list may be modified before raising OriginUnauthorized, in order to
give client an opportunity to clean stale/broken values.
"""
my_uri = application_uri(environ)
my_origin = my_uri.split('/', 1)[0]
my_origin = application_uri(environ).split('/', 1)[0]
origin = environ.get('HTTP_ORIGIN', my_origin)
if origin == my_origin:
# Not a CORS request
......@@ -776,10 +773,8 @@ class Application(object):
if access is None:
# Missing or malformed cookie, missing or expired or invalid entry
# for origin: require authentication via cors form.
if not my_uri.endswith('/'):
my_uri += '/'
raise OriginUnauthorized(
toHTTPS(my_uri) + 'cors?' +
self._https_url + '/cors?' +
urlencode([(CORS_FORM_ORIGIN_PARAMETER, origin)]) +
'{&' + CORS_FORM_RETURN_PARAMETER + '}',
)
......@@ -877,7 +872,7 @@ class Application(object):
return (
STATUS_FOUND,
[
('Location', toHTTPS(request_uri(environ))),
('Location', self._https_url),
],
[],
)
......