mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 01:15:41 +08:00
87 lines
1.8 KiB
Go
87 lines
1.8 KiB
Go
// protocol spec:
|
|
// https://trojan-gfw.github.io/trojan/protocol
|
|
|
|
package trojan
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"crypto/tls"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/nadoo/glider/proxy"
|
|
)
|
|
|
|
// Trojan is a base trojan struct.
|
|
type Trojan struct {
|
|
dialer proxy.Dialer
|
|
proxy proxy.Proxy
|
|
addr string
|
|
pass [56]byte
|
|
withTLS bool
|
|
tlsConfig *tls.Config
|
|
serverName string
|
|
skipVerify bool
|
|
certFile string
|
|
keyFile string
|
|
fallback string
|
|
}
|
|
|
|
// NewTrojan returns a trojan proxy.
|
|
func NewTrojan(s string, d proxy.Dialer, p proxy.Proxy) (*Trojan, error) {
|
|
u, err := url.Parse(s)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parse url err: %s", err)
|
|
}
|
|
|
|
query := u.Query()
|
|
t := &Trojan{
|
|
dialer: d,
|
|
proxy: p,
|
|
addr: u.Host,
|
|
withTLS: true,
|
|
skipVerify: query.Get("skipVerify") == "true",
|
|
serverName: query.Get("serverName"),
|
|
certFile: query.Get("cert"),
|
|
keyFile: query.Get("key"),
|
|
fallback: query.Get("fallback"),
|
|
}
|
|
|
|
if t.addr != "" {
|
|
if _, port, _ := net.SplitHostPort(t.addr); port == "" {
|
|
t.addr = net.JoinHostPort(t.addr, "443")
|
|
}
|
|
if t.serverName == "" {
|
|
t.serverName = t.addr[:strings.LastIndex(t.addr, ":")]
|
|
}
|
|
}
|
|
|
|
// pass
|
|
pass := u.User.Username()
|
|
if pass == "" {
|
|
return nil, errors.New("[trojan] password must be specified")
|
|
}
|
|
|
|
hash := sha256.New224()
|
|
hash.Write([]byte(pass))
|
|
hex.Encode(t.pass[:], hash.Sum(nil))
|
|
|
|
return t, nil
|
|
}
|
|
|
|
func init() {
|
|
proxy.AddUsage("trojan", `
|
|
Trojan client scheme:
|
|
trojan://pass@host:port[?serverName=SERVERNAME][&skipVerify=true][&cert=PATH]
|
|
trojanc://pass@host:port (cleartext, without TLS)
|
|
|
|
Trojan server scheme:
|
|
trojan://pass@host:port?cert=PATH&key=PATH[&fallback=127.0.0.1]
|
|
trojanc://pass@host:port[?fallback=127.0.0.1] (cleartext, without TLS)
|
|
`)
|
|
}
|