This repository has been archived by the owner on Aug 9, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
148 lines (124 loc) · 3.2 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"os/user"
"path/filepath"
"syscall"
"github.com/pkg/sftp" // SFTP connection
"github.com/satori/go.uuid" // UUID Generation
"github.com/shibukawa/configdir" // Configuration file
"gopkg.in/alecthomas/kingpin.v2" // CLI helper
"golang.org/x/crypto/ssh" // SSH Session
)
var (
Path = kingpin.Arg("path", "Path to file you want to share").Required().String()
configDirs = configdir.New("fmartingr", "goshare")
usr, _ = user.Current()
)
func PublicKeyFile(file string) ssh.AuthMethod {
// Check for ~ characters and replace accordingly
if file[:2] == "~/" {
dir := usr.HomeDir
file = filepath.Join(dir, file[2:])
}
buffer, err := ioutil.ReadFile(file)
if err != nil {
fmt.Println("Error reading SSH key")
os.Exit(1)
}
key, err := ssh.ParsePrivateKey(buffer)
if err != nil {
fmt.Println("Error parsing SSH key")
os.Exit(1)
}
return ssh.PublicKeys(key)
}
type SSHConfiguration struct {
User string
Host string
Key string
Port int
RemotePath string
}
type Configuration struct {
SSH SSHConfiguration
ShareUrl string
}
func getBaseConfiguration() Configuration {
// Creates the base configuration options
config := Configuration{}
config.ShareUrl = "http://share.example.com/%s"
config.SSH = SSHConfiguration{
Host: "share.example.com",
User: "share_user",
Key: "~/.ssh/id_rsa",
Port: 22,
RemotePath: "/var/www/",
}
return config
}
func main() {
kingpin.Parse()
// Configuration
config := getBaseConfiguration()
configDirs.LocalPath = filepath.Join(usr.HomeDir, ".config", "goshare")
folder := configDirs.QueryFolderContainsFile("config.json")
if folder != nil {
data, _ := folder.ReadFile("config.json")
json.Unmarshal(data, &config)
} else {
folders := configDirs.QueryFolders(configdir.Local)
jsonConfig, _ := json.Marshal(config)
folders[0].WriteFile("config.json", jsonConfig)
log.Fatal("Unable to read config file, created base configuration.")
}
// Check if path exists and if it isn't a directory
stat, err := os.Stat(*Path)
if os.IsNotExist(err) || stat.IsDir() {
log.Fatalf("%s not found or it isn't a file\n", *Path)
}
// Copy file to temp folder with new name
newFileName := fmt.Sprintf("%s%s",
uuid.NewV4().String(), filepath.Ext(*Path))
// Create ssh connection
sshConfig := &ssh.ClientConfig{
User: config.SSH.User,
Auth: []ssh.AuthMethod{
PublicKeyFile(config.SSH.Key),
},
}
connection, err := ssh.Dial("tcp",
fmt.Sprintf("%s:%d", config.SSH.Host, config.SSH.Port),
sshConfig)
if err != nil {
log.Fatal("Failed to stablish SSH connection")
}
defer connection.Close()
MaxPacketSize := 1<<15
client, err := sftp.NewClient(connection, sftp.MaxPacket(MaxPacketSize))
if err != nil {
log.Fatal("Unable to start SFTP connection")
}
defer client.Close()
destPath := fmt.Sprintf("%s/%s", config.SSH.RemotePath, newFileName)
w, err := client.OpenFile(destPath, syscall.O_CREAT | syscall.O_RDWR)
if err != nil {
log.Fatal(err)
}
defer w.Close()
srcFile, err := ioutil.ReadFile(*Path)
if err != nil {
log.Fatal(err)
}
_, err = w.Write(srcFile)
if err != nil {
log.Fatal(err)
}
// Show sharing URL
fmt.Printf(config.ShareUrl, newFileName)
os.Exit(0)
}