Skip to content

Commit

Permalink
Add pki-server <subsystem>-user-mod --password
Browse files Browse the repository at this point in the history
The pki-server <subsystem>-user-mod has been updated to provide
a way to change the user password. This could be used to restore
access to PKI server in case the current password is lost or the
user cert has expired.

The UGSubsystem.modifyUser() has been modified to remove the
userPassword attribute from the user record if the password is
blank.

The test for admin user has been updated to validate password
change and password removal.
  • Loading branch information
edewata committed Aug 24, 2023
1 parent 872a925 commit c5dd663
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 22 deletions.
78 changes: 66 additions & 12 deletions .github/workflows/ca-admin-user-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,45 +75,100 @@ jobs:
sed -n 's/^ *Type: *\(.*\)$/\1/p' output > actual
diff expected actual
- name: Check CA admin certs
- name: Check auth with CA admin password
run: |
# import CA signing cert
docker exec pki pki-server cert-export ca_signing --cert-file ca_signing.crt
docker exec pki pki client-cert-import ca_signing --ca-cert ca_signing.crt
# correct password should work
docker exec pki pki -u caadmin -w Secret.123 ca-user-find
# wrong password should not work
docker exec pki pki -u caadmin -w wrong ca-user-find \
> >(tee stdout) 2> >(tee stderr >&2) || true
echo "PKIException: Unauthorized" > expected
diff expected stderr
- name: Change CA admin password
run: |
docker exec pki pki-server ca-user-mod --password new caadmin
# original password should no longer work
docker exec pki pki -u caadmin -w Secret.123 ca-user-find \
> >(tee stdout) 2> >(tee stderr >&2) || true
echo "PKIException: Unauthorized" > expected
diff expected stderr
# new password should work
docker exec pki pki -u caadmin -w new ca-user-find
- name: Change CA admin password with file
run: |
echo secret > secret.txt
docker exec pki pki-server ca-user-mod --password-file $SHARED/secret.txt caadmin
# password file should work
docker exec pki pki -u caadmin -w secret ca-user-find
- name: Remove CA admin password
run: |
docker exec pki pki-server ca-user-mod --password "" caadmin
# old password should no longer work
docker exec pki pki -u caadmin -w secret ca-user-find \
> >(tee stdout) 2> >(tee stderr >&2) || true
echo "PKIException: Unauthorized" > expected
diff expected stderr
# blank password should not work
docker exec pki pki -u caadmin -w "" ca-user-find \
> >(tee stdout) 2> >(tee stderr >&2) || true
echo "PKIException: Unauthorized" > expected
diff expected stderr
- name: Check certs assigned to CA admin user
run: |
docker exec pki pki-server ca-user-cert-find caadmin | tee output
# get admin cert ID
sed -n 's/^ *Cert ID: *\(.*\)$/\1/p' output > cert.id
CERT_ID=$(cat cert.id)
echo "CERT_ID: $CERT_ID"
- name: Authentication and authorization with CA admin cert should work
- name: Check auth with CA admin cert
run: |
docker exec pki pki-server cert-export ca_signing --cert-file ca_signing.crt
docker exec pki pki client-cert-import ca_signing --ca-cert ca_signing.crt
# import admin cert
docker exec pki pki pkcs12-import \
--pkcs12 /root/.dogtag/pki-tomcat/ca_admin_cert.p12 \
--pkcs12-password Secret.123
# admin cert should work
docker exec pki pki -n caadmin ca-user-find
- name: Remove CA admin cert
- name: Unassign certs from CA admin user
run: |
CERT_ID=$(cat cert.id)
echo "CERT_ID: $CERT_ID"
docker exec pki pki-server ca-user-cert-del caadmin "$CERT_ID"
# admin should have no certs
# admin user should have no certs
docker exec pki pki-server ca-user-cert-find caadmin | tee actual
diff /dev/null actual
- name: Authentication with CA admin cert should not work
run: |
# admin cert should no longer work
docker exec pki pki -n caadmin ca-user-find \
> >(tee stdout) 2> >(tee stderr >&2) || true
echo "PKIException: Unauthorized" > expected
diff expected stderr
- name: Restore CA admin cert
- name: Reassign certs to CA admin user
run: |
CERT_ID=$(cat cert.id)
echo "CERT_ID: $CERT_ID"
Expand All @@ -126,8 +181,7 @@ jobs:
sed -n 's/^ *Cert ID: *\(.*\)$/\1/p' output > actual
diff cert.id actual
- name: Authentication with CA admin cert should work again
run: |
# admin cert should work again
docker exec pki pki -n caadmin ca-user-find
- name: Check CA admin roles
Expand Down
15 changes: 14 additions & 1 deletion base/server/python/pki/server/cli/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ def print_help(self):
print('Usage: pki-server %s-user-mod [OPTIONS] <user ID>' % self.parent.parent.name)
print()
print(' -i, --instance <instance ID> Instance ID (default: pki-tomcat).')
print(' --password <password> User password')
print(' --password-file <path> User password file')
print(' --add-see-also <subject DN> Link user to a certificate.')
print(' --del-see-also <subject DN> Unlink user from a certificate.')
print(' -v, --verbose Run in verbose mode.')
Expand All @@ -295,7 +297,8 @@ def print_help(self):
def execute(self, argv):
try:
opts, args = getopt.gnu_getopt(argv, 'i:v', [
'instance=', 'add-see-also=', 'del-see-also=',
'instance=', 'password=', 'password-file=',
'add-see-also=', 'del-see-also=',
'verbose', 'debug', 'help'])

