()
| 13 | ) |
| 14 | |
| 15 | func cmdConfigGen() { |
| 16 | fs := flag.NewFlagSet("config-gen", flag.ExitOnError) |
| 17 | host := fs.String("host", "", "host name") |
| 18 | user := fs.String("user", "", "user") |
| 19 | port := fs.String("port", "", "port") |
| 20 | write := fs.Bool("write", false, "write to ~/.ssh/config") |
| 21 | overwrite := fs.Bool("overwrite", false, "overwrite existing host block") |
| 22 | globalAlgos := fs.Bool("global-algos", false, "write RSA-SHA2 algorithms to Host *") |
| 23 | fs.Parse(os.Args[2:]) |
| 24 | if *host == "" { fatal(errors.New("host is required")) } |
| 25 | cfg, _ := config.Load() |
| 26 | block := buildHostBlock(*host, *user, *port, cfg.Socket) |
| 27 | if !*write { |
| 28 | fmt.Print(block) |
| 29 | return |
| 30 | } |
| 31 | home, _ := os.UserHomeDir() |
| 32 | p := filepath.Join(home, ".ssh", "config") |
| 33 | _ = os.MkdirAll(filepath.Dir(p), 0700) |
| 34 | bak := p + ".bak." + fmt.Sprintf("%d", time.Now().Unix()) |
| 35 | _ = copyFile(p, bak) |
| 36 | content := readFileOrEmpty(p) |
| 37 | var out string |
| 38 | if hasHostBlock(content, *host) { |
| 39 | if !*overwrite { out = content } else { out = replaceHostBlock(content, *host, block) } |
| 40 | } else { |
| 41 | out = strings.TrimRight(content, "\n") + "\n\n" + block |
| 42 | } |
| 43 | if *globalAlgos { |
| 44 | out = ensureGlobalAlgos(out) |
| 45 | } |
| 46 | if err := os.WriteFile(p, []byte(out), 0600); err != nil { fatal(err) } |
| 47 | fmt.Println("wrote", p) |
| 48 | } |
| 49 | |
| 50 | func buildHostBlock(host, user, port, sock string) string { |
| 51 | var b strings.Builder |
no test coverage detected