Pass client SSH key fingerprint in upstream username
When using public key auth, include the client's key fingerprint in the upstream username with format: fp:FINGERPRINT.originaluser This allows upstream servers (like maldoror) to identify users by their original SSH key even when sshpiper uses its own key for upstream authentication.
This commit is contained in:
parent
17c0645dc6
commit
e6667a6b8c
1 changed files with 20 additions and 1 deletions
|
|
@ -2,10 +2,13 @@ package skel
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/patrickmn/go-cache"
|
||||
|
|
@ -253,7 +256,8 @@ func (p *SkelPlugin) PublicKeyCallback(conn libplugin.ConnMetadata, publicKey []
|
|||
return nil, err
|
||||
}
|
||||
|
||||
u, err := p.createUpstream(conn, to, nil)
|
||||
// Pass the client's public key so their fingerprint can be included in the upstream username
|
||||
u, err := p.createUpstreamWithClientKey(conn, to, nil, publicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -262,6 +266,10 @@ func (p *SkelPlugin) PublicKeyCallback(conn libplugin.ConnMetadata, publicKey []
|
|||
}
|
||||
|
||||
func (p *SkelPlugin) createUpstream(conn libplugin.ConnMetadata, to SkelPipeTo, originalPassword []byte) (*libplugin.Upstream, error) {
|
||||
return p.createUpstreamWithClientKey(conn, to, originalPassword, nil)
|
||||
}
|
||||
|
||||
func (p *SkelPlugin) createUpstreamWithClientKey(conn libplugin.ConnMetadata, to SkelPipeTo, originalPassword []byte, clientPublicKey []byte) (*libplugin.Upstream, error) {
|
||||
host, port, err := libplugin.SplitHostPortForSSH(to.Host(conn))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -272,6 +280,17 @@ func (p *SkelPlugin) createUpstream(conn libplugin.ConnMetadata, to SkelPipeTo,
|
|||
user = conn.User()
|
||||
}
|
||||
|
||||
// If client public key is provided, prepend fingerprint to username
|
||||
// Format: "SHA256:xxxxx.originaluser" - maldoror/upstream can parse this
|
||||
if clientPublicKey != nil {
|
||||
hash := sha256.Sum256(clientPublicKey)
|
||||
fingerprint := base64.RawStdEncoding.EncodeToString(hash[:])
|
||||
// Replace any dots in fingerprint with underscores to avoid parsing issues
|
||||
fingerprint = strings.ReplaceAll(fingerprint, ".", "_")
|
||||
user = "fp:" + fingerprint + "." + user
|
||||
log.Debugf("passing client fingerprint in username: %s", user)
|
||||
}
|
||||
|
||||
p.cache.SetDefault(conn.UniqueID(), to)
|
||||
|
||||
u := &libplugin.Upstream{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue