Skip to content

Commit 3cd2b4c

Browse files
committed
Revert "tweak to remove new scripts. will tests all pass now?"
This reverts commit 264714b.
1 parent 264714b commit 3cd2b4c

2 files changed

Lines changed: 198 additions & 0 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bats
2+
3+
# The tests in this BATS module must be run as a (passwordless) sudo-enabled user.
4+
# It is also required that the python irodsclient be installed under irods' ~/.local environment.
5+
6+
. $BATS_TEST_DIRNAME/test_support_functions
7+
8+
setup() {
9+
[ -f /tmp/test011_flag ] || {
10+
rm -fr ~/.irods
11+
/prc/test_harness/utility/iinit.py host localhost \
12+
port 1247 \
13+
zone tempZone \
14+
user rods \
15+
password rods \
16+
17+
## Because iRODS 5+ negotiates for SSL automatically:
18+
CLIENT_JSON=~/.irods/irods_environment.json
19+
jq '.irods_client_server_policy="CS_NEG_REFUSE"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \
20+
mv $CLIENT_JSON.$$ $CLIENT_JSON
21+
22+
sudo apt install -y irods-auth-plugin-pam-interactive-{client,server}
23+
24+
setup_pam_login_for_user "rods" alice
25+
26+
# Tests require only the irods_environment.json
27+
rm -f ~/.irods/.irodsA
28+
29+
## Switch over to scheme to be tested.
30+
jq '.irods_authentication_scheme="pam_interactive"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \
31+
mv $CLIENT_JSON.$$ $CLIENT_JSON
32+
}
33+
touch /tmp/test011_flag
34+
}
35+
36+
original_test_suite()
37+
{
38+
local USER="alice"
39+
local PASSWORD="rods"
40+
sudo chpasswd <<<"$USER:$PASSWORD"
41+
python -m unittest irods.test.pam_interactive_test_must_run_manually
42+
}
43+
44+
@test "original_pam_interactive_tests" {
45+
original_test_suite
46+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#!/usr/bin/env bats
2+
3+
# The tests in this BATS module must be run as a (passwordless) sudo-enabled user.
4+
# It is also required that the python irodsclient be installed under irods' ~/.local environment.
5+
6+
SKIP_IINIT_FOR_PASSWORD=yes
7+
8+
. $BATS_TEST_DIRNAME/test_support_functions
9+
10+
export TESTUSER="john"
11+
export FIRST_PASSWORD="=i;r@o\\d&s" # somerods
12+
export SECOND_PASSWORD="otherrods"
13+
export CLIENT_AUTH_ERROR_EXITCODE=123
14+
15+
ssl_hash() {
16+
openssl passwd -6 "$1"
17+
}
18+
19+
setup() {
20+
[ -f /tmp/test012_flag ] || {
21+
rm -fr ~/.irods
22+
/prc/test_harness/utility/iinit.py host localhost \
23+
port 1247 \
24+
zone tempZone \
25+
user rods \
26+
password rods \
27+
28+
sudo apt update
29+
sudo apt install -y db-util libpam0g-dev jq
30+
31+
## Because iRODS 5+ negotiates for SSL automatically:
32+
CLIENT_JSON=~/.irods/irods_environment.json
33+
jq '.irods_client_server_policy="CS_NEG_REFUSE"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \
34+
mv $CLIENT_JSON.$$ $CLIENT_JSON
35+
36+
sudo apt install -y irods-auth-plugin-pam-interactive-{client,server}
37+
SERVER_CONFIG=server_config.json
38+
39+
sudo -s <<-EOF
40+
jq '.plugin_configuration.authentication.pam_interactive = {
41+
"pam_stack_name": "pam_interactive"
42+
}' <"/etc/irods/${SERVER_CONFIG}" >"/tmp/${SERVER_CONFIG}"
43+
cp -rp "/etc/irods/${SERVER_CONFIG}"{,.orig}
44+
mv -f "/tmp/${SERVER_CONFIG}" "/etc/irods/${SERVER_CONFIG}"
45+
EOF
46+
waitsrv() {
47+
while true; do
48+
sleep 5
49+
ils >& /dev/null && break
50+
done
51+
}
52+
53+
{ sudo kill -HUP `sudo cat /tmp/irods.pid` && waitsrv; } || {
54+
echo "Couldn't properly bounce server after configuration change."; exit 1; }
55+
56+
setup_pam_login_for_user "${FIRST_PASSWORD}" $TESTUSER
57+
sudo cp $BATS_TEST_DIRNAME/files_for_test012/pam_password /etc/pam.d/irods
58+
sudo cp $BATS_TEST_DIRNAME/files_for_test012/pam_interactive /etc/pam.d/
59+
sudo mkdir /t012 && sudo gcc -o /t012/pam_clear_token.so -fno-stack-protector -shared -fPIC $BATS_TEST_DIRNAME/files_for_test012/pam_clear_token.c
60+
61+
# Tests require only the irods_environment.json
62+
rm -f ~/.irods/.irodsA
63+
64+
## Switch over to scheme to be tested.
65+
jq '.irods_authentication_scheme="pam_interactive"' >$CLIENT_JSON.$$ <$CLIENT_JSON && \
66+
mv $CLIENT_JSON.$$ $CLIENT_JSON
67+
}
68+
touch /tmp/test012_flag
69+
}
70+
71+
encode_2nd_password() {
72+
db_file=/t012/pam_userdb.db
73+
sudo db_load -T -t hash "$db_file" <<<"${TESTUSER}"$'\n'"$(ssl_hash ${1})"
74+
sudo chown root:root "$db_file"
75+
sudo chmod 600 "$db_file"
76+
}
77+
78+
SCRIPT="
79+
import getpass
80+
import os
81+
82+
import irods
83+
from irods.auth import ClientAuthError
84+
from unittest.mock import patch
85+
86+
def getpass_new_callable(answers=()):
87+
class iterate_answers:
88+
def __init__(self,answers = answers):
89+
self.answers = answers
90+
self.count = 0
91+
def __call__(self,*_):
92+
count = self.count
93+
self.count += 1
94+
ans = self.answers[count]
95+
print ('*** giving answer:', ans)
96+
return ans
97+
return lambda : iterate_answers()
98+
99+
home = None
100+
101+
pw_count = 0
102+
103+
with patch(
104+
'getpass.getpass',
105+
new_callable=getpass_new_callable(answers=[os.environ['FIRST_PASSWORD'],os.environ['SECOND_PASSWORD']])
106+
) as m:
107+
try:
108+
sess = irods.helpers.make_session(test_server_version=False)
109+
sess.set_auth_option_for_scheme('pam_interactive', irods.auth.FORCE_PASSWORD_PROMPT, True)
110+
home = sess.collections.get(f'/{sess.zone}/home/{sess.username}')
111+
except ClientAuthError as exc:
112+
# Note: The write to stdout, and the specific exit code, are necessary for the test assertions.
113+
# in test "pam_interactive_test_multistep_with_incorrect_2nd_password" below.
114+
print(f'ERROR: {exc!r}')
115+
exit(int(os.environ['CLIENT_AUTH_ERROR_EXITCODE']))
116+
finally:
117+
pw_count = m.count
118+
119+
# Assert both passwords were prompted for.
120+
if pw_count < 2:
121+
print(f'************************ {pw_count = } < 2')
122+
exit(3)
123+
124+
# Assert home is defined, ie a session was successfully created and used to retrieve a collection object
125+
if home is None:
126+
exit(2)
127+
128+
username = os.environ['TESTUSER']
129+
130+
# Assert home contains the expected username.
131+
if not home.path.endswith(f'/{username}'):
132+
exit(1)
133+
"
134+
135+
@test "pam_interactive_test_multistep_with_incorrect_2nd_password" {
136+
137+
# We are using a deliberately munged password.
138+
encode_2nd_password "_${SECOND_PASSWORD}"
139+
local STATUS=""
140+
OUTPUT=$(python -c "$SCRIPT" 2>&1) || STATUS=$?
141+
142+
# Here, we assert the process's exit and output conform to expectation. We want to
143+
# enforce that the stdout output stream contains the thrown exception name ("ClientAuthError")
144+
# as well as that the process exits with a particular error status.
145+
[ $STATUS = $CLIENT_AUTH_ERROR_EXITCODE ]
146+
[[ $OUTPUT =~ ClientAuthError ]]
147+
}
148+
149+
@test "pam_interactive_test_multistep_with_correct_2nd_password" {
150+
encode_2nd_password "${SECOND_PASSWORD}"
151+
python -c "$SCRIPT"
152+
}

0 commit comments

Comments
 (0)