-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
146 lines (123 loc) · 3.39 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
// 基于 TOTP 的 FRP 访问授权验证
package main
import (
"encoding/json"
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
var appName string
var buildRev string
var buildDate string
var buildVersion string
var entry = flag.String("e", "web", "工具启动入口")
var proxy = flag.String("p", "", "代理通道名")
var configFile = flag.String("c", "frp.otp.json", "OPT 配置文件")
var showVer = flag.Bool("v", false, "显示应用版本信息并退出")
var showHelp = flag.Bool("h", false, "显示应用帮助信息并退出")
// LoadJSON 从文件加载 JSON 到变量
func LoadJSON(file string, in interface{}) error {
var err error
var data []byte
if data, err = ioutil.ReadFile(file); nil == err {
err = json.Unmarshal(data, in)
}
return err
}
// SaveJSON 保存数据到 JSON 文件
func SaveJSON(file string, in interface{}) error {
var bj, _ = json.Marshal(in)
return ioutil.WriteFile(file, bj, 0644)
}
// IsFile returns true if given path is a file,
// or returns false when it's a directory or does not exist.
func IsFile(filePath string) bool {
f, e := os.Stat(filePath)
if e != nil {
return false
}
return !f.IsDir()
}
// runWeb 运行 WEB 服务器
func runWeb(cfg *Config) error {
var s, err = NewServer(cfg)
if nil == err {
err = s.Run()
}
return err
}
// genOtpKey 生成通道KEY
func genOtpKey(cfg *Config, proxy string) error {
if c, ok := cfg.Channel[proxy]; ok {
fmt.Println("正在生成通道 " + proxy + " 的 OTP KEY")
c.GenerateOTP(proxy, cfg.Domain)
} else {
if "" == proxy {
fmt.Println("请输入要生成 OTP KEY 的通道,当前可用通道列表:")
} else {
fmt.Println("输入的通道 " + proxy + " 不存在,当前可用通道列表:")
}
for k := range cfg.Channel {
fmt.Println(k)
}
}
return nil
}
func main() {
flag.Usage = func() {
fmt.Fprintln(os.Stderr, "使用说明: ", filepath.Base(os.Args[0]), " 参数选项")
fmt.Fprintln(os.Stderr, "欢迎使用 FRP 访问授权验证工具")
fmt.Fprintln(os.Stderr, "更多信息: http://github.com/csg800/frp-otp")
fmt.Fprintln(os.Stderr, "")
fmt.Fprintln(os.Stderr, "参数选项:")
flag.PrintDefaults()
if *showHelp {
fmt.Fprintln(os.Stderr, "")
fmt.Fprintln(os.Stderr, "启动入口:")
fmt.Fprintln(os.Stderr, " web 启用访问授权验证服务")
fmt.Fprintln(os.Stderr, " key 为通道生成访问授权KEY")
}
}
flag.Parse()
if *showVer {
fmt.Println(appName + " " + "Ver: " + buildVersion + " build: " + buildDate + " Rev:" + buildRev)
return
}
if *showHelp {
flag.Usage()
return
}
defer func() {
if err := recover(); nil != err {
fmt.Println("system error:", err)
}
}()
var err error
var cfg = new(Config)
if IsFile(*configFile) {
if err = LoadJSON(*configFile, cfg); nil == err {
if 0 == len(cfg.Channel) {
err = errors.New("配置文件中通道列表为空")
} else {
switch *entry {
case "web":
err = runWeb(cfg)
case "key":
err = genOtpKey(cfg, *proxy)
default:
flag.Usage()
}
}
} else {
err = errors.New("加载配置文件失败:" + err.Error())
}
} else {
err = errors.New("配置文件 " + *configFile + " 不存在")
}
if nil != err {
fmt.Println("错误:", err)
}
}