From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001 From: Paul Martin <paul@paulsputer.com> Date: Sat, 30 Apr 2016 04:19:14 -0400 Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates --- src/main/java/com/gitblit/transport/ssh/FileKeyManager.java | 85 ++++++++++++++++++++++++++---------------- 1 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java b/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java index ae0bc9c..1a2cd68 100644 --- a/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java +++ b/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java @@ -17,35 +17,33 @@ import java.io.File; import java.io.IOException; -import java.security.PublicKey; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.apache.commons.codec.binary.Base64; -import org.apache.sshd.common.util.Buffer; -import org.eclipse.jgit.lib.Constants; - +import com.gitblit.Constants.AccessPermission; import com.gitblit.Keys; import com.gitblit.manager.IRuntimeManager; import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.io.Files; +import com.google.inject.Inject; /** - * Manages SSH keys on the filesystem. + * Manages public keys on the filesystem. * * @author James Moger * */ -public class FileKeyManager extends IKeyManager { +public class FileKeyManager extends IPublicKeyManager { protected final IRuntimeManager runtimeManager; protected final Map<File, Long> lastModifieds; + @Inject public FileKeyManager(IRuntimeManager runtimeManager) { this.runtimeManager = runtimeManager; this.lastModifieds = new ConcurrentHashMap<File, Long>(); @@ -59,6 +57,7 @@ @Override public FileKeyManager start() { + log.info(toString()); return this; } @@ -91,15 +90,15 @@ } @Override - protected List<PublicKey> getKeysImpl(String username) { + protected List<SshKey> getKeysImpl(String username) { try { - log.info("loading keystore for {}", username); + log.info("loading ssh keystore for {}", username); File keystore = getKeystore(username); if (!keystore.exists()) { return null; } if (keystore.exists()) { - List<PublicKey> list = new ArrayList<PublicKey>(); + List<SshKey> list = new ArrayList<SshKey>(); for (String entry : Files.readLines(keystore, Charsets.ISO_8859_1)) { if (entry.trim().length() == 0) { // skip blanks @@ -109,9 +108,18 @@ // skip comments continue; } - final String[] parts = entry.split(" "); - final byte[] bin = Base64.decodeBase64(Constants.encodeASCII(parts[1])); - list.add(new Buffer(bin).getRawPublicKey()); + String [] parts = entry.split(" ", 2); + AccessPermission perm = AccessPermission.fromCode(parts[0]); + if (perm.equals(AccessPermission.NONE)) { + // ssh-rsa DATA COMMENT + SshKey key = new SshKey(entry); + list.add(key); + } else if (perm.exceeds(AccessPermission.NONE)) { + // PERMISSION ssh-rsa DATA COMMENT + SshKey key = new SshKey(parts[1]); + key.setPermission(perm); + list.add(key); + } } if (list.isEmpty()) { @@ -122,7 +130,7 @@ return list; } } catch (IOException e) { - throw new RuntimeException("Canot read ssh keys", e); + throw new RuntimeException("Cannot read ssh keys", e); } return null; } @@ -132,10 +140,9 @@ * by disregarding the comment/description field during key comparisons. */ @Override - public boolean addKey(String username, String data) { + public boolean addKey(String username, SshKey key) { try { - String newKey = stripCommentFromKey(data); - + boolean replaced = false; List<String> lines = new ArrayList<String>(); File keystore = getKeystore(username); if (keystore.exists()) { @@ -152,16 +159,22 @@ continue; } - // only add keys that do not match the new key - String oldKey = stripCommentFromKey(line); - if (!newKey.equals(oldKey)) { + SshKey oldKey = parseKey(line); + if (key.equals(oldKey)) { + // replace key + lines.add(key.getPermission() + " " + key.getRawData()); + replaced = true; + } else { + // retain key lines.add(entry); } } } - // add new key - lines.add(data); + if (!replaced) { + // new key, append + lines.add(key.getPermission() + " " + key.getRawData()); + } // write keystore String content = Joiner.on("\n").join(lines).trim().concat("\n"); @@ -176,13 +189,11 @@ } /** - * Removes a key from the keystore. + * Removes the specified key from the keystore. */ @Override - public boolean removeKey(String username, String data) { + public boolean removeKey(String username, SshKey key) { try { - String rmKey = stripCommentFromKey(data); - File keystore = getKeystore(username); if (keystore.exists()) { List<String> lines = new ArrayList<String>(); @@ -200,8 +211,8 @@ } // only include keys that are NOT rmKey - String oldKey = stripCommentFromKey(line); - if (!rmKey.equals(oldKey)) { + SshKey oldKey = parseKey(line); + if (!key.equals(oldKey)) { lines.add(entry); } } @@ -241,10 +252,18 @@ return keys; } - /* Strips the comment from the key data and eliminates whitespace diffs */ - protected String stripCommentFromKey(String data) { - String [] cols = data.split(" "); - String key = Joiner.on(" ").join(cols[0], cols[1]); - return key; + protected SshKey parseKey(String line) { + String [] parts = line.split(" ", 2); + AccessPermission perm = AccessPermission.fromCode(parts[0]); + if (perm.equals(AccessPermission.NONE)) { + // ssh-rsa DATA COMMENT + SshKey key = new SshKey(line); + return key; + } else { + // PERMISSION ssh-rsa DATA COMMENT + SshKey key = new SshKey(parts[1]); + key.setPermission(perm); + return key; + } } } -- Gitblit v1.9.1