123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /*
- * 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.Serializable;
- import java.security.PublicKey;
- import java.util.Arrays;
- import java.util.List;
-
- import org.apache.commons.codec.binary.Base64;
- import org.apache.sshd.common.SshException;
- import org.apache.sshd.common.util.Buffer;
- import org.eclipse.jgit.lib.Constants;
-
- import com.gitblit.Constants.AccessPermission;
- import com.gitblit.utils.StringUtils;
-
- /**
- * Class that encapsulates a public SSH key and it's metadata.
- *
- * @author James Moger
- *
- */
- public class SshKey implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- private String rawData;
-
- private PublicKey publicKey;
-
- private String comment;
-
- private String fingerprint;
-
- private String toString;
-
- private AccessPermission permission;
-
- public SshKey(String data) {
- this.rawData = data;
- this.permission = AccessPermission.PUSH;
- }
-
- public SshKey(PublicKey key) {
- this.publicKey = key;
- this.comment = "";
- this.permission = AccessPermission.PUSH;
- }
-
- public PublicKey getPublicKey() {
- if (publicKey == null && rawData != null) {
- // instantiate the public key from the raw key data
- final String[] parts = rawData.split(" ", 3);
- if (comment == null && parts.length == 3) {
- comment = parts[2];
- }
- final byte[] bin = Base64.decodeBase64(Constants.encodeASCII(parts[1]));
- try {
- publicKey = new Buffer(bin).getRawPublicKey();
- } catch (SshException e) {
- throw new RuntimeException(e);
- }
- }
- return publicKey;
- }
-
- public String getAlgorithm() {
- return getPublicKey().getAlgorithm();
- }
-
- public String getComment() {
- if (comment == null && rawData != null) {
- // extract comment from the raw data
- final String[] parts = rawData.split(" ", 3);
- if (parts.length == 3) {
- comment = parts[2];
- }
- }
- return comment;
- }
-
- public void setComment(String comment) {
- this.comment = comment;
- if (rawData != null) {
- rawData = null;
- }
- }
-
- /**
- * Returns true if this key may be used to clone or fetch.
- *
- * @return true if this key can be used to clone or fetch
- */
- public boolean canClone() {
- return permission.atLeast(AccessPermission.CLONE);
- }
-
- /**
- * Returns true if this key may be used to push changes.
- *
- * @return true if this key can be used to push changes
- */
- public boolean canPush() {
- return permission.atLeast(AccessPermission.PUSH);
- }
-
- /**
- * Returns the access permission for the key.
- *
- * @return the access permission for the key
- */
- public AccessPermission getPermission() {
- return permission;
- }
-
- /**
- * Control the access permission assigned to this key.
- *
- * @param value
- */
- public void setPermission(AccessPermission value) throws IllegalArgumentException {
- List<AccessPermission> permitted = Arrays.asList(AccessPermission.SSHPERMISSIONS);
- if (!permitted.contains(value)) {
- throw new IllegalArgumentException("Illegal SSH public key permission specified: " + value);
- }
- this.permission = value;
- }
-
- public String getRawData() {
- if (rawData == null && publicKey != null) {
- // build the raw data manually from the public key
- Buffer buf = new Buffer();
-
- // 1: identify the algorithm
- buf.putRawPublicKey(publicKey);
- String alg = buf.getString();
-
- // 2: encode the key
- buf.clear();
- buf.putPublicKey(publicKey);
- String b64 = Base64.encodeBase64String(buf.getBytes());
-
- String c = getComment();
- rawData = alg + " " + b64 + (StringUtils.isEmpty(c) ? "" : (" " + c));
- }
- return rawData;
- }
-
- public String getFingerprint() {
- if (fingerprint == null) {
- StringBuilder sb = new StringBuilder();
- // append the key hash as colon-separated pairs
- String hash;
- if (rawData != null) {
- final String[] parts = rawData.split(" ", 3);
- final byte [] bin = Base64.decodeBase64(Constants.encodeASCII(parts[1]));
- hash = StringUtils.getMD5(bin);
- } else {
- // TODO calculate the correct hash from a PublicKey instance
- hash = StringUtils.getMD5(getPublicKey().getEncoded());
- }
- for (int i = 0; i < hash.length(); i += 2) {
- sb.append(hash.charAt(i)).append(hash.charAt(i + 1)).append(':');
- }
- sb.setLength(sb.length() - 1);
- fingerprint = sb.toString();
- }
- return fingerprint;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof PublicKey) {
- return getPublicKey().equals(o);
- } else if (o instanceof SshKey) {
- return getPublicKey().equals(((SshKey) o).getPublicKey());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return getPublicKey().hashCode();
- }
-
- @Override
- public String toString() {
- if (toString == null) {
- StringBuilder sb = new StringBuilder();
- // TODO append the keysize
- int keySize = 0;
- if (keySize > 0) {
- sb.append(keySize).append(' ');
- }
- // append fingerprint
- sb.append(' ');
- sb.append(getFingerprint());
- // append the comment
- String c = getComment();
- if (!StringUtils.isEmpty(c)) {
- sb.append(' ');
- sb.append(c);
- }
- // append algorithm
- String alg = getAlgorithm();
- if (!StringUtils.isEmpty(alg)) {
- sb.append(" (").append(alg).append(")");
- }
- toString = sb.toString();
- }
- return toString;
- }
- }
|