Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion irods/api_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,5 +179,7 @@
"GET_RESOURCE_INFO_FOR_OPERATION_AN": 10220,
"ATOMIC_APPLY_METADATA_OPERATIONS_APN": 20002,
"GET_FILE_DESCRIPTOR_INFO_APN": 20000,
"REPLICA_CLOSE_APN": 20004
"REPLICA_CLOSE_APN": 20004,

"AUTH_PLUG_REQ_AN": 1201
}
14 changes: 7 additions & 7 deletions irods/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
from irods.message import (PamAuthRequest, PamAuthRequestOut)



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

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

if Pam_Long_Tokens:
if use_dedicated_pam_api:
message_body = PamAuthRequest( pamUser = self.account.client_user,
pamPassword = new_pam_password,
timeToLive = time_to_live_in_hours)
Expand All @@ -502,7 +503,7 @@ def _login_pam(self):
auth_req = iRODSMessage(
msg_type='RODS_API_REQ',
msg=message_body,
int_info=(725 if Pam_Long_Tokens else 1201)
int_info=api_number['PAM_AUTH_REQUEST_AN' if use_dedicated_pam_api else 'AUTH_PLUG_REQ_AN']
)

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

Pam_Response_Class = (PamAuthRequestOut if Pam_Long_Tokens
else AuthPluginOut)
Pam_Response_Class = (PamAuthRequestOut if use_dedicated_pam_api else AuthPluginOut)

auth_out = output_message.get_main_message( Pam_Response_Class )

Expand Down
61 changes: 35 additions & 26 deletions irods/test/PRC_issue_362.bats
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
# The tests in this BATS module must be run as a (passwordless) sudo-enabled user.
# It is also required that the python irodsclient be installed under irods' ~/.local environment.

. $BATS_TEST_DIRNAME/scripts/funcs

setup() {
local -A chars=(
[semicolon]=";"
[atsymbol]="@"
[equals]="="
[ampersand]="&"
)
[ $BATS_TEST_NUMBER = 1 ] && echo "---" >/tmp/PRC_test_issue_362
local name=${BATS_TEST_DESCRIPTION##*_}
CHR="${chars[$name]}"

iinit_as_rods

setup_pam_login_for_user "test123" alice

cat >~/test_get_home_coll.py <<-EOF
import irods.test.helpers as h
ses = h.make_session()
home_coll = h.home_collection(ses)
exit(0 if ses.collections.get(home_coll).path == home_coll
and ses.pool.account._original_authentication_scheme.lower() in ('pam','pam_password')
else 1)
EOF
}

TEST_THE_TEST=""
teardown() {
iinit_as_rods
finalize_pam_login_for_user alice
}

prc_test()
{
local USER="alissa"
local PASSWORD=$(tr "." "$CHR" <<<"my.pass")
echo "$USER:$PASSWORD" | sudo chpasswd
if [ "$TEST_THE_TEST" = 1 ]; then
echo -n `date`: "" >&2
{ su - "$USER" -c "id" <<<"$PASSWORD" 2>/dev/null | grep $USER ; } >&2
else
sudo su - irods -c "env PYTHON_IRODSCLIENT_TEST_PAM_PW_OVERRIDE='$PASSWORD' python -m unittest \
irods.test.login_auth_test.TestLogins.test_escaped_pam_password_chars__362"
fi
} 2>> /tmp/PRC_test_issue_362

@test "test_with_atsymbol" { prc_test; }
@test "test_with_semicolon" { prc_test; }
@test "test_with_equals" { prc_test; }
@test "test_with_ampersand" { prc_test; }
local CHR="$1"
## Arrange for secrets file to be generated internally by the Python client
cat >~/.python_irodsclient <<-EOF
legacy_auth.pam.store_password_to_environment True
legacy_auth.pam.password_for_auto_renew 'my${CHR}pass'
legacy_auth.pam.time_to_live_in_hours 1
EOF
local USER="alice"
local PASSWORD="my${CHR}pass"
sudo chpasswd <<<"$USER:$PASSWORD"
env PYTHON_IRODSCLIENT_CONFIGURATION_PATH='' python ~/test_get_home_coll.py
}

@test "test_with_atsymbol" { prc_test "@"; }
@test "test_with_semicolon" { prc_test ";"; }
@test "test_with_equals" { prc_test "="; }
@test "test_with_ampersand" { prc_test "&"; }