@@ -2,6 +2,7 @@ package ssh_agent
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"io"
7
8
"io/ioutil"
31
32
tmpSockPath string
32
33
)
33
34
35
+ var (
36
+ ErrSocketPathTooLong = errors .New ("system ssh-agent socket path length exceeds the limit" )
37
+ ErrSocketPathEmpty = errors .New ("system ssh-agent socket path is empty" )
38
+ )
39
+
34
40
func setupProcessSSHAgent (sshAuthSock string ) error {
35
41
SSHAuthSock = sshAuthSock
36
42
return os .Setenv (SSHAuthSockEnv , SSHAuthSock )
@@ -134,8 +140,15 @@ func Init(ctx context.Context, userKeys []string) error {
134
140
}
135
141
136
142
systemAgentSock := os .Getenv (SSHAuthSockEnv )
137
- systemAgentSockExists , _ := util .FileExists (systemAgentSock )
138
- if systemAgentSock != "" && systemAgentSockExists {
143
+ validSystemAgentSock , err := validateAgentSock (systemAgentSock )
144
+ if err != nil {
145
+ if errors .Is (err , ErrSocketPathEmpty ) {
146
+ logboek .Context (ctx ).Debug ().LogF ("System ssh agent not found\n " )
147
+ } else {
148
+ return err
149
+ }
150
+ }
151
+ if systemAgentSock != "" && validSystemAgentSock {
139
152
SSHAuthSock = systemAgentSock
140
153
logboek .Context (ctx ).Info ().LogF ("Using system ssh-agent: %s\n " , systemAgentSock )
141
154
return nil
@@ -198,18 +211,17 @@ func runSSHAgentWithKeys(ctx context.Context, keys []sshKey) (string, error) {
198
211
}
199
212
200
213
func runSSHAgent (ctx context.Context ) (string , error ) {
201
- var sockPath string
202
- // darwin does not support path more than 108 characters
203
- if runtime .GOOS == "darwin" {
204
- // TODO(iapershin): needs refactoring. since user can change tmpDir we want to prevent it from setting path more than 108 chars
205
- sockPath = filepath .Join (os .TempDir (), "werf" , "Listeners" , uuid .NewString ())
206
- } else {
207
- sockPath = filepath .Join (werf .GetTmpDir (), "werf-ssh-agent" , uuid .NewString ())
214
+ sockPath := filepath .Join (werf .GetTmpDir (), "werf-ssh-agent" , uuid .NewString ())
215
+ err := validateSockPathLength (sockPath )
216
+ if err != nil {
217
+ logboek .Context (ctx ).Warn ().LogF ("WARNING: unable to use unix sock path %s: %s\n " , sockPath , err )
218
+ sockPath = fallbackToDefaultUnix ()
219
+ logboek .Context (ctx ).Warn ().LogF ("WARNING: fallback to %s\n " , sockPath )
208
220
}
209
221
210
222
tmpSockPath = sockPath
211
223
212
- err : = os .MkdirAll (filepath .Dir (sockPath ), os .ModePerm )
224
+ err = os .MkdirAll (filepath .Dir (sockPath ), os .ModePerm )
213
225
if err != nil {
214
226
return "" , err
215
227
}
@@ -310,3 +322,53 @@ func parsePrivateSSHKey(cfg sshKeyConfig) (sshKey, error) {
310
322
311
323
return sshKey {Config : cfg , PrivateKey : privateKey }, nil
312
324
}
325
+
326
+ func validateAgentSock (sock string ) (bool , error ) {
327
+ if sock == "" {
328
+ return false , ErrSocketPathEmpty
329
+ }
330
+
331
+ err := validateSockPathLength (sock )
332
+ if err != nil {
333
+ return false , fmt .Errorf ("unable to use system ssh sock '%s': %w" , sock , err )
334
+ }
335
+
336
+ if runtime .GOOS != "windows" {
337
+ info , err := os .Stat (sock )
338
+ if err != nil {
339
+ return false , err
340
+ }
341
+
342
+ if info .Mode ()& os .ModeSocket == 0 {
343
+ return false , fmt .Errorf ("system ssh-agent socket `%s` is not a socket" , sock )
344
+ }
345
+ }
346
+ conn , err := net .Dial ("unix" , sock )
347
+ if err != nil {
348
+ return false , fmt .Errorf ("unable to connect to system ssh-agent socket %s: %w" , sock , err )
349
+ }
350
+ defer conn .Close ()
351
+
352
+ return true , nil
353
+ }
354
+
355
+ func getUnixSocketPathLimit () int {
356
+ switch runtime .GOOS {
357
+ case "darwin" , "freebsd" , "openbsd" , "netbsd" :
358
+ return 104
359
+ default :
360
+ return 108
361
+ }
362
+ }
363
+
364
+ func validateSockPathLength (sockPath string ) error {
365
+ if len (sockPath ) > getUnixSocketPathLimit () {
366
+ return ErrSocketPathTooLong
367
+ }
368
+ return nil
369
+ }
370
+
371
+ func fallbackToDefaultUnix () string {
372
+ // since user can change tmpDir we want to prevent it from setting path more than 104/108 chars
373
+ return filepath .Join (os .TempDir (), "werf-ssh-agent" , uuid .NewString ())
374
+ }
0 commit comments