except getopt.GetoptError as e:
Expand All @@ -305,13 +308,21 @@ def execute(self, argv):

instance_name = 'pki-tomcat'
subsystem_name = self.parent.parent.name
password = None
password_file = None
add_see_also = None
del_see_also = None

for o, a in opts:
if o in ('-i', '--instance'):
instance_name = a

elif o == '--password':
password = a

elif o == '--password-file':
password_file = a

elif o == '--add-see-also':
add_see_also = a

Expand Down Expand Up @@ -356,6 +367,8 @@ def execute(self, argv):

subsystem.modify_user(
user_id,
password=password,
password_file=password_file,
add_see_also=add_see_also,
del_see_also=del_see_also)

Expand Down
16 changes: 14 additions & 2 deletions base/server/python/pki/server/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1825,11 +1825,23 @@ def add_user(self,
finally:
shutil.rmtree(tmpdir)

def modify_user(self, user_id, add_see_also=None, del_see_also=None,
as_current_user=False):
def modify_user(
self,
user_id,
password=None,
password_file=None,
add_see_also=None,
del_see_also=None,
as_current_user=False):

cmd = [self.name + '-user-mod']

if password is not None:
cmd.extend(['--password', password])

if password_file is not None:
cmd.extend(['--password-file', password_file])

if add_see_also:
cmd.append('--add-see-also')
cmd.append(add_see_also)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1134,9 +1134,12 @@ public void modifyUser(User identity) throws EUsrGrpException {

attrs.add(LDAPModification.REPLACE, ld);
}
if ((st = user.getPassword()) != null && (!st.equals(""))) {
attrs.add(LDAPModification.REPLACE,
new LDAPAttribute("userpassword", st));
if ((st = user.getPassword()) != null) {
if (st.equals("")) {
attrs.add(LDAPModification.DELETE, new LDAPAttribute("userPassword"));
} else {
attrs.add(LDAPModification.REPLACE, new LDAPAttribute("userPassword", st));
}
}
if ((st = user.getPhone()) != null) {
if (!st.equals("")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@
//
package org.dogtagpki.server.cli;

import java.io.BufferedReader;
import java.io.FileReader;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.dogtagpki.cli.CLI;
import org.dogtagpki.cli.CLIException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netscape.certsrv.user.UserCollection;
import com.netscape.cmscore.apps.EngineConfig;
import com.netscape.cmscore.ldapconn.LDAPConfig;
import com.netscape.cmscore.ldapconn.PKISocketConfig;
import com.netscape.cmscore.usrgrp.UGSubsystem;
import com.netscape.cmscore.usrgrp.UGSubsystemConfig;
import com.netscape.cmscore.usrgrp.User;
import com.netscape.cmsutil.password.PasswordStore;
import com.netscape.cmsutil.password.PasswordStoreConfig;

Expand All @@ -34,7 +38,15 @@ public SubsystemUserModifyCLI(CLI parent) {
@Override
public void createOptions() {

Option option = new Option(null, "add-see-also", true, "Link user to a certificate.");
Option option = new Option(null, "password", true, "User password");
option.setArgName("password");
options.addOption(option);

option = new Option(null, "password-file", true, "User password file");
option.setArgName("password-file");
options.addOption(option);

option = new Option(null, "add-see-also", true, "Link user to a certificate.");
option.setArgName("subject DN");
options.addOption(option);

Expand Down Expand Up @@ -70,13 +82,30 @@ public void execute(CommandLine cmd) throws Exception {

UGSubsystem ugSubsystem = new UGSubsystem();

String password = cmd.getOptionValue("password");
String passwordFile = cmd.getOptionValue("password-file");

if (passwordFile != null) {
try (BufferedReader br = new BufferedReader(new FileReader(passwordFile))) {
password = br.readLine();
}
}

String addSeeAlso = cmd.getOptionValue("add-see-also");
String delSeeAlso = cmd.getOptionValue("del-see-also");

UserCollection response = new UserCollection();

try {
ugSubsystem.init(ldapConfig, socketConfig, passwordStore);
User user = ugSubsystem.getUser(userID);

if (user == null) {
throw new CLIException("User not found: " + userID);
}

if (password != null) {
user.setPassword(password);
ugSubsystem.modifyUser(user);
}

if (addSeeAlso != null) {
ugSubsystem.addSeeAlso(userID, addSeeAlso);
Expand Down

0 comments on commit c5dd663

Please sign in to comment.