From: Sergey Matveev Date: Wed, 20 May 2015 09:56:11 +0000 (+0300) Subject: Merge branch 'develop' X-Git-Tag: 3.3^0 X-Git-Url: http://www.git.cypherpunks.ru/?a=commitdiff_plain;h=46043bf7ed8bfbbb03e2c4821fc7eab09ddb32f7;hp=d3495f5a1d42c4cdeeeca5c8020efbd050fbde03;p=govpn.git Merge branch 'develop' Signed-off-by: Sergey Matveev --- diff --git a/BSDmakefile b/BSDmakefile new file mode 100644 index 0000000..b57abb4 --- /dev/null +++ b/BSDmakefile @@ -0,0 +1,4 @@ +GOPATH != pwd +VERSION != cat VERSION + +include common.mk diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..79efdfc --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,4 @@ +GOPATH = $(shell pwd) +VERSION = $(shell cat VERSION) + +include common.mk diff --git a/VERSION b/VERSION index a3ec5a4..eb39e53 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.2 +3.3 diff --git a/Makefile b/common.mk similarity index 97% rename from Makefile rename to common.mk index 0670d39..b2f01fe 100644 --- a/Makefile +++ b/common.mk @@ -1,6 +1,3 @@ -GOPATH != pwd -VERSION != cat VERSION - LDFLAGS = -X govpn.Version $(VERSION) PREFIX ?= /usr/local BINDIR = $(DESTDIR)$(PREFIX)/bin diff --git a/doc/download.texi b/doc/download.texi index 351c8db..4ce61a5 100644 --- a/doc/download.texi +++ b/doc/download.texi @@ -34,6 +34,10 @@ You can obtain releases source code prepared tarballs from the links below: @tab @url{download/govpn-3.1.tar.xz, link} @url{download/govpn-3.1.tar.xz.sig, sign} @tab @code{4034a67eb472e33760ed1783ca871f531c3a6be99b9bd6213f4f83c1147c344b} +@item 3.2 @tab 174 KiB +@tab @url{download/govpn-3.2.tar.xz, link} @url{download/govpn-3.2.tar.xz.sig, sign} +@tab @code{388e98d6adef5ebf3431b0d48419f54d2e2064c657de67e23c669ebcf273126d} + @end multitable Also you can try its @ref{Contacts, .onion} version. diff --git a/doc/example.texi b/doc/example.texi index c203d43..129b10f 100644 --- a/doc/example.texi +++ b/doc/example.texi @@ -14,26 +14,67 @@ GoVPN is 1500 - 20 - 8 = 1472. is 1432. @end itemize +@strong{Install}. At first you must @ref{Installation, install} this +software: download, check the signature, compile. + Do not forget about setting @code{GOMAXPROC} environment variable for -using more than one CPU. +using more than one CPU on both sides: + +@example +% export GOMAXPROC=4 +@end example + +@strong{Prepare the server}. Create the new client, named (for example) +"Alice": + +@example +% ./utils/newclient.sh Alice +Place verifier to peers/6d4ac605ce8dc37c2f0bf21cb542a713/verifier +@end example + +"6d4ac605ce8dc37c2f0bf21cb542a713" -- is the new client's identity. + +@strong{Prepare the client}. Generate @ref{Verifier} for known client +identity: + +@example +% ./utils/storekey.sh /tmp/passphrase +Enter passphrase:[my secure passphrase is here] +% govpn-verifier -id 6d4ac605ce8dc37c2f0bf21cb542a713 -key /tmp/passphrase +562556cc9ecf0019b4cf45bcdf42706944ae9b3ac7c73ad299d83f2d5a169c55 +% rm /tmp/passphrase +@end example -As a preparation you have to generate peer directory (register new -client) on the server side using @code{utils/newsclient.sh}, generate -@ref{Verifier} on client side and place it on the server. Assume that -you made those steps. +"562556cc9ecf0019b4cf45bcdf42706944ae9b3ac7c73ad299d83f2d5a169c55" -- +this is verifier itself. -GNU/Linux IPv4 client-server example: +@strong{Save verifier on server}. @example -server% echo "echo tap10" >> peers/CLIENTID/up.sh +% cat > peers/6d4ac605ce8dc37c2f0bf21cb542a713/verifier <> peers/6d4ac605ce8dc37c2f0bf21cb542a713/up.sh server% ip addr add 192.168.0.1/24 dev wlan0 server% tunctl -t tap10 server% ip link set mtu 1432 dev tap10 server% ip addr add 172.16.0.1/24 dev tap10 server% ip link set up dev tap10 -server% GOMAXPROC=4 govpn-server -bind 192.168.0.1:1194 -mtu 1472 @end example +@strong{Run server daemon itself}: + +@example +server% govpn-server -bind 192.168.0.1:1194 -mtu 1472 +@end example + +@strong{Prepare network on GNU/Linux IPv4 client}: + @example client% umask 066 client% utils/storekey.sh key.txt @@ -43,18 +84,23 @@ client% ip link set mtu 1432 dev tap10 client% ip addr add 172.16.0.2/24 dev tap10 client% ip link set up dev tap10 client% ip route add default via 172.16.0.1 -client% export GOMAXPROC=4 -client% while :; do - govpn-client -key key.txt -id CLIENTID -iface tap10 \ - -remote 192.168.0.1:1194 -mtu 1472 -done @end example -FreeBSD IPv6 client-server example: +@strong{Run client daemon itself}: +@example +client% govpn-client \ + -key key.txt \ + -id 6d4ac605ce8dc37c2f0bf21cb542a713 \ + -iface tap10 \ + -remote 192.168.0.1:1194 \ + -mtu 1472 +@end example + +@strong{FreeBSD IPv6 similar client-server example}: @example server% ifconfig em0 inet6 fe80::1/64 -server% GOMAXPROC=4 govpn-server -bind "fe80::1%em0" +server% govpn-server -bind "fe80::1%em0" @end example @example @@ -62,9 +108,9 @@ client% ifconfig me0 inet6 -ifdisabled auto_linklocal client% ifconfig tap10 client% ifconfig tap10 inet6 fc00::2/96 mtu 1412 up client% route -6 add default fc00::1 -client% export GOMAXPROC=4 -client% while :; do - govpn-client -key key.txt -id CLIENTID -iface tap10 \ - -remote [fe80::1%me0]:1194 -done +client% govpn-client \ + -key key.txt \ + -id 6d4ac605ce8dc37c2f0bf21cb542a713 \ + -iface tap10 \ + -remote "[fe80::1%me0]":1194 @end example diff --git a/doc/installation.texi b/doc/installation.texi index 6d3cf7d..3f5bde6 100644 --- a/doc/installation.texi +++ b/doc/installation.texi @@ -19,6 +19,15 @@ Get the tarball and run @code{make}. @emph{govpn-client}, @emph{govpn-server}, @emph{govpn-verifier} binaries will be build in the current directory. +As a prerequisite you must install Go compiler and possibly TUN/TAP +interfaces utilities: + +@itemize @bullet +@item @code{lang/go} port in FreeBSD. +@item @code{golang} and @code{uml-utilities} packages in GNU/Linux +distributions. +@end itemize + @example % wget http://www.cypherpunks.ru/govpn/download/govpn-2.3.tar.xz % wget http://www.cypherpunks.ru/govpn/download/govpn-2.3.tar.xz.sig diff --git a/doc/news.texi b/doc/news.texi index 8b68bf4..0ef3f82 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -2,6 +2,17 @@ @unnumbered News @table @strong + +@item Release 3.3 +@itemize @bullet +@item Compatibility with an old GNU Make 3.x. Previously only BSD Make +and GNU Make 4.x were supported. +@item /dev/urandom is used for correct client identity generation under +GNU/Linux systems. Previously /dev/random can produce less than required +128-bits of random. +@item Updated user manual examples. +@end itemize + @item Release 3.2 @itemize @bullet @item @@ -125,4 +136,5 @@ consuming and resource heavy computations. @itemize @bullet @item Initial stable release. @end itemize + @end table diff --git a/src/govpn/cmd/govpn-client/main.go b/src/govpn/cmd/govpn-client/main.go index f49edf8..a951160 100644 --- a/src/govpn/cmd/govpn-client/main.go +++ b/src/govpn/cmd/govpn-client/main.go @@ -53,9 +53,9 @@ func main() { govpn.MTU = *mtu - id := govpn.IDDecode(*IDRaw) - if id == nil { - panic("ID is not specified") + id, err := govpn.IDDecode(*IDRaw) + if err != nil { + log.Fatalln(err) } pub, priv := govpn.NewVerifier(id, govpn.StringFromFile(*keyPath)) @@ -72,15 +72,15 @@ func main() { bind, err := net.ResolveUDPAddr("udp", "0.0.0.0:0") if err != nil { - panic(err) + log.Fatalln("Can not resolve address:", err) } conn, err := net.ListenUDP("udp", bind) if err != nil { - panic(err) + log.Fatalln("Can not listen on UDP:", err) } remote, err := net.ResolveUDPAddr("udp", *remoteAddr) if err != nil { - panic(err) + log.Fatalln("Can not resolve remote address:", err) } tap, ethSink, ethReady, _, err := govpn.TAPListen( @@ -89,7 +89,7 @@ func main() { *cpr, ) if err != nil { - panic(err) + log.Fatalln("Can not listen on TAP interface:", err) } udpSink, udpBuf, udpReady := govpn.ConnListen(conn) @@ -107,7 +107,7 @@ func main() { log.Println("Stats are going to listen on", *stats) statsPort, err := net.Listen("tcp", *stats) if err != nil { - panic(err) + log.Fatalln("Can not listen on stats port:", err) } go govpn.StatsProcessor(statsPort, &knownPeers) } diff --git a/src/govpn/cmd/govpn-server/main.go b/src/govpn/cmd/govpn-server/main.go index 8aa26ec..0a127ef 100644 --- a/src/govpn/cmd/govpn-server/main.go +++ b/src/govpn/cmd/govpn-server/main.go @@ -85,11 +85,11 @@ func main() { bind, err := net.ResolveUDPAddr("udp", *bindAddr) if err != nil { - panic(err) + log.Fatalln("Can not resolve bind address:", err) } conn, err := net.ListenUDP("udp", bind) if err != nil { - panic(err) + log.Fatalln("Can listen on UDP:", err) } udpSink, udpBuf, udpReady := govpn.ConnListen(conn) @@ -123,7 +123,7 @@ func main() { log.Println("Stats are going to listen on", *stats) statsPort, err := net.Listen("tcp", *stats) if err != nil { - panic(err) + log.Fatalln("Can not listen on stats port:", err) } go govpn.StatsProcessor(statsPort, &knownPeers) } diff --git a/src/govpn/cmd/govpn-verifier/main.go b/src/govpn/cmd/govpn-verifier/main.go index e7cc0e9..ede2de7 100644 --- a/src/govpn/cmd/govpn-verifier/main.go +++ b/src/govpn/cmd/govpn-verifier/main.go @@ -24,6 +24,7 @@ import ( "encoding/hex" "flag" "fmt" + "log" "govpn" ) @@ -36,9 +37,9 @@ var ( func main() { flag.Parse() - id := govpn.IDDecode(*IDRaw) - if id == nil { - panic("ID is not specified") + id, err := govpn.IDDecode(*IDRaw) + if err != nil { + log.Fatalln(err) } pub, _ := govpn.NewVerifier(id, govpn.StringFromFile(*keyPath)) if *verifierPath == "" { @@ -46,7 +47,7 @@ func main() { } else { verifier, err := hex.DecodeString(govpn.StringFromFile(*verifierPath)) if err != nil { - panic("Can not decode verifier") + log.Fatalln("Can not decode verifier:", err) } fmt.Println(subtle.ConstantTimeCompare(verifier[:], pub[:]) == 1) } diff --git a/src/govpn/handshake.go b/src/govpn/handshake.go index 73cb4e2..7019148 100644 --- a/src/govpn/handshake.go +++ b/src/govpn/handshake.go @@ -108,7 +108,7 @@ func dhKeypairGen() (*[32]byte, *[32]byte) { reprFound := false for !reprFound { if _, err := rand.Read(priv[:]); err != nil { - panic("Can not read random for DH private key") + log.Fatalln("Error reading random for DH private key:", err) } reprFound = extra25519.ScalarBaseMult(pub, repr, priv) } @@ -158,15 +158,13 @@ func HandshakeStart(conf *PeerConf, conn *net.UDPConn, addr *net.UDPAddr) *Hands state.rNonce = new([RSize]byte) if _, err := rand.Read(state.rNonce[:]); err != nil { - panic("Can not read random for handshake nonce") + log.Fatalln("Error reading random for nonce:", err) } enc := make([]byte, 32) salsa20.XORKeyStream(enc, dhPubRepr[:], state.rNonce[:], state.dsaPubH) data := append(state.rNonce[:], enc...) data = append(data, idTag(state.Conf.Id, state.rNonce[:])...) - if _, err := conn.WriteTo(data, addr); err != nil { - panic(err) - } + conn.WriteToUDP(data, addr) return state } @@ -204,20 +202,17 @@ func (h *Handshake) Server(conn *net.UDPConn, data []byte) *Peer { // Generate R* and encrypt them h.rServer = new([RSize]byte) if _, err := rand.Read(h.rServer[:]); err != nil { - panic("Can not read random for handshake random key") + log.Fatalln("Error reading random for R:", err) } h.sServer = new([SSize]byte) if _, err := rand.Read(h.sServer[:]); err != nil { - panic("Can not read random for handshake shared key") + log.Fatalln("Error reading random for S:", err) } encRs := make([]byte, RSize+SSize) salsa20.XORKeyStream(encRs, append(h.rServer[:], h.sServer[:]...), h.rNonce[:], h.key) // Send that to client - if _, err := conn.WriteTo( - append(encPub, append(encRs, idTag(h.Conf.Id, encPub)...)...), h.addr); err != nil { - panic(err) - } + conn.WriteToUDP(append(encPub, append(encRs, idTag(h.Conf.Id, encPub)...)...), h.addr) h.LastPing = time.Now() } else // ENC(K, R+1, RS + RC + SC + Sign(DSAPriv, K)) + IDtag @@ -244,9 +239,7 @@ func (h *Handshake) Server(conn *net.UDPConn, data []byte) *Peer { // Send final answer to client enc := make([]byte, RSize) salsa20.XORKeyStream(enc, dec[RSize:RSize+RSize], h.rNonceNext(2), h.key) - if _, err := conn.WriteTo(append(enc, idTag(h.Conf.Id, enc)...), h.addr); err != nil { - panic(err) - } + conn.WriteToUDP(append(enc, idTag(h.Conf.Id, enc)...), h.addr) // Switch peer peer := newPeer( @@ -295,11 +288,11 @@ func (h *Handshake) Client(conn *net.UDPConn, data []byte) *Peer { // Generate R* and signature and encrypt them h.rClient = new([RSize]byte) if _, err := rand.Read(h.rClient[:]); err != nil { - panic("Can not read random for handshake random key") + log.Fatalln("Error reading random for R:", err) } h.sClient = new([SSize]byte) if _, err := rand.Read(h.sClient[:]); err != nil { - panic("Can not read random for handshake shared key") + log.Fatalln("Error reading random for S:", err) } sign := ed25519.Sign(h.Conf.DSAPriv, h.key[:]) @@ -310,9 +303,7 @@ func (h *Handshake) Client(conn *net.UDPConn, data []byte) *Peer { append(h.sClient[:], sign[:]...)...)...), h.rNonceNext(1), h.key) // Send that to server - if _, err := conn.WriteTo(append(enc, idTag(h.Conf.Id, enc)...), h.addr); err != nil { - panic(err) - } + conn.WriteToUDP(append(enc, idTag(h.Conf.Id, enc)...), h.addr) h.LastPing = time.Now() case 16: // ENC(K, R+2, RC) + IDtag if h.key == nil { diff --git a/src/govpn/identify.go b/src/govpn/identify.go index 4363c58..663afe7 100644 --- a/src/govpn/identify.go +++ b/src/govpn/identify.go @@ -21,6 +21,7 @@ package govpn import ( "crypto/subtle" "encoding/hex" + "errors" "io/ioutil" "log" "os" @@ -112,8 +113,8 @@ func (cc cipherCache) refresh() { } available := make(map[PeerId]bool) for _, peerId := range peerIds { - id := IDDecode(peerId) - if id == nil { + id, err := IDDecode(peerId) + if err != nil { continue } available[*id] = true @@ -220,17 +221,16 @@ func (id *PeerId) Conf() *PeerConf { // Decode identification string. // It must be 32 hexadecimal characters long. -// If it is not the valid one, then return nil. -func IDDecode(raw string) *PeerId { +func IDDecode(raw string) (*PeerId, error) { if len(raw) != IDSize*2 { - return nil + return nil, errors.New("ID must be 32 characters long") } idDecoded, err := hex.DecodeString(raw) if err != nil { - return nil + return nil, errors.New("ID must contain hexadecimal characters only") } idP := new([IDSize]byte) copy(idP[:], idDecoded) id := PeerId(*idP) - return &id + return &id, nil } diff --git a/src/govpn/tap.go b/src/govpn/tap.go index a807955..c5e3bf8 100644 --- a/src/govpn/tap.go +++ b/src/govpn/tap.go @@ -64,7 +64,7 @@ func NewTAP(ifaceName string) (*TAP, error) { <-tap.ready n, err = tap.dev.Read(tap.buf) if err != nil { - panic(err) + panic("Reading TAP:" + err.Error()) } tap.sink <- tap.buf[:n] } diff --git a/src/govpn/transport_test.go b/src/govpn/transport_test.go index 51f0e6e..d12c26d 100644 --- a/src/govpn/transport_test.go +++ b/src/govpn/transport_test.go @@ -20,7 +20,7 @@ var ( func init() { MTU = 1500 addr, _ = net.ResolveUDPAddr("udp", "[::1]:1") - peerId = IDDecode("ffffffffffffffffffffffffffffffff") + peerId, _ = IDDecode("ffffffffffffffffffffffffffffffff") conf = &PeerConf{ Id: peerId, Timeout: time.Second * time.Duration(TimeoutDefault), diff --git a/src/govpn/verifier.go b/src/govpn/verifier.go index f86cdcc..8954047 100644 --- a/src/govpn/verifier.go +++ b/src/govpn/verifier.go @@ -22,6 +22,7 @@ import ( "bytes" "crypto/sha512" "io/ioutil" + "log" "strings" "github.com/agl/ed25519" @@ -45,16 +46,16 @@ func NewVerifier(id *PeerId, password string) (*[ed25519.PublicKeySize]byte, *[e src := bytes.NewBuffer(r) pub, priv, err := ed25519.GenerateKey(src) if err != nil { - panic("Unable to generate Ed25519 keypair" + err.Error()) + log.Fatalln("Unable to generate Ed25519 keypair", err) } return pub, priv } -// Read string from the file, trimming newline. Panics if error occured. +// Read string from the file, trimming newline. func StringFromFile(path string) string { s, err := ioutil.ReadFile(path) if err != nil { - panic("Can not read string from" + path) + log.Fatalln("Can not read string from", path, err) } return strings.TrimRight(string(s), "\n") } diff --git a/utils/newclient.sh b/utils/newclient.sh index ab86a7f..e741130 100755 --- a/utils/newclient.sh +++ b/utils/newclient.sh @@ -3,7 +3,7 @@ getrand() { local size=$1 - dd if=/dev/random bs=$size count=1 2>/dev/null | hexdump -ve '"%02x"' + dd if=/dev/urandom bs=$size count=1 2>/dev/null | hexdump -ve '"%02x"' } [ -n "$1" ] || {