Go1.5从文件读取密码,然后到远端下载文件的小实例.(通过sftp协议下载)
2015-09-11 11:40
447 查看
package main import ( "bufio" "fmt" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" "io" "log" "net" "os" "path/filepath" "regexp" "sftp" "strings" ) func main() { if len(os.Args) != 3 { fmt.Println("参数不正确:") fmt.Printf("上传文件:%s %s %s\n", os.Args[0], "/data/Test.txt", "127.0.0.1:/mnt/") fmt.Printf("下载文件:%s %s %s\n", os.Args[0], "127.0.0.1:/mnt/Test.txt", "/data/") os.Exit(1) } _, err := os.Stat(os.Args[1]) if err != nil { get() return } push() } func get() { localpath := strings.Replace(os.Args[2], `\`, `/`, 20) re, _ := regexp.Compile(`((([1-9]?|1\d)\d|2([0-4]\d|5[0-5]))\.){3}(([1-9]?|1\d)\d|2([0-4]\d|5[0-5]))`) if re.MatchString(localpath) { fmt.Println("检查文件源地址.") return } list := strings.Split(os.Args[1], ":") if len(list) != 2 { fmt.Println("检查文件源地址.") return } fmt.Println("文件下载.") Sftp(list[0], list[1], localpath, "get") } func push() { list := strings.Split(os.Args[2], ":") if len(list) != 2 { fmt.Println("检查文件源地址.") return } fmt.Println("文件推送.") localpath := strings.Replace(list[1], `\`, `/`, 20) Sftp(list[0], os.Args[1], localpath, "push") } func Sftp(ip, path, localpath, action string) { var auths []ssh.AuthMethod if aconn, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil { auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(aconn).Signers)) } auth_list := parse("passlist", ip) if len(auth_list) == 0 { log.Println("获取用户和密码失败.") os.Exit(-1) } auths = append(auths, ssh.Password(auth_list[2])) config := ssh.ClientConfig{ User: auth_list[1], Auth: auths, } addr := fmt.Sprintf("%s:%s", ip, auth_list[3]) conn, err := ssh.Dial("tcp", addr, &config) if err != nil { log.Fatalf("unable to connect to [%s]: %v", addr, err) } defer conn.Close() c, err := sftp.NewClient(conn, sftp.MaxPacket(6e9)) if err != nil { log.Fatalf("unable to start sftp subsytem: %v", err) } defer c.Close() switch action { case "get": fs, e := c.Open(path) if e != nil { log.Println(e) os.Exit(-1) } filename := filepath.Base(path) info, _ := fs.Stat() File, err := os.Create(fmt.Sprintf(`%s/%s`, strings.TrimRight(localpath, `/`), filename)) if err != nil { log.Println(err) os.Exit(-1) } log.Println("保存路径:", fmt.Sprintf(`%s/%s`, strings.TrimRight(localpath, `/`), filename)) defer File.Close() io.Copy(File, io.LimitReader(fs, info.Size())) case "push": filename := filepath.Base(path) fs, err := c.Create(fmt.Sprintf(`%s/%s`, strings.TrimRight(localpath, `/`), filename)) if err != nil { log.Println(err) os.Exit(-1) } defer fs.Close() log.Println("保存路径:", fmt.Sprintf(`%s/%s`, strings.TrimRight(localpath, `/`), filename)) File, err := os.Open(path) if err != nil { log.Println(err) os.Exit(-1) } defer File.Close() io.Copy(io.MultiWriter(fs), File) } } func parse(cfg, ip string) []string { File, err := os.Open(cfg) if err != nil { log.Println("打开配置文件失败.") os.Exit(-1) } defer File.Close() buf := bufio.NewReader(File) for { line, _, err := buf.ReadLine() if err != nil { if err == io.EOF { break } fmt.Println(err) break } if strings.Contains(string(line), ip) { return split(string(line)) } } return []string{} } func split(str string) []string { var l []string list := strings.Split(str, " ") for _, v := range list { if len(v) == 0 { continue } if strings.Contains(v, " ") { list := strings.Split(v, " ") for _, v := range list { if len(v) == 0 { continue } l = append(l, v) } continue } l = append(l, v) } return l }
相关文章推荐
- Go 语言 Channel 实现原理精要
- Patrol 7 架构下?的处理方法
- Go语言将支持Android
- 清除IE分级审查密码
- 华为路由器密码恢复
- 注册表导出管理员密码文件
- 路由器版本与密码恢复
- 密码知识教程一
- 密码破解全教程
- 通过批处理修改FTP账号和密码
- redis中修改配置文件中的端口号 密码方法
- C#判断密码强度的方法
- C#使用伪随机数实现加密用户密码的方法
- C#修改及重置电脑密码DirectoryEntry实现方法
- 深入密码加salt原理的分析
- C#动态创建Access数据库及密码的方法
- JQuery记住用户名密码实现下次自动登录功能
- 详解Redis使用认证密码登录
- php使用cookie实现记住用户名和密码实现代码
- 防止浏览器记住用户名及密码的简单实用方法