func (l *sshListener) checkLogin(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { if bytes.Equal(key.Marshal(), l.id.PublicKey().Marshal()) && conn.User() == "termite" { return nil, nil } return nil, fmt.Errorf("denied") }
func CheckHostKey(HostKey string) (checkHostKey func(string, net.Addr, ssh.PublicKey) error) { var err error var public ssh.PublicKey var publices []ssh.PublicKey rest := []byte(HostKey) for { public, _, _, rest, err = ssh.ParseAuthorizedKey(rest) if err != nil { err = nil break } publices = append(publices, public) } checkHostKey = func(hostname string, remote net.Addr, key ssh.PublicKey) (err error) { hostkey := key.Marshal() log.Debug("remote hostkey: %s, type: %s", hostname, key.Type()) for _, public := range publices { if key.Type() == public.Type() && bytes.Compare(hostkey, public.Marshal()) == 0 { log.Info("host key match: %s", hostname) return nil } } log.Info("host key not match: %s", hostname) return ErrHostKey } return }
// Remove removes all identities with the given public key. func (r *keyring) Remove(key ssh.PublicKey) error { r.mu.Lock() defer r.mu.Unlock() if r.locked { return errLocked } want := key.Marshal() found := false for i := 0; i < len(r.keys); { if bytes.Equal(r.keys[i].signer.PublicKey().Marshal(), want) { found = true r.keys[i] = r.keys[len(r.keys)-1] r.keys = r.keys[len(r.keys)-1:] continue } else { i++ } } if !found { return errors.New("agent: key not found") } return nil }
func (k *storedHostKey) Check(addr string, remote net.Addr, key ssh.PublicKey) error { k.checkCount++ algo := key.Type() if k.keys == nil || bytes.Compare(key.Marshal(), k.keys[algo]) != 0 { return fmt.Errorf("host key mismatch. Got %q, want %q", key, k.keys[algo]) } return nil }
func SSHFingerprint(pubkey ssh.PublicKey) (fingerprint string) { binary := pubkey.Marshal() hash := md5.Sum(binary) // now add the colons fingerprint = fmt.Sprintf("%02x", (hash[0])) for i := 1; i < len(hash); i += 1 { fingerprint += ":" + fmt.Sprintf("%02x", (hash[i])) } return fingerprint }
func MarshalPublickKey(key ssh.PublicKey) string { pemBlock := &pem.Block{ Type: "", // The type, taken from the preamble (i.e. "RSA PRIVATE KEY"). // Headers: map[string]string{}, // Optional headers. Bytes: key.Marshal(), // The decoded bytes of the contents. Typically a DER encoded ASN.1 structure. } pemData := pem.EncodeToMemory(pemBlock) pemArray := strings.Split(string(pemData), "\n") return strings.Join(pemArray[1:len(pemArray)-2], "") }
// Sign returns a signature for the data. func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) { r.mu.Lock() defer r.mu.Unlock() if r.locked { return nil, errLocked } wanted := key.Marshal() for _, k := range r.keys { if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) { return k.signer.Sign(rand.Reader, data) } } return nil, errors.New("not found") }
func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate) { signer, err := ssh.NewSignerFromKey(key) if err != nil { t.Fatalf("NewSignerFromKey: %v", err) } // The agent should start up empty. if keys, err := agent.List(); err != nil { t.Fatalf("RequestIdentities: %v", err) } else if len(keys) > 0 { t.Fatalf("got %d keys, want 0: %v", len(keys), keys) } // Attempt to insert the key, with certificate if specified. var pubKey ssh.PublicKey if cert != nil { err = agent.Add(key, cert, "comment") pubKey = cert } else { err = agent.Add(key, nil, "comment") pubKey = signer.PublicKey() } if err != nil { t.Fatalf("insert: %v", err) } // Did the key get inserted successfully? if keys, err := agent.List(); err != nil { t.Fatalf("List: %v", err) } else if len(keys) != 1 { t.Fatalf("got %v, want 1 key", keys) } else if keys[0].Comment != "comment" { t.Fatalf("key comment: got %v, want %v", keys[0].Comment, "comment") } else if !bytes.Equal(keys[0].Blob, pubKey.Marshal()) { t.Fatalf("key mismatch") } // Can the agent make a valid signature? data := []byte("hello") sig, err := agent.Sign(pubKey, data) if err != nil { t.Fatalf("Sign: %v", err) } if err := pubKey.Verify(data, sig); err != nil { t.Fatalf("key signature Verify: %v", err) } }
func (srv *Server) findPubkey(key ssh.PublicKey) (username string, err error) { pubkey := base64.StdEncoding.EncodeToString(key.Marshal()) v := &url.Values{} v.Add("pubkey", pubkey) type PubkeyRslt struct { Name string Username string } rslt := &PubkeyRslt{} err = srv.GetJson("/l/pubk", false, v, rslt) if err != nil { return } username = rslt.Username return }
// Check is called during the handshake to check the server's public key for // unexpected changes. The key argument is in SSH wire format. It can be parsed // using ssh.ParsePublicKey. The address before DNS resolution is passed in the // addr argument, so the key can also be checked against the hostname. // It returns any error encountered while checking the public key. A nil return // value indicates that the key was either successfully verified (against an // existing known_hosts entry), or accepted by the user as a new key. func (kc *HostKeyChecker) Check(addr string, remote net.Addr, key gossh.PublicKey) error { remoteAddr, err := kc.addrToHostPort(remote.String()) if err != nil { return err } algoStr := algoString(key.Type()) keyFingerprintStr := md5String(md5.Sum(key.Marshal())) hostKeys, err := kc.m.GetHostKeys() _, ok := err.(*os.PathError) if err != nil && !ok { log.Errorf("Failed to read known_hosts file %v: %v", kc.m.String(), err) } mismatched := false for pattern, keys := range hostKeys { if !matchHost(remoteAddr, pattern) { continue } for _, hostKey := range keys { // Any matching key is considered a success, irrespective of previous failures if hostKey.Type() == key.Type() && bytes.Compare(hostKey.Marshal(), key.Marshal()) == 0 { return nil } // TODO(jonboulle): could be super friendly like the OpenSSH client // and note exactly which key failed (file + line number) mismatched = true } } if mismatched { fmt.Fprintf(os.Stderr, warningRemoteHostChanged, algoStr, keyFingerprintStr, kc.m.String()) return ErrUnmatchKey } // If we get this far, we haven't matched on any of the hostname patterns, // so it's considered a new key. Prompt the user to trust it. if !kc.trustHost(remoteAddr, algoStr, keyFingerprintStr) { fmt.Fprintln(os.Stderr, "Host key verification failed.") return ErrUntrustHost } if err := kc.m.PutHostKey(remoteAddr, key); err != nil { fmt.Fprintf(os.Stderr, "Failed to add the host to the list of known hosts (%v).\n", kc.m) return nil } fmt.Fprintf(os.Stderr, "Warning: Permanently added '%v' (%v) to the list of known hosts.\n", remoteAddr, algoStr) return nil }
// Sign has the agent sign the data using a protocol 2 key as defined // in [PROTOCOL.agent] section 2.6.2. func (c *client) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) { req := ssh.Marshal(signRequestAgentMsg{ KeyBlob: key.Marshal(), Data: data, }) msg, err := c.call(req) if err != nil { return nil, err } switch msg := msg.(type) { case *signResponseAgentMsg: var sig ssh.Signature if err := ssh.Unmarshal(msg.SigBlob, &sig); err != nil { return nil, err } return &sig, nil case *failureAgentMsg: return nil, errors.New("agent: failed to sign challenge") } panic("unreachable") }
func (d *sshDialer) checkHost(hostname string, remote net.Addr, key ssh.PublicKey) error { if bytes.Equal(key.Marshal(), d.identity.PublicKey().Marshal()) { return nil } return fmt.Errorf("key mismatch") }
func (k *storedHostKey) Add(key ssh.PublicKey) { if k.keys == nil { k.keys = map[string][]byte{} } k.keys[key.PublicKeyAlgo()] = ssh.MarshalPublicKey(key) }
func (c *client) Remove(key ssh.PublicKey) error { req := ssh.Marshal(&agentRemoveIdentityMsg{ KeyBlob: key.Marshal(), }) return c.simpleCall(req) }
func (k *storedHostKey) Add(key ssh.PublicKey) { if k.keys == nil { k.keys = map[string][]byte{} } k.keys[key.Type()] = key.Marshal() }
func SerializeKey(key ssh.PublicKey) string { return string(key.Marshal()) }