github.com/engineyard/workflow-cli@v2.21.6+incompatible/pkg/ssh/ssh.go (about)

     1  package ssh
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  )
     7  
     8  var (
     9  	pubKeyRegex = regexp.MustCompile("^(ssh-rsa|ssh-dss|ssh-ed25519|ecdsa-[^ ]+) ([^ ]+) ?(.*)")
    10  )
    11  
    12  // PubKeyInfo contains the information on an SSH public key
    13  type PubKeyInfo struct {
    14  	ID     string
    15  	Public string
    16  }
    17  
    18  // ErrInvalidPubKey is the error returned when an SSH public key is unrecognizable
    19  type ErrInvalidPubKey struct {
    20  	pubKey []byte
    21  }
    22  
    23  // Error is the error interface implementation
    24  func (e ErrInvalidPubKey) Error() string {
    25  	return fmt.Sprintf("invalid SSH public key %s", string(e.pubKey))
    26  }
    27  
    28  // ErrUnknownPubKeyID is the error returned when an SSH public key is not the expected format
    29  type ErrUnknownPubKeyID struct {
    30  	pubKey []byte
    31  }
    32  
    33  func (e ErrUnknownPubKeyID) Error() string {
    34  	return fmt.Sprintf("unknown SSH public key ID for %s", string(e.pubKey))
    35  }
    36  
    37  // ParsePubKey parses a byte slice representation of an SSH Public Key into an
    38  // SSHPubKeyInfo struct. If it cannot find the key ID from the pubKey byte slice itself,
    39  // it uses backupKeyID instead. Returns an appropriate error if parsing failed.
    40  func ParsePubKey(backupKeyID string, pubKey []byte) (*PubKeyInfo, error) {
    41  	if !pubKeyRegex.Match(pubKey) {
    42  		return nil, ErrInvalidPubKey{pubKey: pubKey}
    43  	}
    44  	capture := pubKeyRegex.FindStringSubmatch(string(pubKey))
    45  	if len(capture) < 4 || capture[3] == "" {
    46  		return &PubKeyInfo{ID: backupKeyID, Public: string(pubKey)}, nil
    47  	}
    48  	return &PubKeyInfo{ID: capture[3], Public: string(pubKey)}, nil
    49  }