From 3e3581286bdf064cabb46b2c30bca73e6a78ea58 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Fri, 25 Apr 2014 14:48:29 -0400 Subject: [PATCH] Merged #50 "Prohibit creation and storage of empty ssh keys" --- src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java | 116 +++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 79 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java b/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java index 62daec6..da58584 100644 --- a/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java +++ b/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java @@ -25,7 +25,6 @@ import org.slf4j.LoggerFactory; import com.gitblit.Constants.AccessPermission; -import com.gitblit.models.UserModel; import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.transport.ssh.SshKey; import com.gitblit.transport.ssh.commands.CommandMetaData; @@ -47,12 +46,13 @@ public class KeysDispatcher extends DispatchCommand { @Override - protected void setup(UserModel user) { - register(user, AddKey.class); - register(user, RemoveKey.class); - register(user, ListKeys.class); - register(user, WhichKey.class); - register(user, CommentKey.class); + protected void setup() { + register(AddKey.class); + register(RemoveKey.class); + register(ListKeys.class); + register(WhichKey.class); + register(CommentKey.class); + register(PermissionKey.class); } @CommandMetaData(name = "add", description = "Add an SSH public key to your account") @@ -61,7 +61,7 @@ protected final Logger log = LoggerFactory.getLogger(getClass()); - @Argument(metaVar = "<KEY>", usage = "the key(s) to add") + @Argument(metaVar = "<STDIN>", usage = "the key to add") private List<String> addKeys = new ArrayList<String>(); @Option(name = "--permission", aliases = { "-p" }, metaVar = "PERMISSION", usage = "set the key access permission") @@ -76,18 +76,31 @@ } @Override - public void run() throws IOException, UnloggedFailure { + public void run() throws IOException, Failure { String username = getContext().getClient().getUsername(); List<String> keys = readKeys(addKeys); + if (keys.isEmpty()) { + throw new UnloggedFailure("No public keys were read from STDIN!"); + } for (String key : keys) { SshKey sshKey = parseKey(key); + try { + // this method parses the rawdata and produces a public key + // if it fails it will throw a Buffer.BufferException + // the null check is a QC verification on top of that + if (sshKey.getPublicKey() == null) { + throw new RuntimeException(); + } + } catch (RuntimeException e) { + throw new UnloggedFailure("The data read from SDTIN can not be parsed as an SSH public key!"); + } if (!StringUtils.isEmpty(permission)) { AccessPermission ap = AccessPermission.fromCode(permission); if (ap.exceeds(AccessPermission.NONE)) { try { sshKey.setPermission(ap); } catch (IllegalArgumentException e) { - throw new UnloggedFailure(1, e.getMessage()); + throw new Failure(1, e.getMessage()); } } } @@ -105,22 +118,21 @@ private final String ALL = "ALL"; - @Argument(metaVar = "<INDEX>|<KEY>|ALL", usage = "the key to remove", required = true) - private List<String> removeKeys = new ArrayList<String>(); + @Argument(metaVar = "<INDEX>|ALL", usage = "the key to remove", required = true) + private List<String> keyParameters = new ArrayList<String>(); @Override - public void run() throws IOException, UnloggedFailure { + public void run() throws IOException, Failure { String username = getContext().getClient().getUsername(); // remove a key that has been piped to the command // or remove all keys - List<SshKey> currentKeys = getKeyManager().getKeys(username); - if (currentKeys == null || currentKeys.isEmpty()) { + List<SshKey> registeredKeys = new ArrayList<SshKey>(getKeyManager().getKeys(username)); + if (registeredKeys.isEmpty()) { throw new UnloggedFailure(1, "There are no registered keys!"); } - List<String> keys = readKeys(removeKeys); - if (keys.contains(ALL)) { + if (keyParameters.contains(ALL)) { if (getKeyManager().removeAllKeys(username)) { stdout.println("Removed all keys."); log.info("removed all SSH public keys from {}", username); @@ -128,32 +140,25 @@ log.warn("failed to remove all SSH public keys from {}", username); } } else { - for (String key : keys) { + for (String keyParameter : keyParameters) { try { // remove a key by it's index (1-based indexing) - int index = Integer.parseInt(key); - if (index > keys.size()) { - if (keys.size() == 1) { - throw new UnloggedFailure(1, "Invalid index specified. There is only 1 registered key."); + int index = Integer.parseInt(keyParameter); + if (index > registeredKeys.size()) { + if (keyParameters.size() == 1) { + throw new Failure(1, "Invalid index specified. There is only 1 registered key."); } - throw new UnloggedFailure(1, String.format("Invalid index specified. There are %d registered keys.", keys.size())); + throw new Failure(1, String.format("Invalid index specified. There are %d registered keys.", registeredKeys.size())); } - SshKey sshKey = currentKeys.get(index - 1); + SshKey sshKey = registeredKeys.get(index - 1); if (getKeyManager().removeKey(username, sshKey)) { stdout.println(String.format("Removed %s", sshKey.getFingerprint())); } else { - throw new UnloggedFailure(1, String.format("failed to remove #%s: %s", key, sshKey.getFingerprint())); + throw new Failure(1, String.format("failed to remove #%s: %s", keyParameter, sshKey.getFingerprint())); } - } catch (Exception e) { - // remove key by raw key data - SshKey sshKey = parseKey(key); - if (getKeyManager().removeKey(username, sshKey)) { - stdout.println(String.format("Removed %s", sshKey.getFingerprint())); - log.info("removed SSH public key {} from {}", sshKey.getFingerprint(), username); - } else { - log.warn("failed to remove SSH public key {} from {}", sshKey.getFingerprint(), username); - throw new UnloggedFailure(1, String.format("failed to remove %s", sshKey.getFingerprint())); - } + } catch (NumberFormatException e) { + log.warn("failed to remove SSH public key {} from {}", keyParameter, username); + throw new Failure(1, String.format("failed to remove key %s", keyParameter)); } } } @@ -254,7 +259,7 @@ private List<String> values = new ArrayList<String>(); @Override - public void run() throws UnloggedFailure { + public void run() throws Failure { final String username = getContext().getClient().getUsername(); IPublicKeyManager keyManager = getContext().getGitblit().getPublicKeyManager(); List<SshKey> keys = keyManager.getKeys(username); @@ -268,7 +273,44 @@ if (keyManager.addKey(username, key)) { stdout.println(String.format("Updated the comment for key #%d.", index)); } else { - throw new UnloggedFailure(1, String.format("Failed to update the comment for key #%d!", index)); + throw new Failure(1, String.format("Failed to update the comment for key #%d!", index)); + } + } + + } + + @CommandMetaData(name = "permission", description = "Set the permission of an SSH public key") + @UsageExample(syntax = "${cmd} 3 RW", description = "Set the permission for key #3 to PUSH (PW)") + public static class PermissionKey extends SshCommand { + + @Argument(index = 0, metaVar = "INDEX", usage = "the key index", required = true) + private int index; + + @Argument(index = 1, metaVar = "PERMISSION", usage = "the new permission", required = true) + private String value; + + @Override + public void run() throws Failure { + final String username = getContext().getClient().getUsername(); + IPublicKeyManager keyManager = getContext().getGitblit().getPublicKeyManager(); + List<SshKey> keys = keyManager.getKeys(username); + if (index > keys.size()) { + throw new UnloggedFailure(1, "Invalid key index!"); + } + + SshKey key = keys.get(index - 1); + AccessPermission permission = AccessPermission.fromCode(value); + if (permission.exceeds(AccessPermission.NONE)) { + try { + key.setPermission(permission); + } catch (IllegalArgumentException e) { + throw new Failure(1, e.getMessage()); + } + } + if (keyManager.addKey(username, key)) { + stdout.println(String.format("Updated the permission for key #%d.", index)); + } else { + throw new Failure(1, String.format("Failed to update the comment for key #%d!", index)); } } -- Gitblit v1.9.1