diff options
author | James Moger <james.moger@gitblit.com> | 2014-03-08 22:09:18 -0500 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2014-04-10 18:58:08 -0400 |
commit | b5361179d924eab162e17d7923f60d91cffb2d08 (patch) | |
tree | 5d3483efc8b80a02084258f252ff323afb108346 /src/main/java/com/gitblit/transport/ssh/FileKeyManager.java | |
parent | 8b63e0aaf044b36627e9ce02a1d73618e50700e4 (diff) | |
download | gitblit-b5361179d924eab162e17d7923f60d91cffb2d08.tar.gz gitblit-b5361179d924eab162e17d7923f60d91cffb2d08.zip |
Extract key manager interface and implement a file-based key manager
Diffstat (limited to 'src/main/java/com/gitblit/transport/ssh/FileKeyManager.java')
-rw-r--r-- | src/main/java/com/gitblit/transport/ssh/FileKeyManager.java | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java b/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java new file mode 100644 index 00000000..87912cae --- /dev/null +++ b/src/main/java/com/gitblit/transport/ssh/FileKeyManager.java @@ -0,0 +1,154 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.gitblit.transport.ssh; + +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 org.apache.commons.codec.binary.Base64; +import org.apache.sshd.common.util.Buffer; +import org.eclipse.jgit.lib.Constants; + +import com.gitblit.Keys; +import com.gitblit.manager.IRuntimeManager; +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +/** + * Manages SSH keys on the filesystem. + * + * @author James Moger + * + */ +public class FileKeyManager implements IKeyManager { + + protected final IRuntimeManager runtimeManager; + + public FileKeyManager(IRuntimeManager runtimeManager) { + this.runtimeManager = runtimeManager; + } + + @Override + public String toString() { + File dir = runtimeManager.getFileOrFolder(Keys.git.sshKeysFolder, "${baseFolder}/ssh"); + return MessageFormat.format("{0} ({1})", getClass().getSimpleName(), dir); + } + + @Override + public FileKeyManager start() { + return this; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public FileKeyManager stop() { + return this; + } + + @Override + public List<PublicKey> getKeys(String username) { + try { + File keys = getKeystore(username); + if (!keys.exists()) { + return null; + } + if (keys.exists()) { + String str = Files.toString(keys, Charsets.ISO_8859_1); + String [] entries = str.split("\n"); + List<PublicKey> list = new ArrayList<PublicKey>(); + for (String entry : entries) { + if (entry.trim().length() == 0) { + // skip blanks + continue; + } + if (entry.charAt(0) == '#') { + // skip comments + continue; + } + final String[] parts = entry.split(" "); + final byte[] bin = Base64.decodeBase64(Constants.encodeASCII(parts[1])); + list.add(new Buffer(bin).getRawPublicKey()); + } + + if (list.isEmpty()) { + return null; + } + return list; + } + } catch (IOException e) { + throw new RuntimeException("Canot read ssh keys", e); + } + return null; + } + + @Override + public boolean addKey(String username, String data) { + try { + File keys = getKeystore(username); + Files.append(data + '\n', keys, Charsets.ISO_8859_1); + return true; + } catch (IOException e) { + throw new RuntimeException("Cannot add ssh key", e); + } + } + + @Override + public boolean removeKey(String username, String data) { + try { + File keystore = getKeystore(username); + if (keystore.exists()) { + String str = Files.toString(keystore, Charsets.ISO_8859_1); + List<String> keep = new ArrayList<String>(); + String [] entries = str.split("\n"); + for (String entry : entries) { + if (entry.trim().length() == 0) { + // keep blanks + keep.add(entry); + continue; + } + if (entry.charAt(0) == '#') { + // keep comments + keep.add(entry); + continue; + } + final String[] parts = entry.split(" "); + if (!parts[1].equals(data)) { + keep.add(entry); + } + } + return true; + } + } catch (IOException e) { + throw new RuntimeException("Cannot remove ssh key", e); + } + return false; + } + + protected File getKeystore(String username) { + File dir = runtimeManager.getFileOrFolder(Keys.git.sshKeysFolder, "${baseFolder}/ssh"); + dir.mkdirs(); + File keys = new File(dir, username + ".keys"); + return keys; + } +} |