Skip to content

Commit

Permalink
add PAM plugin to test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
grooverdan committed Aug 29, 2015
1 parent bcea1a6 commit 93fdb75
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ branch = True
source =
pymysql
omit = pymysql/test/*
pymysql/tests/thirdparty/test_MySQLdb/*


[report]
Expand Down
13 changes: 11 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ sudo: false
language: python
python: "3.4"
cache:
directories:
- mysql
- pip

env:
matrix:
Expand All @@ -27,6 +26,7 @@ matrix:
env:
- TOX_ENV=py33
- EXTRAPKG=mariadb-test
- PAMCLEAR=1
sudo: required
- addons:
mariadb: 10.1
Expand All @@ -41,6 +41,9 @@ matrix:
apt:
packages:
- libaio-dev
cache:
directories:
- mysql
# really only need libaio1 however libaio-dev is whitelisted
#
# http://dev.mysql.com/downloads/mysql/5.7.html
Expand All @@ -52,6 +55,10 @@ install:
- if [ -n "${EXTRAPKG}" ]; then
sudo apt-get install ${EXTRAPKG};
fi
- if [ -n "${PAMCLEAR}" ]; then
echo -e '[mysqld]\n\nplugin-load=auth_pam.so\npam-use-cleartext-plugin' | sudo tee -a /etc/mysql/pam-cleartext.cnf;
sudo service mysql restart;
fi
- pip install -U tox coveralls

before_script:
Expand Down Expand Up @@ -80,6 +87,8 @@ before_script:
- export COVERALLS_PARALLEL=true

script:
- export PAMSERVICE=chfn
- export PASSWORD=travis
- tox -e $TOX_ENV

after_success:
Expand Down
39 changes: 33 additions & 6 deletions pymysql/tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ def authenticate(self, pkt):
break
return pkt

class DefectiveHandler(object):
def __init__(self, con):
self.con=con


@unittest2.skipUnless(socket_auth, "connection to unix_socket required")
Expand Down Expand Up @@ -227,11 +230,8 @@ def realTestDialogAuthThreeAttempts(self):
with self.assertRaises(pymysql.err.OperationalError):
pymysql.connect(user='pymysql_3a', plugin_map={b'dialog': object}, **self.db)

class DefectiveHandler(object):
def __init__(self, con):
self.con=con
with self.assertRaises(pymysql.err.OperationalError):
pymysql.connect(user='pymysql_3a', plugin_map={b'dialog': DefectiveHandler}, **self.db)
pymysql.connect(user='pymysql_3a', plugin_map={b'dialog': TestAuthentication.DefectiveHandler}, **self.db)
with self.assertRaises(pymysql.err.OperationalError):
pymysql.connect(user='pymysql_3a', plugin_map={b'notdialogplugin': TestAuthentication.Dialog}, **self.db)
TestAuthentication.Dialog.m = {b'Password, please:': b'I do not know'}
Expand All @@ -241,19 +241,46 @@ def __init__(self, con):
with self.assertRaises(pymysql.err.OperationalError):
pymysql.connect(user='pymysql_3a', plugin_map={b'dialog': TestAuthentication.Dialog}, **self.db)

@unittest2.skipUnless(socket_auth, "connection to unix_socket required")
@unittest2.skipIf(pam_found, "pam plugin already installed")
@unittest2.skipIf(os.environ.get('PASSWORD') is None, "PASSWORD env var required")
@unittest2.skipIf(os.environ.get('PAMSERVICE') is None, "PAMSERVICE env var required")
def testPamAuthInstallPlugin(self):
# needs plugin. lets install it.
cur = self.connections[0].cursor()
try:
cur.execute("install plugin pam soname 'auth_pam.so'")
TestAuthentication.pam_found = True
self.realTestPamAuth()
except pymysql.err.InternalError:
raise unittest2.SkipTest('we couldn\'t install the auth_pam plugin')
finally:
if TestAuthentication.pam_found:
cur.execute("uninstall plugin pam")


@unittest2.skipUnless(socket_auth, "connection to unix_socket required")
@unittest2.skipUnless(pam_found, "no pam plugin")
@unittest2.skipIf(os.environ.get('PASSWORD') is None, "PASSWORD env var required")
@unittest2.skipIf(os.environ.get('PAMSERVICE') is None, "PAMSERVICE env var required")
def testPamAuth(self):
self.realTestPamAuth()

def realTestPamAuth(self):
db = self.db.copy()
db['password'] = b'bad guess at password'
import os
db['password'] = os.environ.get('PASSWORD')

with TempUser(self.connections[0].cursor(), TestAuthentication.osuser + '@localhost',
self.databases[0]['db'], self.pam_plugin_name) as u:
self.databases[0]['db'], 'pam', os.environ.get('PAMSERVICE')) as u:
try:
c = pymysql.connect(user=TestAuthentication.osuser, **db)
except pymysql.OperationalError as e:
self.assertEqual(1045, e.args[0])
return
# else we had 'bad guess at password' work with pam. Well cool
with self.assertRaises(pymysql.err.OperationalError):
pymysql.connect(user=TestAuthentication.osuser + '@localhost', plugin_map={b'mysql_cleartext_password': TestAuthentication.DefectiveHandler}, **self.db)

# select old_password("crummy p\tassword");
#| old_password("crummy p\tassword") |
Expand Down
2 changes: 2 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ commands = coverage run ./runtests.py
deps = unittest2
coverage
passenv = USER
PASSWORD
PAMSERVICE

0 comments on commit 93fdb75

Please sign in to comment.