/* * Copyright (C) 2014 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.trustagent.cmd; import com.intel.dcsg.cpg.console.Command; import com.intel.dcsg.cpg.console.input.Input; import com.intel.dcsg.cpg.crypto.RandomUtil; import com.intel.mtwilson.shiro.file.LoginDAO; import com.intel.mtwilson.trustagent.TrustagentConfiguration; import org.apache.commons.configuration.Configuration; import com.intel.mtwilson.shiro.file.model.UserPassword; import com.intel.mtwilson.shiro.file.model.UserPermission; import com.intel.mtwilson.crypto.password.PasswordUtil; import java.io.IOException; import java.nio.charset.Charset; import java.util.List; /** * * @author jbuhacoff */ public class Password implements Command { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Password.class); private TrustagentConfiguration configuration; private Configuration options; private LoginDAO dao; @Override public void setOptions(Configuration options) { this.options = options; } // never returns null but password may be empty (and that's allowed) private String getPassword(String[] args) throws IOException { String password; if( options.getBoolean("nopass", false) ) { password = ""; } else if(args.length > 1) { password = args[1]; // always after username if present if( password == null || password.isEmpty() ) { throw new IllegalArgumentException("Password is empty"); } if( password.startsWith("env:") && password.length() > 4 ) { String variableName = password.substring(4); password = System.getenv(variableName); if( password == null || password.isEmpty() ) { throw new IllegalArgumentException(String.format("Environment variable %s does not contain a password", variableName)); } } } else { password = Input.getConfirmedPasswordWithPrompt(String.format("Choose a password for %s",args[0])); // throws IOException, or always returns value or expression if( password == null || password.isEmpty() ) { throw new IllegalArgumentException("Input password is empty"); } } return password; } // get the 3rd arg if it's usrename passsword permissions, or the 2nd arg if it's username --nopass permissions private String getPermissions(String[] args) { String permissions = null; if( args.length == 2 && options.getBoolean("nopass", false) ) { permissions = args[1]; } else if(args.length == 3 ) { permissions = args[2]; } return permissions; } @Override public void execute(String[] args) throws Exception { configuration = TrustagentConfiguration.loadConfiguration(); // store or replace the user record log.debug("Loading users and permissions"); dao = new LoginDAO(configuration.getTrustagentUserFile(), configuration.getTrustagentPermissionsFile()); // usage: username (prompt for password, no permissions) // usage: username password (no permissions) // usage: username password permissions // usage: username --nopass (no permissions) // usage: username --nopass permissions // usage: username --remove String username = args[0]; if( options.getBoolean("remove",false) ) { removeUser(username); removePermissions(username); log.info("Removed username {}", username); return; } String password = getPassword(args); // never returns null but password may be empty // create the new user record UserPassword userPassword = new UserPassword(); userPassword.setAlgorithm("SHA256"); userPassword.setIterations(1); userPassword.setSalt(RandomUtil.randomByteArray(8)); byte[] hashedPassword = PasswordUtil.hash(password.getBytes(Charset.forName("UTF-8")), userPassword); userPassword.setUsername(username); userPassword.setPasswordHash(hashedPassword); removeUser(username); dao.createUser(userPassword); log.info("Created user {}", username); String newPermissions = getPermissions(args); if( newPermissions != null ) { removePermissions(username); dao.addPermission(username, newPermissions); log.info("Added permissions {}", newPermissions); } } private void removeUser(String username) throws IOException { UserPassword existingUser = dao.findUserByName(username); if( existingUser != null ) { dao.deleteUserByName(username); } } private void removePermissions(String username) throws IOException { List<UserPermission> existingPermissions = dao.getPermissions(username); for(UserPermission existingPermission : existingPermissions) { dao.removePermission(username, existingPermission.toString()); } } }