/************************************************************************* * * * EJBCA Community: The OpenSource Certificate Authority * * * * This software is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or any later version. * * * * See terms of license at gnu.org. * * * *************************************************************************/ package org.ejbca.ui.cli.ra; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import org.cesecore.authorization.AuthorizationDeniedException; import org.cesecore.certificates.ca.CADoesntExistsException; import org.cesecore.certificates.ca.CAInfo; import org.cesecore.certificates.ca.CaSessionRemote; import org.cesecore.certificates.ca.IllegalNameException; import org.cesecore.certificates.certificate.CertificateConstants; import org.cesecore.certificates.certificate.exception.CertificateSerialNumberException; import org.cesecore.certificates.certificateprofile.CertificateProfileConstants; import org.cesecore.certificates.certificateprofile.CertificateProfileSessionRemote; import org.cesecore.certificates.endentity.EndEntityConstants; import org.cesecore.certificates.endentity.EndEntityType; import org.cesecore.certificates.endentity.EndEntityTypes; import org.cesecore.configuration.GlobalConfigurationSessionRemote; import org.cesecore.util.EjbRemoteHelper; import org.cesecore.util.StringTools; import org.ejbca.config.GlobalConfiguration; import org.ejbca.core.ejb.hardtoken.HardTokenSessionRemote; import org.ejbca.core.ejb.ra.EndEntityExistsException; import org.ejbca.core.ejb.ra.EndEntityManagementSessionRemote; import org.ejbca.core.ejb.ra.raadmin.EndEntityProfileSessionRemote; import org.ejbca.core.model.SecConst; import org.ejbca.core.model.approval.ApprovalException; import org.ejbca.core.model.approval.WaitingForApprovalException; import org.ejbca.core.model.authorization.AccessRulesConstants; import org.ejbca.core.model.ra.CustomFieldException; import org.ejbca.core.model.ra.raadmin.EndEntityProfileNotFoundException; import org.ejbca.core.model.ra.raadmin.EndEntityProfileValidationException; import org.ejbca.ui.cli.infrastructure.command.CommandResult; import org.ejbca.ui.cli.infrastructure.parameter.Parameter; import org.ejbca.ui.cli.infrastructure.parameter.ParameterContainer; import org.ejbca.ui.cli.infrastructure.parameter.enums.MandatoryMode; import org.ejbca.ui.cli.infrastructure.parameter.enums.ParameterMode; import org.ejbca.ui.cli.infrastructure.parameter.enums.StandaloneMode; /** * Adds an end entity to the database. * * @version $Id: AddEndEntityCommand.java 27775 2018-01-08 15:19:49Z mikekushner $ */ public class AddEndEntityCommand extends BaseRaCommand { private static final Logger log = Logger.getLogger(AddEndEntityCommand.class); private static final String USERGENERATED = "USERGENERATED"; private static final String P12 = "P12"; private static final String JKS = "JKS"; private static final String PEM = "PEM"; private static final String OLD_SUBCOMMAND = "adduser"; private static final String SUBCOMMAND = "addendentity"; private static final String[] SOFT_TOKEN_NAMES = { USERGENERATED, P12, JKS, PEM }; private static final int[] SOFT_TOKEN_IDS = { SecConst.TOKEN_SOFT_BROWSERGEN, SecConst.TOKEN_SOFT_P12, SecConst.TOKEN_SOFT_JKS, SecConst.TOKEN_SOFT_PEM }; private static final Set ALIASES = new HashSet(); static { ALIASES.add(OLD_SUBCOMMAND); } private static final String USERNAME_KEY = "--username"; private static final String PASSWORD_KEY = "--password"; private static final String DN_KEY = "--dn"; private static final String CA_NAME_KEY = "--caname"; private static final String TYPE_KEY = "--type"; private static final String TOKEN_KEY = "--token"; private static final String SUBJECT_ALT_NAME_KEY = "--altname"; private static final String EMAIL_KEY = "--email"; private static final String CERT_PROFILE_KEY = "--certprofile"; private static final String EE_PROFILE_KEY = "--eeprofile"; private static final String HARDTOKEN_ISSUER_KEY = "--hardtokenissuer"; private final GlobalConfiguration globalConfiguration = (GlobalConfiguration) EjbRemoteHelper.INSTANCE.getRemoteSession( GlobalConfigurationSessionRemote.class).getCachedConfiguration(GlobalConfiguration.GLOBAL_CONFIGURATION_ID); private final boolean usehardtokens = globalConfiguration.getIssueHardwareTokens(); { registerParameter(new Parameter(USERNAME_KEY, "Username", MandatoryMode.MANDATORY, StandaloneMode.ALLOW, ParameterMode.ARGUMENT, "Username for the new end entity.")); registerParameter(new Parameter(PASSWORD_KEY, "Password", MandatoryMode.OPTIONAL, StandaloneMode.FORBID, ParameterMode.ARGUMENT, "Password for the new end entity. Will be prompted for if not set.")); registerParameter(new Parameter(DN_KEY, "DN", MandatoryMode.MANDATORY, StandaloneMode.ALLOW, ParameterMode.ARGUMENT, "DN is of form \"C=SE, O=MyOrg, OU=MyOrgUnit, CN=MyName\" etc. " + "\nAn LDAP escaped DN is for example:\n" + "DN: CN=Tomas Gustavsson, O=PrimeKey Solutions, C=SE\n" + "LDAP escaped DN: CN=Tomas Gustavsson\\, O=PrimeKey Solutions\\, C=SE")); registerParameter(new Parameter(CA_NAME_KEY, "CA Name", MandatoryMode.MANDATORY, StandaloneMode.ALLOW, ParameterMode.ARGUMENT, "CA issuing this End Entity.")); registerParameter(new Parameter(SUBJECT_ALT_NAME_KEY, "Subject Name", MandatoryMode.OPTIONAL, StandaloneMode.FORBID, ParameterMode.ARGUMENT, "SubjectAltName is of form \"rfc822Name=, dNSName=, uri=," + " ipaddress=
, upn=, guid=, directoryName=," + " krb5principal=\"")); registerParameter(new Parameter(EMAIL_KEY, "E-Mail", MandatoryMode.OPTIONAL, StandaloneMode.FORBID, ParameterMode.ARGUMENT, "E-Mail of the new end entity.")); registerParameter(new Parameter(TYPE_KEY, "Type", MandatoryMode.MANDATORY, StandaloneMode.ALLOW, ParameterMode.ARGUMENT, "Type (mask): INVALID=0; END-USER=1; " + (globalConfiguration.getEnableKeyRecovery() ? "KEYRECOVERABLE=128; " : "") + "SENDNOTIFICATION=256; PRINTUSERDATA=512")); registerParameter(new Parameter(TOKEN_KEY, "Token", MandatoryMode.MANDATORY, StandaloneMode.ALLOW, ParameterMode.ARGUMENT, "Desired token type for the end entity: USERGENERATED, P12, JKS, PEM.")); registerParameter(new Parameter(CERT_PROFILE_KEY, "Profile Name", MandatoryMode.OPTIONAL, StandaloneMode.FORBID, ParameterMode.ARGUMENT, "The certificate profile, will default to End User.")); registerParameter(new Parameter(EE_PROFILE_KEY, "Profile Name", MandatoryMode.OPTIONAL, StandaloneMode.FORBID, ParameterMode.ARGUMENT, "The end entity profile, will default to Empty.")); if (usehardtokens) { registerParameter(new Parameter(HARDTOKEN_ISSUER_KEY, "Hard Token Issuer", MandatoryMode.OPTIONAL, StandaloneMode.FORBID, ParameterMode.ARGUMENT, "A hard token issuer.")); } } @Override public Set getMainCommandAliases() { return ALIASES; } @Override public String getMainCommand() { return SUBCOMMAND; } @Override public CommandResult execute(ParameterContainer parameters) { final String username = parameters.get(USERNAME_KEY); final String password = getAuthenticationCode(parameters.get(PASSWORD_KEY)); final String dn = parameters.get(DN_KEY); final String caname = parameters.get(CA_NAME_KEY); final String subjectaltname = parameters.get(SUBJECT_ALT_NAME_KEY); final String email = parameters.get(EMAIL_KEY); final EndEntityType type; final String tokenString = parameters.get(TYPE_KEY); try { type = new EndEntityType(EndEntityTypes.getTypesFromHexCode(Integer.parseInt(tokenString))); } catch (NumberFormatException e) { log.error("ERROR: Invalid type: " + tokenString); return CommandResult.FUNCTIONAL_FAILURE; } String tokenname = parameters.get(TOKEN_KEY); boolean error = false; boolean usehardtokenissuer = false; int caid = 0; try { CAInfo caInfo = EjbRemoteHelper.INSTANCE.getRemoteSession(CaSessionRemote.class).getCAInfo(getAuthenticationToken(), caname); if (caInfo != null) { // let it be 0 if not found, we will print a suitable error message below caid = caInfo.getCAId(); } } catch (AuthorizationDeniedException e) { log.error("CLI user not authorized to CA " + caname); error = true; } int certificatetypeid = CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER; final String certificateProfile = parameters.get(CERT_PROFILE_KEY); if (certificateProfile != null) { // Use certificate type, no end entity profile. certificatetypeid = EjbRemoteHelper.INSTANCE.getRemoteSession(CertificateProfileSessionRemote.class).getCertificateProfileId( certificateProfile); } getLogger().info( "Using certificate profile: " + EjbRemoteHelper.INSTANCE.getRemoteSession(CertificateProfileSessionRemote.class).getCertificateProfileName( certificatetypeid) + ", with id: " + certificatetypeid); final String endEntityProfile = parameters.get(EE_PROFILE_KEY); int endEntityProfileId = EndEntityConstants.EMPTY_END_ENTITY_PROFILE; if (endEntityProfile != null) { try { endEntityProfileId = EjbRemoteHelper.INSTANCE.getRemoteSession(EndEntityProfileSessionRemote.class).getEndEntityProfileId( endEntityProfile); } catch (EndEntityProfileNotFoundException e) { getLogger().error("ERROR: Could not find end entity profile in database."); error = true; } getLogger().info("Using entity profile: " + endEntityProfile + ", with id: " + endEntityProfileId); } int hardtokenissuerid = SecConst.NO_HARDTOKENISSUER; if (usehardtokens) { final String hardTokenIssuer = parameters.get(HARDTOKEN_ISSUER_KEY); if (hardTokenIssuer != null) { // Use certificate type, end entity profile and hardtokenissuer. hardtokenissuerid = EjbRemoteHelper.INSTANCE.getRemoteSession(HardTokenSessionRemote.class).getHardTokenIssuerId(hardTokenIssuer); usehardtokenissuer = true; getLogger().info("Using hard token issuer: " + hardTokenIssuer + ", with id: " + hardtokenissuerid); } } int tokenid = getTokenId(tokenname, usehardtokens, EjbRemoteHelper.INSTANCE.getRemoteSession(HardTokenSessionRemote.class)); if (tokenid == 0) { getLogger().error("Invalid token id."); error = true; } if (certificatetypeid == CertificateProfileConstants.CERTPROFILE_NO_PROFILE) { // Certificate profile not found in database. getLogger().error("Could not find certificate profile in database."); error = true; } if (caid == 0) { // CA not found i database. getLogger().error("Could not find CA '" + caname + "' in database."); error = true; } if (usehardtokenissuer && hardtokenissuerid == SecConst.NO_HARDTOKENISSUER) { getLogger().error("Could not find hard token issuer in database."); error = true; } if ((tokenid > SecConst.TOKEN_SOFT) && (hardtokenissuerid == SecConst.NO_HARDTOKENISSUER)) { getLogger().error("HardTokenIssuer has to be choosen when user with hard tokens is added."); error = true; } if (email == null && type.contains(EndEntityTypes.SENDNOTIFICATION)) { getLogger().error("Email field cannot be null when send notification type is given."); error = true; } // Check if username already exists. if (EjbRemoteHelper.INSTANCE.getRemoteSession(EndEntityManagementSessionRemote.class).existsUser(username)) { getLogger().error("ERROR: User '" + username + "' already exists in the database."); error = true; } if (!error) { getLogger().info("Trying to add end entity:"); getLogger().info("Username: " + username); getLogger().info("Password: