Пример #1
0
func TestHostSection(t *testing.T) {
	hostSection := `# Some example Host section
Host local # Local SSH
	OptionOne do anything here
	OptionTwo 12345 # There is also a comment
	OptionWithoutValue
	OptionsWithComment # Comment
`
	sections, err := sshconfig.Parse(reader(hostSection))
	if err != nil {
		t.Fatal(err)
	}

	if len(sections) != 1 {
		t.Error("Unexpected number of sections")
	}

	s0 := sections[0]
	if s0.Name != "local" {
		t.Error("Unexpected section name")
	}
	if s0.Values["OptionOne"] != "do anything here" {
		t.Error("Unexpected option value (composite string)")
	}
	if s0.Values["OptionTwo"] != "12345" {
		t.Error("Unexpected option value (numeric)")
	}
	if v, ok := s0.Values["OptionWithoutValue"]; !ok || v != "" {
		t.Error("Unexpected value for option without value, or not parsed")
	}
	if v, ok := s0.Values["OptionsWithComment"]; !ok || v != "" {
		t.Error("Unexpected value for option without value, or not parsed")
	}
}
Пример #2
0
func parseCmdLine() (key, username, addr string, interval time.Duration) {
	ok, arg, args := shift(os.Args)
	var argKey, argHost, argInt string
	for ok {
		ok, arg, args = shift(args)
		if !ok {
			break
		}
		if arg == "-h" || arg == "--help" || arg == "--version" {
			usage(0)
		}
		if arg == "-i" {
			ok, argKey, args = shift(args)
			if !ok {
				usage(1)
			}
		} else if len(argHost) == 0 {
			argHost = arg
		} else if len(argInt) == 0 {
			argInt = arg
		} else {
			usage(1)
		}
	}
	if len(argHost) == 0 || argHost[0] == '-' {
		usage(1)
	}

	// key
	usr, err := user.Current()
	if err != nil {
		log.Print(err)
		usage(1)
	}

	f, err := os.Open(filepath.Join(usr.HomeDir, ".ssh", "config"))
	// Got the config, scan for matching hosts
	if err == nil {
		sections, err := sshconfig.Parse(f)
		if err != nil {
			log.Printf("error parsing ssh config: %v", err)
		} else {
			for s := range sections {
				// Support multiple definitions per config entry
				hostnames := strings.Split(sections[s].Name, " ")
				for _, h := range hostnames {
					// Choose ssh config entry values if they exist
					if h == argHost {
						configHostname, ok := sections[s].Values["Hostname"]
						if ok {
							argHost = configHostname
						}
						configUser, ok := sections[s].Values["User"]
						if ok {
							username = configUser
						}
						configPort, ok := sections[s].Values["Port"]
						if ok {
							argHost = fmt.Sprintf("%v:%v", argHost, configPort)
						}
					}
				}
			}
		}
	}

	if len(argKey) == 0 {
		key = filepath.Join(usr.HomeDir, ".ssh", "id_rsa")
		if _, err := os.Stat(key); os.IsNotExist(err) {
			key = ""
		}
	} else {
		key = argKey
	}
	// username, addr
	if i := strings.Index(argHost, "@"); i != -1 {
		username = argHost[:i]
		if i+1 >= len(argHost) {
			usage(1)
		}
		addr = argHost[i+1:]
	} else {
		username = usr.Username
		addr = argHost
	}
	if i := strings.Index(addr, ":"); i == -1 {
		addr += ":22"
	}
	// interval
	if len(argInt) == 0 {
		interval = DEFAULT_REFRESH * time.Second
	} else {
		i, err := strconv.ParseUint(argInt, 10, 64)
		if err != nil {
			log.Print(err)
			usage(1)
		}
		interval = time.Duration(i) * time.Second
	}

	return
}