Skip to content
Snippets Groups Projects
Commit 63d10037 authored by ale's avatar ale
Browse files

Merge branch 'py3' into 'master'

Drop Python 2 support

See merge request !4
parents 91ccfcb1 0061e8c9
No related branches found
No related tags found
1 merge request!4Drop Python 2 support
......@@ -93,7 +93,7 @@ dnl Python-dev (actually only used for $PYTHON)
AX_PYTHON_DEVEL
dnl nosetests
AC_PATH_PROG([NOSETESTS], [nosetests])
AC_PATH_PROG([NOSETESTS], [nosetests${PYTHON_VERSION}])
dnl GoogleTest (use the embedded version)
GTEST_LIBS="\$(top_builddir)/lib/gtest/libgtest.la"
......
9
10
......@@ -3,9 +3,9 @@ Section: net
Priority: extra
Maintainer: Autistici/Inventati <debian@autistici.org>
Build-Depends: debhelper (>= 10), apache2-dev | apache2-prefork-dev | apache2-threaded-dev,
apache2, autoconf, automake, libtool, python-dev, dh-python, python-all,
libpam-dev, libssl-dev, python-setuptools, python-flup, pkg-config, libz-dev,
python-m2crypto, python-flask, python-nose, python-mox, python-beautifulsoup
apache2, autoconf, automake, libtool, python3-dev, dh-python, python3-all,
libpam-dev, libssl-dev, python3-setuptools, pkg-config, libz-dev,
python3-requests, python3-nose, python3-mox
Standards-Version: 3.7.2
Package: ai-sso
......
......@@ -9,7 +9,7 @@
override_dh_auto_configure:
sh autogen.sh
./configure --prefix=/usr --with-pam-dir=/lib/security --enable-pam-sso --enable-mod-sso --enable-shared
./configure --prefix=/usr --with-pam-dir=/lib/security --enable-pam-sso --enable-mod-sso --enable-shared PYTHON_VERSION=3
override_dh_auto_install:
install -d $(CURDIR)/debian/tmp/etc/sso
......
......@@ -7,7 +7,7 @@ if ENABLE_PAM_SSO
PAM_SSO_SUBDIR = pam_sso
endif
PYTHON_SUBDIR = python sso_server
PYTHON_SUBDIR = python #sso_server
SUBDIRS = \
sso \
......
#!/usr/bin/python
import Cookie
import httplib
import os
import re
import requests
import subprocess
import sys
import time
import unittest
import urllib
import urlparse
from urllib.parse import urlencode, urlsplit, parse_qsl
sys.path.append("../../python")
import sso
......@@ -31,7 +29,7 @@ devnull = open(os.devnull)
def _start_httpd(public_key, config_file):
with open('public.key', 'w') as fd:
with open('public.key', 'wb') as fd:
fd.write(public_key)
env = dict(os.environ)
env['TESTROOT'] = os.getcwd()
......@@ -58,7 +56,7 @@ def _start_httpd(public_key, config_file):
return httpd
def _stop_httpd(httpd):
def _stop_httpd(httpd, dump_log=False):
httpd.terminate()
time.sleep(1)
try:
......@@ -66,23 +64,25 @@ def _stop_httpd(httpd):
except OSError:
pass
dump_log = (os.getenv('DUMP_APACHE_LOG') == '1')
if os.getenv('DUMP_APACHE_LOG'):
dump_log = True
status = httpd.wait()
if os.WIFEXITED(status):
if os.WEXITSTATUS(status) != 0:
print 'WARNING: httpd exited with status %d' % os.WEXITSTATUS(status)
print('WARNING: httpd exited with status %d' % os.WEXITSTATUS(status))
dump_log = True
elif os.WIFSIGNALED(status):
print 'WARNING: httpd exited due to signal %d' % os.WTERMSIG(status)
print('WARNING: httpd exited due to signal %d' % os.WTERMSIG(status))
dump_log = True
else:
print 'WARNING: httpd exited for unknown reason (returncode=%d)' % status
print('WARNING: httpd exited for unknown reason (returncode=%d)' % status)
dump_log = True
if dump_log:
print('*** APACHE LOG ***')
with open(APACHE_LOG) as fd:
for line in fd:
print line.rstrip('\n')
print(line.rstrip('\n'))
for f in ('public.key', 'test-httpd.pid', '.apache_log'):
try:
......@@ -93,20 +93,20 @@ def _stop_httpd(httpd):
def _query(url, host=None, cookie=None):
"""Make a simple request to url using httplib."""
conn = httplib.HTTPConnection("127.0.0.1", APACHE_PORT)
headers = {"Host": host or "localhost"}
if cookie:
headers["Cookie"] = cookie
conn.request("GET", url, headers=headers)
resp = conn.getresponse()
headers['Cookie'] = cookie
resp = requests.get(
f'http://127.0.0.1:{APACHE_PORT}{url}',
headers=headers,
allow_redirects=False)
location = None
body = None
if resp.status in (301, 302):
location = resp.getheader("Location")
elif resp.status == 200:
body = resp.read()
conn.close()
return (resp.status, body, location)
if resp.status_code in (301, 302):
location = resp.headers["Location"]
elif resp.status_code == 200:
body = resp.text
return (resp.status_code, body, location)
def mkcookie(tkt):
......@@ -116,9 +116,9 @@ def mkcookie(tkt):
class HttpdKeyLoadingTest(unittest.TestCase):
def test_key_with_null_byte(self):
has_null_byte = lambda s: '\0' in s
has_null_byte = lambda s: 0 in s
public = ''
public = b''
while not has_null_byte(public):
public, secret = sso.generate_keys()
......@@ -138,6 +138,7 @@ class HttpdKeyLoadingTest(unittest.TestCase):
class HttpdIntegrationTestBase(unittest.TestCase):
CONFIG = None
DUMP_LOG = False
def setUp(self):
self.public, self.secret = sso.generate_keys()
......@@ -145,7 +146,7 @@ class HttpdIntegrationTestBase(unittest.TestCase):
self.httpd = _start_httpd(self.public, self.CONFIG)
def tearDown(self):
_stop_httpd(self.httpd)
_stop_httpd(self.httpd, self.DUMP_LOG)
def _ticket(self, user="testuser", group="group1", service="service.example.com/",
nonce=None):
......@@ -238,8 +239,8 @@ class HttpdIntegrationTestBase(unittest.TestCase):
"status": 401 }),
]
for name, check in checks:
for i in xrange(repeats):
print 'CHECKING %s (%d of 10)' % (name, i), check
for i in range(repeats):
print('CHECKING %s (%d of 10)' % (name, i), check)
status, body, location = _query(check["url"],
host=check.get("http_host"),
cookie=check.get("cookie"))
......@@ -268,48 +269,41 @@ class HttpdIntegrationTestBase(unittest.TestCase):
if not sso_login_url:
sso_login_url = '/%s/sso_login' % sso_service.split('/', 1)[1]
cookies = Cookie.SimpleCookie()
sess = requests.Session()
# Make a request to a protected URL.
conn = httplib.HTTPConnection("127.0.0.1", APACHE_PORT)
conn.request("GET", url, headers={'Host': host_header})
resp = conn.getresponse()
self.assertEquals(302, resp.status)
set_cookie_hdr = resp.getheader("Set-Cookie")
self.assertTrue(set_cookie_hdr)
cookies.load(set_cookie_hdr)
location = resp.getheader("Location")
location_u = urlparse.urlsplit(location)
location_args = dict(urlparse.parse_qsl(location_u.query))
resp = sess.get(
f'http://127.0.0.1:{APACHE_PORT}{url}',
headers={'Host': host_header},
allow_redirects=False)
self.assertEquals(302, resp.status_code)
location = resp.headers["Location"]
location_u = urlsplit(location)
location_args = dict(parse_qsl(location_u.query))
nonce = location_args.get('n')
self.assertTrue(nonce)
conn.close()
session_cookie = resp.cookies['_sso_local_session']
# Now call the /sso_login endpoint.
conn = httplib.HTTPConnection("127.0.0.1", APACHE_PORT)
tkt = self._ticket(nonce=nonce, service=sso_service)
conn.request("GET", sso_login_url + "?" + urllib.urlencode(
{"t": tkt, "d": "https://" + host_header + url}), headers={
"Cookie": cookies.output(attrs=[], header='', sep='; '),
"Host": host_header,
})
resp = conn.getresponse()
self.assertEquals(302, resp.status)
set_cookie_hdr = resp.getheader("Set-Cookie")
self.assertTrue(set_cookie_hdr)
cookies.load(set_cookie_hdr)
self.assertEquals(tkt, cookies['SSO_test'].value)
conn.close()
query_args = urlencode({"t": tkt, "d": "https://" + host_header + url})
resp = sess.get(
f'http://127.0.0.1:{APACHE_PORT}{sso_login_url}?{query_args}',
headers={'Host': host_header},
cookies={'_sso_local_session': session_cookie},
allow_redirects=False)
self.assertEquals(302, resp.status_code)
self.assertTrue('SSO_test' in resp.cookies,
'missing cookie: %s\n%s' % (resp.cookies, resp.headers))
self.assertEquals(tkt, resp.cookies['SSO_test'])
# Make the original request again.
conn = httplib.HTTPConnection("127.0.0.1", APACHE_PORT)
conn.request("GET", url, headers={
"Cookie": cookies.output(attrs=[], header='', sep='; '),
'Host': host_header,
})
resp = conn.getresponse()
self.assertEquals(200, resp.status)
conn.close()
resp = sess.get(
f'http://127.0.0.1:{APACHE_PORT}{url}',
headers={'Host': host_header},
cookies={'SSO_test': tkt},
allow_redirects=False)
self.assertEquals(200, resp.status_code)
class HttpdIntegrationTest(HttpdIntegrationTestBase):
......@@ -324,8 +318,7 @@ class HttpdIntegrationTest(HttpdIntegrationTestBase):
# to spot issues where we are not cleaning up state properly
# between requests.
n = 100
errors = 0
for i in xrange(n):
for i in range(n):
cookie = 'SSO_test=%s' % self._ticket()
status, body, location = _query("/index.html", cookie=cookie)
self.assertEquals(200, status)
......@@ -345,29 +338,28 @@ class HttpdIntegrationTest(HttpdIntegrationTestBase):
def test_sso_login(self):
# Call the /sso_login endpoint, verify that it sets the local
# SSO cookie to whatever the 't' parameter says.
cookies = Cookie.SimpleCookie()
conn = httplib.HTTPConnection("127.0.0.1", APACHE_PORT)
tkt = self._ticket()
conn.request("GET", "/sso_login?%s" % urllib.urlencode(
{"t": tkt, "d": "https://service.example.com/index.html"}))
resp = conn.getresponse()
self.assertEquals(302, resp.status)
set_cookie_hdr = resp.getheader("Set-Cookie")
query_args = urlencode(
{"t": tkt, "d": "https://service.example.com/index.html"})
resp = requests.get(
f'http://127.0.0.1:{APACHE_PORT}/sso_login?{query_args}',
allow_redirects=False)
self.assertEquals(302, resp.status_code)
set_cookie_hdr = resp.headers["Set-Cookie"]
self.assertTrue(set_cookie_hdr)
cookies.load(set_cookie_hdr)
self.assertEquals(tkt, cookies['SSO_test'].value)
conn.close()
self.assertTrue('SSO_test' in resp.cookies,
'missing cookie: %s' % resp.cookies)
self.assertEquals(tkt, resp.cookies['SSO_test'])
def test_sso_logout(self):
# test the /sso_logout endpoint
conn = httplib.HTTPConnection("127.0.0.1", APACHE_PORT)
conn.request("GET", "/sso_logout", headers={
"Cookie": mkcookie(self._ticket())})
resp = conn.getresponse()
set_cookie_hdr = resp.getheader("Set-Cookie")
resp = requests.get(
f'http://127.0.0.1:{APACHE_PORT}/sso_logout',
headers={"Cookie": mkcookie(self._ticket())},
allow_redirects=False)
set_cookie_hdr = resp.headers["Set-Cookie"]
self.assertTrue(set_cookie_hdr)
self.assertTrue("SSO_test=;" in set_cookie_hdr)
conn.close()
class HttpdIntegrationTestWithNonces(HttpdIntegrationTestBase):
......@@ -375,7 +367,7 @@ class HttpdIntegrationTestWithNonces(HttpdIntegrationTestBase):
CONFIG = 'test-httpd-2.4-nonces.conf'
def setUp(self):
with open('session.key', 'w') as fd:
with open('session.key', 'wb') as fd:
fd.write(os.urandom(32))
HttpdIntegrationTestBase.setUp(self)
......@@ -409,9 +401,10 @@ class HttpdIntegrationTestWithNonces(HttpdIntegrationTestBase):
class WebmailIntegrationTestWithNonces(HttpdIntegrationTestBase):
CONFIG = 'test-httpd-2.4-webmail.conf'
DUMP_LOG = True
def setUp(self):
with open('session.key', 'w') as fd:
with open('session.key', 'wb') as fd:
fd.write(os.urandom(32))
HttpdIntegrationTestBase.setUp(self)
......
......@@ -87,9 +87,3 @@ def install_handler(jar=None, **kwargs):
urllib2.build_opener(urllib2.HTTPCookieProcessor(jar),
SSOProcessor(**kwargs)))
if __name__ == '__main__':
install_handler()
resp = urllib2.urlopen('https://wiki.autistici.org/')
print resp.read()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment