This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

5pkgs/ssh-tpm-agent: rebase client-pid patch onto upstream 0.9.0

+63 -54
+62 -54
5pkgs/ssh-tpm-agent/client-pid.patch
··· 1 1 diff --git a/agent/agent.go b/agent/agent.go 2 - index 76a2610..e643575 100644 2 + index ac39d24..b1e399b 100644 3 3 --- a/agent/agent.go 4 4 +++ b/agent/agent.go 5 - @@ -25,6 +25,7 @@ import ( 5 + @@ -26,6 +26,7 @@ import ( 6 6 "github.com/google/go-tpm/tpm2/transport" 7 7 "golang.org/x/crypto/ssh" 8 8 "golang.org/x/crypto/ssh/agent" ··· 10 10 "golang.org/x/text/cases" 11 11 "golang.org/x/text/language" 12 12 ) 13 - @@ -37,17 +38,18 @@ var ( 13 + @@ -39,17 +40,18 @@ var ( 14 14 var SSH_TPM_AGENT_ADD = "tpm-add-key" 15 15 16 16 type Agent struct { ··· 19 19 - op func() ([]byte, error) 20 20 - pin func(key.SSHTPMKeys) ([]byte, error) 21 21 - listener *net.UnixListener 22 - - quit chan interface{} 22 + - quit chan any 23 23 - wg sync.WaitGroup 24 24 - keyring func() *keyring.ThreadKeyring 25 25 - keys []key.SSHTPMKeys ··· 30 30 + op func() ([]byte, error) 31 31 + pin func(key.SSHTPMKeys, int) ([]byte, error) 32 32 + listener *net.UnixListener 33 - + quit chan interface{} 33 + + quit chan any 34 34 + wg sync.WaitGroup 35 35 + keyring func() *keyring.ThreadKeyring 36 36 + keys []key.SSHTPMKeys ··· 40 40 } 41 41 42 42 var _ agent.ExtendedAgent = &Agent{} 43 - @@ -118,8 +120,8 @@ func (a *Agent) signers() ([]ssh.Signer, error) { 43 + @@ -120,8 +122,8 @@ func (a *Agent) signers() ([]ssh.Signer, error) { 44 44 s, err := ssh.NewSignerFromSigner(k.Signer( 45 45 a.keyring(), a.op, a.tpm, 46 46 func(_ *keyfile.TPMKey) ([]byte, error) { ··· 51 51 }), 52 52 ) 53 53 if err != nil { 54 - @@ -225,6 +227,21 @@ func (a *Agent) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) { 54 + @@ -260,7 +262,7 @@ func (a *Agent) confirmKeyUse(wantKey []byte, peer string) error { 55 + if peer != "" { 56 + prompt += "\nRequested by " + peer 57 + } 58 + - ok, err := askpass.AskPermission(prompt) 59 + + ok, err := askpass.AskPermission(prompt, a.clientPID) 60 + if err != nil { 61 + slog.Info("askpass confirmation failed", slog.String("error", err.Error())) 62 + return ErrUserDeniedConfirm 63 + @@ -289,6 +291,18 @@ func (c *connAgent) SignWithFlags(key ssh.PublicKey, data []byte, flags agent.Si 55 64 } 56 65 57 - func (a *Agent) serveConn(c net.Conn) { 66 + func (a *Agent) serveConn(c *net.UnixConn) { 58 67 + // Extract peer credentials to get the client PID 59 - + if uc, ok := c.(*net.UnixConn); ok { 60 - + rawConn, err := uc.SyscallConn() 61 - + if err == nil { 62 - + rawConn.Control(func(fd uintptr) { 63 - + if cred, err := unix.GetsockoptUcred(int(fd), unix.SOL_SOCKET, unix.SO_PEERCRED); err == nil { 64 - + a.mu.Lock() 65 - + a.clientPID = int(cred.Pid) 66 - + a.mu.Unlock() 67 - + slog.Debug("client connected", slog.Int("pid", int(cred.Pid))) 68 - + } 69 - + }) 70 - + } 68 + + if rc, err := c.SyscallConn(); err == nil { 69 + + rc.Control(func(fd uintptr) { 70 + + if cred, err := unix.GetsockoptUcred(int(fd), unix.SOL_SOCKET, unix.SO_PEERCRED); err == nil { 71 + + a.mu.Lock() 72 + + a.clientPID = int(cred.Pid) 73 + + a.mu.Unlock() 74 + + slog.Debug("client connected", slog.Int("pid", int(cred.Pid))) 75 + + } 76 + + }) 71 77 + } 72 78 + 73 - if err := agent.ServeAgent(a, c); err != io.EOF { 79 + ca := &connAgent{Agent: a, peer: peerChain(c)} 80 + if err := agent.ServeAgent(ca, c); err != io.EOF { 74 81 slog.Info("Agent client connection ended unsuccessfully", slog.String("error", err.Error())) 75 - } 76 - @@ -461,7 +478,7 @@ func LoadKeys(keyDir string) ([]key.SSHTPMKeys, error) { 82 + @@ -524,7 +538,7 @@ func LoadKeys(keyDir string) ([]key.SSHTPMKeys, error) { 77 83 return keys, err 78 84 } 79 85 ··· 96 102 defer ag.Stop() 97 103 98 104 diff --git a/askpass/askpass.go b/askpass/askpass.go 99 - index 8ef6370..0653165 100644 105 + index 9830586..aefe469 100644 100 106 --- a/askpass/askpass.go 101 107 +++ b/askpass/askpass.go 102 108 @@ -8,6 +8,7 @@ import ( ··· 134 140 var askpass string 135 141 var err error 136 142 if s, ok := os.LookupEnv("SSH_ASKPASS"); ok { 137 - @@ -147,6 +148,11 @@ func SshAskPass(prompt, hint string) ([]byte, error) { 138 - if hint != "" { 139 - os.Setenv("SSH_ASKPASS_PROMPT", hint) 143 + @@ -144,7 +145,15 @@ func SshAskPass(prompt, hint string) ([]byte, error) { 144 + } 140 145 } 141 - + 142 - + if clientPID > 0 { 146 + 147 + + if clientPID > 0 && os.Getenv("SSH_CLIENT_PID") == "" { 148 + + // Pass the requesting client's PID to pinentry so it can cache per-client. 143 149 + os.Setenv("SSH_CLIENT_PID", strconv.Itoa(clientPID)) 144 150 + } 145 151 + 146 - out, err := exec.Command(askpass, prompt).Output() 147 - switch hint { 148 - case "confirm": 149 - @@ -169,8 +175,8 @@ func SshAskPass(prompt, hint string) ([]byte, error) { 152 + cmd := exec.Command(askpass, prompt) 153 + + if clientPID > 0 { 154 + + cmd.Env = append(os.Environ(), "SSH_CLIENT_PID="+strconv.Itoa(clientPID)) 155 + + } 156 + if hint != "" { 157 + // Set SSH_ASKPASS_PROMPT only on the subprocess. os.Setenv() would 158 + // leak into subsequent passphrase prompts from the same agent 159 + @@ -173,8 +182,8 @@ func SshAskPass(prompt, hint string) ([]byte, error) { 150 160 151 - // AskPremission runs SSH_ASKPASS in with SSH_ASKPASS_PROMPT=confirm set as env 152 - // it will expect exit code 0 or !0 and return 'yes' and 'no' respectively. 153 - -func AskPermission() (bool, error) { 154 - - a, err := ReadPassphrase("Confirm touch", RP_USE_ASKPASS|RP_ASK_PERMISSION) 155 - +func AskPermission(clientPID int) (bool, error) { 156 - + a, err := ReadPassphrase("Confirm touch", RP_USE_ASKPASS|RP_ASK_PERMISSION, clientPID) 161 + // AskPermission runs SSH_ASKPASS with SSH_ASKPASS_PROMPT=confirm set as env. 162 + // It will expect exit code 0 or !0 and return true and false respectively. 163 + -func AskPermission(prompt string) (bool, error) { 164 + - a, err := ReadPassphrase(prompt, RP_USE_ASKPASS|RP_ASK_PERMISSION) 165 + +func AskPermission(prompt string, clientPID int) (bool, error) { 166 + + a, err := ReadPassphrase(prompt, RP_USE_ASKPASS|RP_ASK_PERMISSION, clientPID) 157 167 if err != nil { 158 168 return false, err 159 169 } 160 170 diff --git a/cmd/ssh-tpm-agent/main.go b/cmd/ssh-tpm-agent/main.go 161 - index 1b76351..797428c 100644 171 + index 7c6f397..8e19473 100644 162 172 --- a/cmd/ssh-tpm-agent/main.go 163 173 +++ b/cmd/ssh-tpm-agent/main.go 164 174 @@ -243,7 +243,7 @@ func main() { ··· 177 187 - func(key key.SSHTPMKeys) ([]byte, error) { 178 188 + func(key key.SSHTPMKeys, clientPID int) ([]byte, error) { 179 189 auth, err := agentkeyring.ReadKey(key.Fingerprint()) 180 - if err == nil { 181 - slog.Debug("providing cached userauth for key", slog.String("fp", key.Fingerprint())) 182 - @@ -261,8 +261,8 @@ func main() { 183 - return auth.Read(), nil 184 - } else if errors.Is(err, syscall.ENOKEY) || errors.Is(err, syscall.EACCES) { 190 + switch { 191 + case errors.Is(err, syscall.ENOENT): 192 + @@ -262,7 +262,7 @@ func main() { 193 + case errors.Is(err, syscall.ENOKEY) || errors.Is(err, syscall.EACCES): 185 194 keyInfo := fmt.Sprintf("Enter passphrase for (%s): ", key.GetDescription()) 186 - - // TODOt kjk: askpass should box the byte slice 195 + // TODO: askpass should box the byte slice 187 196 - userauth, err := askpass.ReadPassphrase(keyInfo, askpass.RP_USE_ASKPASS) 188 - + // TODO: askpass should box the byte slice 189 197 + userauth, err := askpass.ReadPassphrase(keyInfo, askpass.RP_USE_ASKPASS, clientPID) 190 198 fmt.Println(err) 191 199 if !noCache && err == nil { 192 200 slog.Debug("caching userauth for key in keyring", slog.String("fp", key.Fingerprint())) 193 201 diff --git a/cmd/ssh-tpm-agent/main_test.go b/cmd/ssh-tpm-agent/main_test.go 194 - index 051febf..d2ff3c4 100644 202 + index 8335058..89697f2 100644 195 203 --- a/cmd/ssh-tpm-agent/main_test.go 196 204 +++ b/cmd/ssh-tpm-agent/main_test.go 197 205 @@ -144,7 +144,7 @@ func runSSHAuth(t *testing.T, keytype tpm2.TPMAlgID, bits int, pin []byte, keyfn ··· 204 212 }, 205 213 ) 206 214 diff --git a/cmd/ssh-tpm-keygen/main.go b/cmd/ssh-tpm-keygen/main.go 207 - index f5d9421..12073b0 100644 215 + index 4002026..eae8d39 100644 208 216 --- a/cmd/ssh-tpm-keygen/main.go 209 217 +++ b/cmd/ssh-tpm-keygen/main.go 210 218 @@ -89,11 +89,11 @@ Example: ··· 239 247 if err != nil { 240 248 return err 241 249 } 242 - @@ -199,18 +199,18 @@ func doChangePin(tpm transport.TPMCloser, passphrase, keyPin, ownerPassword []by 250 + @@ -202,18 +202,18 @@ func doChangePin(tpm transport.TPMCloser, passphrase, keyPin, ownerPassword []by 243 251 } 244 252 245 253 if len(passphrase) == 0 { ··· 261 269 if err != nil { 262 270 return err 263 271 } 264 - @@ -256,7 +256,7 @@ func doWrapWith(supportedECCBitsizes []int, wrap, wrapWith string, keyParentHand 272 + @@ -260,7 +260,7 @@ func doWrapWith(supportedECCBitsizes []int, wrap, wrapWith string, keyParentHand 265 273 rawKey, err = ssh.ParseRawPrivateKey(pem) 266 274 if errors.As(err, &kerr) { 267 275 for { ··· 270 278 if err != nil { 271 279 log.Fatal(err) 272 280 } 273 - @@ -353,7 +353,7 @@ func supportedECCBitsizes(tpm transport.TPMCloser) []int { 281 + @@ -358,7 +358,7 @@ func supportedECCBitsizes(tpm transport.TPMCloser) []int { 274 282 func checkFile(f string) error { 275 283 if utils.FileExists(f) { 276 284 fmt.Printf("%s already exists.\n", f) ··· 279 287 if err != nil { 280 288 return err 281 289 } 282 - @@ -373,7 +373,7 @@ func doImportKey(tpm transport.TPMCloser, keyParentHandle tpm2.TPMHandle, ownerP 290 + @@ -378,7 +378,7 @@ func doImportKey(tpm transport.TPMCloser, keyParentHandle tpm2.TPMHandle, ownerP 283 291 rawKey, err = ssh.ParseRawPrivateKey(pem) 284 292 if errors.As(err, &kerr) { 285 293 for { ··· 288 296 if err != nil { 289 297 return nil, err 290 298 } 291 - @@ -665,7 +665,7 @@ func main() { 299 + @@ -670,7 +670,7 @@ func main() { 292 300 // Else create a normal key 293 301 fmt.Printf("Generating a sealed public/private %s key pair.\n", keyType) 294 302 if outputFile == "" {
+1
keys/ssh/ignavia.pub
··· 1 + ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKJgmNpAQtiGJNAJg4QbYydoVzeyRpw8UYQGdQNx85YZRwReJ/hnoT7nS2q51OVbtEO65GL4lOWuXs94uB1Amxc= lass@ignavia