SSH client with identities support
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package main
  2. import (
  3. "os"
  4. "path"
  5. "regexp"
  6. "strings"
  7. )
  8. type Identity struct {
  9. Name string
  10. Path string
  11. }
  12. func newIdentity(config Config, name string) Identity {
  13. return Identity{
  14. Name: name,
  15. Path: "",
  16. }
  17. }
  18. var hostRegexps = map[string]*regexp.Regexp{
  19. "ssh": regexp.MustCompile("(?P<user>.*@)?(?P<host>.*)"),
  20. "scp": regexp.MustCompile("(?P<user>.*@)?(?P<host>.*):(?P<file>.*)"),
  21. }
  22. func extractHost(prog string, args []string) string {
  23. args = removeOptions(prog, args)
  24. switch prog {
  25. case "ssh":
  26. if len(args) == 0 {
  27. return ""
  28. }
  29. re := hostRegexps["ssh"]
  30. arg := args[0]
  31. p := matchParams(re, arg)
  32. return p["host"]
  33. case "scp":
  34. re := hostRegexps["scp"]
  35. for _, arg := range args {
  36. if p := matchParams(re, arg); p != nil {
  37. return p["host"]
  38. }
  39. }
  40. }
  41. return ""
  42. }
  43. func findIdentityName(config Config, prog string, args []string) string {
  44. name := os.Getenv("SSH_IDENTITY")
  45. if name != "" {
  46. return name
  47. }
  48. identities := config.Identities
  49. host := extractHost(prog, args)
  50. for _, identity := range identities {
  51. match := identity.Key.(string)
  52. name := identity.Value.(string)
  53. if strings.Contains(host, match) {
  54. return name
  55. }
  56. }
  57. return config.DefaultIdentity
  58. }
  59. func FindIdentity(config Config, prog string, args []string) Identity {
  60. name := findIdentityName(config, prog, args)
  61. path := path.Join(config.IdentitiesDir, name)
  62. return Identity{
  63. Name: name,
  64. Path: path,
  65. }
  66. }