Пример #1
0
// 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
}
Пример #2
0
// Generates a MD5 based fingerprint of a SSH key.
func pubKeyFingerprint(key ssh.PublicKey) (string, error) {
	h := md5.New()
	_, err := h.Write(key.Marshal())
	if err != nil {
		return "", err
	}
	fp := fmt.Sprintf("%x", h.Sum(nil))
	return fp, nil
}
Пример #3
0
// 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")
}
Пример #4
0
// 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")
}
Пример #5
0
func (c *client) Remove(key ssh.PublicKey) error {
	req := ssh.Marshal(&agentRemoveIdentityMsg{
		KeyBlob: key.Marshal(),
	})
	return c.simpleCall(req)
}
Пример #6
0
// Callback function responsible for authenticating the SSH client.
func keyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
	log.Printf("(keyAuth) >>  New client conn from '%s' authenticating with '%s'\n", conn.RemoteAddr(), key.Type())

	// Create a fingerprint of the external provided pub key.
	fpProvidedPubKey, err := pubKeyFingerprint(key)
	if err != nil {
		log.Printf("(keyAuth) >>  Error: Unable to create fingerprint for provided PubKey: %s\n", err.Error())
	}
	log.Printf("(keyAuth) >>  Fingerprint of provided PubKey    : %s\n", fpProvidedPubKey)

	// Get all the pub keys for a given user.
	authorizedPubKeys, err := getPubKeysForUser(conn.User())
	if err != nil {
		return nil, fmt.Errorf("(keyAuth) >>  No pub key for user '%s' found / user not allowed to connect.", conn.User())

	}

	// Check if the user is allowed to connect at all (meaning: the must be a subdirectory in the 'data' dir
	// matching the provided SSH username).
	var authSuccess bool = false
	for i, authPubKey := range authorizedPubKeys {

		fpAuthorizedPubKey, err := pubKeyFingerprint(authPubKey)
		if err != nil {
			log.Printf("(keyAuth) >>  Error: Unable to create fingerprint for authorized PubKey %d: %s\n", i, err.Error())
		}
		log.Printf("(keyAuth) >>  Fingerprint of authorized PubKey %d: %s\n", i, fpAuthorizedPubKey)

		// Check if username and Public Key combination is allowed to establish a connection.
		if theseTwoPublicKeysAreEqual(key, authPubKey) {
			authSuccess = true
			break

		}
	}
	if authSuccess {
		log.Printf("(keyAuth) >>  Correct username '%s' and public key provided.", conn.User())
		// Signaling success / authentication passed.
		return nil, nil
	}
	log.Printf("(keyAuth) >>  Wrong username '%s' and/or public key provided.", conn.User())
	return nil, fmt.Errorf("Wrong username and/or public key.")
}