]> Cypherpunks.ru repositories - govpn.git/commitdiff
Merge branch 'develop' 3.3
authorSergey Matveev <stargrave@stargrave.org>
Wed, 20 May 2015 09:56:11 +0000 (12:56 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Wed, 20 May 2015 09:56:11 +0000 (12:56 +0300)
Signed-off-by: Sergey Matveev <stargrave@stargrave.org>
17 files changed:
BSDmakefile [new file with mode: 0644]
GNUmakefile [new file with mode: 0644]
VERSION
common.mk [moved from Makefile with 97% similarity]
doc/download.texi
doc/example.texi
doc/installation.texi
doc/news.texi
src/govpn/cmd/govpn-client/main.go
src/govpn/cmd/govpn-server/main.go
src/govpn/cmd/govpn-verifier/main.go
src/govpn/handshake.go
src/govpn/identify.go
src/govpn/tap.go
src/govpn/transport_test.go
src/govpn/verifier.go
utils/newclient.sh

diff --git a/BSDmakefile b/BSDmakefile
new file mode 100644 (file)
index 0000000..b57abb4
--- /dev/null
@@ -0,0 +1,4 @@
+GOPATH != pwd
+VERSION != cat VERSION
+
+include common.mk
diff --git a/GNUmakefile b/GNUmakefile
new file mode 100644 (file)
index 0000000..79efdfc
--- /dev/null
@@ -0,0 +1,4 @@
+GOPATH = $(shell pwd)
+VERSION = $(shell cat VERSION)
+
+include common.mk
diff --git a/VERSION b/VERSION
index a3ec5a4bd3d7209b4a687a77cad49b945339994b..eb39e5382f4f035e4d71c7f67712cdbfa6c0c335 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.2
+3.3
similarity index 97%
rename from Makefile
rename to common.mk
index 0670d39701bb789f6c17e76290f8fc10ef027f4b..b2f01fe169577de58d7bfeae0ce8ab87d68e3f24 100644 (file)
--- 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
index 351c8dbf0f13af969783c9588b303446d43a3e9f..4ce61a53934e3bdfbe620c603e6a80b7d4ccc440 100644 (file)
@@ -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.
index c203d4356add3b8730551bbd97685978eed59450..129b10f290e7abf3e055307d260054b7a8cc3b11 100644 (file)
@@ -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 <<EOF
+562556cc9ecf0019b4cf45bcdf42706944ae9b3ac7c73ad299d83f2d5a169c55
+EOF
+@end example
+
+@strong{Prepare network on GNU/Linux IPv4 server}:
+
+@example
+server% echo "echo tap10" >> 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
index 6d3cf7d8256749108ab9e615b231482811496021..3f5bde6eeefa6a0379be8b9d5d396c8c8c08191c 100644 (file)
@@ -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
index 8b68bf462af13c8693102ed3574d0d730b79b7d2..0ef3f82365c16d0475ad20abdc497f3ac134f64f 100644 (file)
@@ -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
index f49edf8de8c05be0a87c7633e18aaace92e5eeea..a951160a21d7ce737e01d53188b3fa4b70a272df 100644 (file)
@@ -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)
        }
index 8aa26ec83bdb8878766fd28efd96c06f6a6e9d98..0a127efa78104147f93b0a48e72853ba910ed21b 100644 (file)
@@ -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)
        }
index e7cc0e9ec4a3ecf1c211298480523ca523a314e5..ede2de7438a370c43f770120a818ed454a453b71 100644 (file)
@@ -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)
        }
index 73cb4e2d35f39c3256e81d278328d30e38ff6c3b..7019148e899949f754435bdbad61c2042963350c 100644 (file)
@@ -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 {
index 4363c58d39fd9bd001b8aaae73cab6c8e2b93e81..663afe73599bf14b8fc40acf7e2b738c9ae6d7e6 100644 (file)
@@ -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
 }
index a80795534a70adf431b183c5d339e2ca61c51706..c5e3bf835cfee5f993f4eeff946c035bd005617e 100644 (file)
@@ -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]
                }
index 51f0e6e322f17efa25edfabe9484c8a587b6e134..d12c26dacb68210e1f54ebf8d93ced4580d9eb3f 100644 (file)
@@ -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),
index f86cdcce1f1b73d5fbf25eb857aa1baf5c8f9586..895404792cfd9edcdff67e28f43528d724adb026 100644 (file)
@@ -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")
 }
index ab86a7fdb23dde0009948ccba3190ad063387927..e741130957a6f30d6c8956988bcd3c3b58e2f940 100755 (executable)
@@ -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" ] || {