X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fgovpn%2Fcmd%2Fgovpn-client%2Fmain.go;h=3e372d89029be19f49cab3a4ce81b90f0f713b92;hb=2f3299c343b4036718f254d9c23f147ba1bc0161;hp=b46a16eb93203cb93a7002d372b24b64de050602;hpb=a87ec543051d428aaa3888804d6c8451f6d537c9;p=govpn.git diff --git a/src/cypherpunks.ru/govpn/cmd/govpn-client/main.go b/src/cypherpunks.ru/govpn/cmd/govpn-client/main.go index b46a16e..3e372d8 100644 --- a/src/cypherpunks.ru/govpn/cmd/govpn-client/main.go +++ b/src/cypherpunks.ru/govpn/cmd/govpn-client/main.go @@ -21,133 +21,132 @@ package main import ( "flag" + "fmt" "log" - "net" "os" "os/signal" "time" "cypherpunks.ru/govpn" -) - -var ( - remoteAddr = flag.String("remote", "", "Remote server address") - proto = flag.String("proto", "udp", "Protocol to use: udp or tcp") - ifaceName = flag.String("iface", "tap0", "TAP network interface") - verifierRaw = flag.String("verifier", "", "Verifier") - keyPath = flag.String("key", "", "Path to passphrase file") - upPath = flag.String("up", "", "Path to up-script") - downPath = flag.String("down", "", "Path to down-script") - stats = flag.String("stats", "", "Enable stats retrieving on host:port") - proxyAddr = flag.String("proxy", "", "Use HTTP proxy on host:port") - proxyAuth = flag.String("proxy-auth", "", "user:password Basic proxy auth") - mtu = flag.Int("mtu", govpn.MTUDefault, "MTU of TAP interface") - timeoutP = flag.Int("timeout", 60, "Timeout seconds") - noisy = flag.Bool("noise", false, "Enable noise appending") - encless = flag.Bool("encless", false, "Encryptionless mode") - cpr = flag.Int("cpr", 0, "Enable constant KiB/sec out traffic rate") - egdPath = flag.String("egd", "", "Optional path to EGD socket") - - conf *govpn.PeerConf - tap *govpn.TAP - timeout int - firstUpCall bool = true - knownPeers govpn.KnownPeers - idsCache *govpn.CipherCache + "cypherpunks.ru/govpn/client" ) func main() { + var ( + remoteAddr = flag.String("remote", "", "Remote server address") + proto = flag.String("proto", "udp", "Protocol to use: udp or tcp") + ifaceName = flag.String("iface", "tap0", "TUN/TAP network interface") + verifierRaw = flag.String("verifier", "", "Verifier") + keyPath = flag.String("key", "", "Path to passphrase file") + upPath = flag.String("up", "", "Path to up-script") + downPath = flag.String("down", "", "Path to down-script") + stats = flag.String("stats", "", "Enable stats retrieving on host:port") + proxyAddr = flag.String("proxy", "", "Use HTTP proxy on host:port") + proxyAuth = flag.String("proxy-auth", "", "user:password Basic proxy auth") + mtu = flag.Int("mtu", govpn.MTUDefault, "MTU of TUN/TAP interface") + timeoutP = flag.Int("timeout", 60, "Timeout seconds") + timeSync = flag.Int("timesync", 0, "Time synchronization requirement") + noreconnect = flag.Bool("noreconnect", false, "Disable reconnection after timeout") + noisy = flag.Bool("noise", false, "Enable noise appending") + encless = flag.Bool("encless", false, "Encryptionless mode") + cpr = flag.Int("cpr", 0, "Enable constant KiB/sec out traffic rate") + egdPath = flag.String("egd", "", "Optional path to EGD socket") + syslog = flag.Bool("syslog", false, "Enable logging to syslog") + version = flag.Bool("version", false, "Print version information") + warranty = flag.Bool("warranty", false, "Print warranty information") + protocol client.Protocol + err error + ) + flag.Parse() - timeout = *timeoutP - var err error + if *warranty { + fmt.Println(govpn.Warranty) + return + } + if *version { + fmt.Println(govpn.VersionGet()) + return + } log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile) - if *mtu > govpn.MTUMax { - log.Fatalln("Maximum allowable MTU is", govpn.MTUMax) - } if *egdPath != "" { log.Println("Using", *egdPath, "EGD") govpn.EGDInit(*egdPath) } + switch *proto { + case "udp": + protocol = client.ProtocolUDP + case "tcp": + protocol = client.ProtocolTCP + default: + log.Fatalln("Unknown protocol specified") + } + + if *proxyAddr != "" && protocol == client.ProtocolUDP { + log.Fatalln("HTTP proxy is supported only in TCP mode") + } + + if *verifierRaw == "" { + log.Fatalln("-verifier is required") + } verifier, err := govpn.VerifierFromString(*verifierRaw) if err != nil { - log.Fatalln(err) + log.Fatalln("Invalid -verifier:", err) } key, err := govpn.KeyRead(*keyPath) if err != nil { - log.Fatalln("Unable to read the key", err) + log.Fatalln("Invalid -key:", err) } priv := verifier.PasswordApply(key) if *encless { - if *proto != "tcp" { + if protocol != client.ProtocolTCP { log.Fatalln("Currently encryptionless mode works only with TCP") } *noisy = true } - conf = &govpn.PeerConf{ - Id: verifier.Id, - Iface: *ifaceName, - MTU: *mtu, - Timeout: time.Second * time.Duration(timeout), - Noise: *noisy, - CPR: *cpr, - Encless: *encless, - Verifier: verifier, - DSAPriv: priv, + conf := client.Configuration{ + PrivateKey: priv, + Peer: &govpn.PeerConf{ + Id: verifier.Id, + Iface: *ifaceName, + MTU: *mtu, + Timeout: time.Second * time.Duration(*timeoutP), + TimeSync: *timeSync, + Noise: *noisy, + CPR: *cpr, + Encless: *encless, + Verifier: verifier, + DSAPriv: priv, + }, + Protocol: protocol, + InterfaceName: *ifaceName, + ProxyAddress: *proxyAddr, + ProxyAuthentication: *proxyAuth, + RemoteAddress: *remoteAddr, + UpPath: *upPath, + DownPath: *downPath, + StatsAddress: *stats, + NoReconnect: *noreconnect, + MTU: *mtu, } - idsCache = govpn.NewCipherCache([]govpn.PeerId{*verifier.Id}) - log.Println(govpn.VersionGet()) - - tap, err = govpn.TAPListen(*ifaceName, *mtu) - if err != nil { - log.Fatalln("Can not listen on TAP interface:", err) + if err = conf.Validate(); err != nil { + log.Fatalln("Invalid settings:", err) } - if *stats != "" { - log.Println("Stats are going to listen on", *stats) - statsPort, err := net.Listen("tcp", *stats) - if err != nil { - log.Fatalln("Can not listen on stats port:", err) - } - go govpn.StatsProcessor(statsPort, &knownPeers) + log.Println(govpn.VersionGet()) + + if *syslog { + govpn.SyslogEnable() } termSignal := make(chan os.Signal, 1) signal.Notify(termSignal, os.Interrupt, os.Kill) - -MainCycle: - for { - timeouted := make(chan struct{}) - rehandshaking := make(chan struct{}) - termination := make(chan struct{}) - if *proxyAddr != "" { - *proto = "tcp" - } - switch *proto { - case "udp": - go startUDP(timeouted, rehandshaking, termination) - case "tcp": - if *proxyAddr != "" { - go proxyTCP(timeouted, rehandshaking, termination) - } else { - go startTCP(timeouted, rehandshaking, termination) - } - default: - log.Fatalln("Unknown protocol specified") - } - select { - case <-termSignal: - log.Fatalln("Finishing") - termination <- struct{}{} - break MainCycle - case <-timeouted: - break MainCycle - case <-rehandshaking: - } - close(timeouted) - close(rehandshaking) - close(termination) + c := client.NewClient(conf, verifier, termSignal) + go c.MainCycle() + if err := <-c.Error; err != nil { + log.Fatalln(err) + } else { + log.Println("Closed VPN tunnel") } - govpn.ScriptCall(*downPath, *ifaceName) }