@@ -21,7 +21,9 @@ import (
21
21
)
22
22
23
23
const codeServerPath = "~/.cache/sshcode/sshcode-server"
24
- const sshControlPath = "~/.ssh/control-%h-%p-%r"
24
+ const sshDirectory = "~/.ssh"
25
+ const sshDirectoryUnsafeModeMask = 0022
26
+ const sshControlPath = sshDirectory + "/control-%h-%p-%r"
25
27
26
28
type options struct {
27
29
skipSync bool
@@ -34,8 +36,6 @@ type options struct {
34
36
}
35
37
36
38
func sshCode (host , dir string , o options ) error {
37
- flog .Info ("ensuring code-server is updated..." )
38
-
39
39
host , extraSSHFlags , err := parseHost (host )
40
40
if err != nil {
41
41
return xerrors .Errorf ("failed to parse host IP: %w" , err )
@@ -56,6 +56,28 @@ func sshCode(host, dir string, o options) error {
56
56
return xerrors .Errorf ("failed to find available remote port: %w" , err )
57
57
}
58
58
59
+ // Check the SSH directory's permissions and warn the user if it is not safe.
60
+ sshDirectoryMode , err := os .Lstat (expandPath (sshDirectory ))
61
+ if err != nil {
62
+ if ! o .noReuseConnection {
63
+ flog .Info ("failed to stat %v directory, disabling connection reuse feature: %v" , sshDirectory , err )
64
+ o .noReuseConnection = true
65
+ }
66
+ } else {
67
+ if ! sshDirectoryMode .IsDir () {
68
+ if ! o .noReuseConnection {
69
+ flog .Info ("%v is not a directory, disabling connection reuse feature" , sshDirectory )
70
+ o .noReuseConnection = true
71
+ } else {
72
+ flog .Info ("warning: %v is not a directory" , sshDirectory )
73
+ }
74
+ }
75
+ if sshDirectoryMode .Mode ().Perm ()& sshDirectoryUnsafeModeMask != 0 {
76
+ flog .Info ("warning: the %v directory has unsafe permissions, they should only be writable by " +
77
+ "the owner (and files inside should be set to 0600)" , sshDirectory )
78
+ }
79
+ }
80
+
59
81
// Start SSH master connection socket. This prevents multiple password prompts from appearing as authentication
60
82
// only happens on the initial connection.
61
83
if ! o .noReuseConnection {
@@ -100,6 +122,7 @@ func sshCode(host, dir string, o options) error {
100
122
}
101
123
}
102
124
125
+ flog .Info ("ensuring code-server is updated..." )
103
126
dlScript := downloadScript (codeServerPath )
104
127
105
128
// Downloads the latest code-server and allows it to be executed.
@@ -214,6 +237,23 @@ func sshCode(host, dir string, o options) error {
214
237
return nil
215
238
}
216
239
240
+ // expandPath returns an expanded version of path.
241
+ func expandPath (path string ) string {
242
+ path = filepath .Clean (os .ExpandEnv (path ))
243
+
244
+ // Replace tilde notation in path with the home directory.
245
+ homedir := os .Getenv ("HOME" )
246
+ if homedir != "" {
247
+ if path == "~" {
248
+ path = homedir
249
+ } else if strings .HasPrefix (path , "~/" ) {
250
+ path = filepath .Join (homedir , path [2 :])
251
+ }
252
+ }
253
+
254
+ return filepath .Clean (path )
255
+ }
256
+
217
257
func parseBindAddr (bindAddr string ) (string , error ) {
218
258
if bindAddr == "" {
219
259
bindAddr = ":"
0 commit comments