Skip to content

Commit 6962952

Browse files
committed
[#522][#523] allow '=' and ';' in PAM passwords
1 parent ed2e73c commit 6962952

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed

irods/api_number.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,5 +179,7 @@
179179
"GET_RESOURCE_INFO_FOR_OPERATION_AN": 10220,
180180
"ATOMIC_APPLY_METADATA_OPERATIONS_APN": 20002,
181181
"GET_FILE_DESCRIPTOR_INFO_APN": 20000,
182-
"REPLICA_CLOSE_APN": 20004
182+
"REPLICA_CLOSE_APN": 20004,
183+
184+
"AUTH_PLUG_REQ_AN": 1201
183185
}

irods/connection.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
from irods.message import (PamAuthRequest, PamAuthRequestOut)
2626

2727

28-
29-
ALLOW_PAM_LONG_TOKENS = True # True to fix [#279]
3028
# Message to be logged when the connection
3129
# destructor is called. Used in a unit test
3230
DESTRUCTOR_MSG = "connection __del__() called"
@@ -490,9 +488,12 @@ def _login_pam(self):
490488
if getattr(self,'DISALLOWING_PAM_PLAINTEXT',True):
491489
raise PlainTextPAMPasswordError
492490

493-
Pam_Long_Tokens = (ALLOW_PAM_LONG_TOKENS and (len(ctx) >= MAX_NAME_LEN))
491+
# In general authentication API, a ';' and '=' in the password would be misinterpreted due to those
492+
# characters' special meaning in the context string parameter.
493+
use_dedicated_pam_api = len(ctx) >= MAX_NAME_LEN or \
494+
{';','='}.intersection(set(new_pam_password))
494495

495-
if Pam_Long_Tokens:
496+
if use_dedicated_pam_api:
496497
message_body = PamAuthRequest( pamUser = self.account.client_user,
497498
pamPassword = new_pam_password,
498499
timeToLive = time_to_live_in_hours)
@@ -502,7 +503,7 @@ def _login_pam(self):
502503
auth_req = iRODSMessage(
503504
msg_type='RODS_API_REQ',
504505
msg=message_body,
505-
int_info=(725 if Pam_Long_Tokens else 1201)
506+
int_info=api_number['PAM_AUTH_REQUEST_AN' if use_dedicated_pam_api else 'AUTH_PLUG_REQ_AN']
506507
)
507508

508509
self.send(auth_req)
@@ -513,8 +514,7 @@ def _login_pam(self):
513514
# TODO (#480): In Python3 will be able to do: 'raise RuntimeError(...) from exc' for more succinct error messages
514515
raise RuntimeError('Client-configured TTL is outside server parameters (password min and max times)')
515516

516-
Pam_Response_Class = (PamAuthRequestOut if Pam_Long_Tokens
517-
else AuthPluginOut)
517+
Pam_Response_Class = (PamAuthRequestOut if use_dedicated_pam_api else AuthPluginOut)
518518

519519
auth_out = output_message.get_main_message( Pam_Response_Class )
520520

irods/test/PRC_issue_362.bats

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,45 @@
11
# The tests in this BATS module must be run as a (passwordless) sudo-enabled user.
22
# It is also required that the python irodsclient be installed under irods' ~/.local environment.
33

4+
. $BATS_TEST_DIRNAME/scripts/funcs
45

56
setup() {
6-
local -A chars=(
7-
[semicolon]=";"
8-
[atsymbol]="@"
9-
[equals]="="
10-
[ampersand]="&"
11-
)
12-
[ $BATS_TEST_NUMBER = 1 ] && echo "---" >/tmp/PRC_test_issue_362
13-
local name=${BATS_TEST_DESCRIPTION##*_}
14-
CHR="${chars[$name]}"
7+
8+
iinit_as_rods
9+
10+
setup_pam_login_for_user "test123" alice
11+
12+
cat >~/test_get_home_coll.py <<-EOF
13+
import irods.test.helpers as h
14+
ses = h.make_session()
15+
home_coll = h.home_collection(ses)
16+
exit(0 if ses.collections.get(home_coll).path == home_coll
17+
and ses.pool.account._original_authentication_scheme.lower() in ('pam','pam_password')
18+
else 1)
19+
EOF
1520
}
1621

17-
TEST_THE_TEST=""
22+
teardown() {
23+
iinit_as_rods
24+
finalize_pam_login_for_user alice
25+
}
1826

1927
prc_test()
2028
{
21-
local USER="alissa"
22-
local PASSWORD=$(tr "." "$CHR" <<<"my.pass")
23-
echo "$USER:$PASSWORD" | sudo chpasswd
24-
if [ "$TEST_THE_TEST" = 1 ]; then
25-
echo -n `date`: "" >&2
26-
{ su - "$USER" -c "id" <<<"$PASSWORD" 2>/dev/null | grep $USER ; } >&2
27-
else
28-
sudo su - irods -c "env PYTHON_IRODSCLIENT_TEST_PAM_PW_OVERRIDE='$PASSWORD' python -m unittest \
29-
irods.test.login_auth_test.TestLogins.test_escaped_pam_password_chars__362"
30-
fi
31-
} 2>> /tmp/PRC_test_issue_362
32-
33-
@test "test_with_atsymbol" { prc_test; }
34-
@test "test_with_semicolon" { prc_test; }
35-
@test "test_with_equals" { prc_test; }
36-
@test "test_with_ampersand" { prc_test; }
29+
local CHR="$1"
30+
## Arrange for secrets file to be generated internally by the Python client
31+
cat >~/.python_irodsclient <<-EOF
32+
legacy_auth.pam.store_password_to_environment True
33+
legacy_auth.pam.password_for_auto_renew 'my${CHR}pass'
34+
legacy_auth.pam.time_to_live_in_hours 1
35+
EOF
36+
local USER="alice"
37+
local PASSWORD="my${CHR}pass"
38+
sudo chpasswd <<<"$USER:$PASSWORD"
39+
env PYTHON_IRODSCLIENT_CONFIGURATION_PATH='' python ~/test_get_home_coll.py
40+
}
41+
42+
@test "test_with_atsymbol" { prc_test "@"; }
43+
@test "test_with_semicolon" { prc_test ";"; }
44+
@test "test_with_equals" { prc_test "="; }
45+
@test "test_with_ampersand" { prc_test "&"; }

0 commit comments

Comments
 (0)