Package com.gitblit.transport.ssh

Source Code of com.gitblit.transport.ssh.SshKey

/*
* 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;
  }
}
TOP

Related Classes of com.gitblit.transport.ssh.SshKey

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.