summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Wijenbergh <jeroenwijenbergh@protonmail.com>2022-03-21 14:58:58 +0100
committerjwijenbergh <jeroenwijenbergh@protonmail.com>2022-09-20 20:29:52 +0200
commitfc56f8770923ec1997444a8318a18be0a8397520 (patch)
tree3c6522b9b6e44ca2ad6cd94b074da78eed2c1028
parentd45f5df4dc5fa9ad8abdc47c940f6baf96fdbe45 (diff)
Wireguard: Add basic support
-rw-r--r--cli/go.sum22
-rw-r--r--cli/main.go13
-rw-r--r--go.mod2
-rw-r--r--go.sum30
-rw-r--r--src/api.go42
-rw-r--r--src/http.go98
-rw-r--r--src/oauth.go35
-rw-r--r--src/server.go6
-rw-r--r--src/state.go2
-rw-r--r--src/wireguard.go26
10 files changed, 210 insertions, 66 deletions
diff --git a/cli/go.sum b/cli/go.sum
index d152902..346f848 100644
--- a/cli/go.sum
+++ b/cli/go.sum
@@ -82,6 +82,8 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -99,12 +101,17 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b h1:ZGiXF8sz7PDk6RgkP+A/SFfUD0ZR/AgG6SpRNEDKZy8=
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b/go.mod h1:hQmNrgofl+IY/8L+n20H6E6PWBBTokdsv+q49j0QhsU=
+github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/mdlayher/genetlink v1.2.0/go.mod h1:ra5LDov2KrUCZJiAtEvXXZBxGMInICMXIwshlJ+qRxQ=
+github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
+github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
+github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -124,6 +131,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954 h1:BkypuErRT9A9I/iljuaG3/zdMjd/J6m8tKKJQtGfSdA=
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -183,6 +192,8 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
@@ -201,6 +212,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -229,7 +241,11 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc=
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -289,6 +305,12 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d/go.mod h1:5yyfuiqVIJ7t+3MqrpTQ+QqRkMWiESiyDvPNvKYCecg=
+golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
+golang.zx2c4.com/wireguard v0.0.0-20220202223031-3b95c81cc178 h1:Nrf94TOjrvW8nm6N3u2xtbnMZaZudNI9b8nIJH8p8qY=
+golang.zx2c4.com/wireguard v0.0.0-20220202223031-3b95c81cc178/go.mod h1:TjUWrnD5ATh7bFvmm/ALEJZQ4ivKbETb6pmyj1vUoNI=
+golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68 h1:9c4/JVIQUc2qCJEEIiGIs3HmmnFjhPj4qHW4+Uj+u3U=
+golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68/go.mod h1:8P32Ilp1kCpwB4ItaHyvSk4xAtnpQ+8gQVfg5WaO1TU=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
diff --git a/cli/main.go b/cli/main.go
index 0bee0c2..3c66804 100644
--- a/cli/main.go
+++ b/cli/main.go
@@ -50,9 +50,14 @@ func main() {
if oauthErr != nil {
log.Fatal(oauthErr)
}
- infoString, infoErr := state.APIAuthenticatedGet("/info")
- if infoErr != nil {
- log.Fatal(infoErr)
+ wireguardKey, wireguardErr := eduvpn.WireguardGenerateKey()
+
+ if wireguardErr != nil {
+ log.Fatal(wireguardErr)
+ }
+ configString, configErr := state.APIConnectWireguard(wireguardKey.PublicKey().String())
+ if configErr != nil {
+ log.Fatal(configErr)
}
- log.Println(infoString)
+ log.Println(eduvpn.WireguardConfigAddKey(configString, wireguardKey))
}
diff --git a/go.mod b/go.mod
index b21b580..2c73c42 100644
--- a/go.mod
+++ b/go.mod
@@ -5,5 +5,5 @@ go 1.15
require (
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954 // indirect
- golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect
+ golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68
)
diff --git a/go.sum b/go.sum
index a108da6..1a3d3c8 100644
--- a/go.sum
+++ b/go.sum
@@ -1,16 +1,46 @@
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b h1:ZGiXF8sz7PDk6RgkP+A/SFfUD0ZR/AgG6SpRNEDKZy8=
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b/go.mod h1:hQmNrgofl+IY/8L+n20H6E6PWBBTokdsv+q49j0QhsU=
+github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
+github.com/mdlayher/genetlink v1.2.0/go.mod h1:ra5LDov2KrUCZJiAtEvXXZBxGMInICMXIwshlJ+qRxQ=
+github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
+github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
+github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954 h1:BkypuErRT9A9I/iljuaG3/zdMjd/J6m8tKKJQtGfSdA=
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc=
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d/go.mod h1:5yyfuiqVIJ7t+3MqrpTQ+QqRkMWiESiyDvPNvKYCecg=
+golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
+golang.zx2c4.com/wireguard v0.0.0-20220202223031-3b95c81cc178 h1:Nrf94TOjrvW8nm6N3u2xtbnMZaZudNI9b8nIJH8p8qY=
+golang.zx2c4.com/wireguard v0.0.0-20220202223031-3b95c81cc178/go.mod h1:TjUWrnD5ATh7bFvmm/ALEJZQ4ivKbETb6pmyj1vUoNI=
+golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68 h1:9c4/JVIQUc2qCJEEIiGIs3HmmnFjhPj4qHW4+Uj+u3U=
+golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220208144051-fde48d68ee68/go.mod h1:8P32Ilp1kCpwB4ItaHyvSk4xAtnpQ+8gQVfg5WaO1TU=
diff --git a/src/api.go b/src/api.go
index d485728..dae9457 100644
--- a/src/api.go
+++ b/src/api.go
@@ -1,23 +1,57 @@
package eduvpn
import (
+ "fmt"
"net/http"
+ "net/url"
)
-func (eduvpn *VPNState) APIAuthenticatedGet(endpoint string) (string, error) {
+// Authenticated wrappers on top of HTTP
+func (eduvpn *VPNState) apiAuthenticatedWithOpts(method string, endpoint string, opts *HTTPOptionalParams) ([]byte, error) {
+ // Ensure optional is not nil as we will fill it with headers
+ if opts == nil {
+ opts = &HTTPOptionalParams{}
+ }
url := eduvpn.Server.Endpoints.API.V3.API + endpoint
// Ensure we have non-expired tokens
oauthErr := eduvpn.EnsureTokensOAuth()
if oauthErr != nil {
- return "", oauthErr
+ return nil, oauthErr
}
- headers := &http.Header{"Authorization": {"Bearer " + eduvpn.Server.OAuth.Token.Access}}
- body, bodyErr := HTTPGetWithOptionalParams(url, &HTTPOptionalParams{Headers: headers})
+ headerKey := "Authorization"
+ headerValue := fmt.Sprintf("Bearer %s", eduvpn.Server.OAuth.Token.Access)
+ if opts.Headers != nil {
+ opts.Headers.Add(headerKey, headerValue)
+ } else {
+ opts.Headers = &http.Header{headerKey: {headerValue}}
+ }
+ body, bodyErr := HTTPMethodWithOpts(method, url, opts)
+ if bodyErr != nil {
+ return nil, bodyErr
+ }
+ return body, nil
+}
+
+func (eduvpn *VPNState) APIConnectWireguard(pubkey string) (string, error) {
+ headers := &http.Header{
+ "content-type": {"application/x-www-form-urlencoded"},
+ "accept": {"application/x-wireguard-profile"},
+ }
+
+ urlForm := url.Values{
+ "profile_id": {"default"},
+ "public_key": {pubkey},
+ }
+ body, bodyErr := eduvpn.apiAuthenticatedWithOpts(http.MethodPost, "/connect", &HTTPOptionalParams{Headers: headers, Body: urlForm})
if bodyErr != nil {
return "", bodyErr
}
return string(body), nil
}
+
+func (eduvpn *VPNState) APIInfo() ([]byte, error) {
+ return eduvpn.apiAuthenticatedWithOpts(http.MethodGet, "/info", nil)
+}
diff --git a/src/http.go b/src/http.go
index 1374eed..5366c7e 100644
--- a/src/http.go
+++ b/src/http.go
@@ -2,6 +2,7 @@ package eduvpn
import (
"fmt"
+ "io"
"io/ioutil"
"net/http"
"net/url"
@@ -54,15 +55,16 @@ func (e *HTTPRequestCreateError) Error() string {
return fmt.Sprintf("failed to create HTTP request with url %s and error %v", e.URL, e.Err)
}
-type HTTPOptionalParams struct {
- Headers *http.Header
-}
+type URLParameters map[string]string
-func HTTPGet(url string) ([]byte, error) {
- return HTTPGetWithOptionalParams(url, nil)
+type HTTPOptionalParams struct {
+ Headers *http.Header
+ URLParameters *URLParameters
+ Body url.Values
}
-func HTTPConstructURL(baseURL string, parameters map[string]string) (string, error) {
+// Construct an URL including on parameters
+func HTTPConstructURL(baseURL string, parameters URLParameters) (string, error) {
url, err := url.Parse(baseURL)
if err != nil {
@@ -78,59 +80,89 @@ func HTTPConstructURL(baseURL string, parameters map[string]string) (string, err
return url.String(), nil
}
+// Convenience functions
+func HTTPGet(url string) ([]byte, error) {
+ return HTTPMethodWithOpts(http.MethodGet, url, nil)
+}
-func HTTPGetWithOptionalParams(url string, opts *HTTPOptionalParams) ([]byte, error) {
- client := &http.Client{}
- req, reqErr := http.NewRequest(http.MethodGet, url, nil)
- if reqErr != nil {
- return nil, &HTTPRequestCreateError{URL: url, Err: reqErr}
+func HTTPPost(url string, body url.Values) ([]byte, error) {
+ return HTTPMethodWithOpts(http.MethodGet, url, &HTTPOptionalParams{Body: body})
+}
+
+func HTTPGetWithOpts(url string, opts *HTTPOptionalParams) ([]byte, error) {
+ return HTTPMethodWithOpts(http.MethodGet, url, opts)
+}
+
+func HTTPPostWithOpts(url string, opts *HTTPOptionalParams) ([]byte, error) {
+ return HTTPMethodWithOpts(http.MethodPost, url, opts)
+}
+
+func httpOptionalURL(url string, opts *HTTPOptionalParams) (string, error) {
+ if opts != nil && opts.URLParameters != nil {
+ url, urlErr := HTTPConstructURL(url, *opts.URLParameters)
+
+ if urlErr != nil {
+ return url, &HTTPRequestCreateError{URL: url, Err: urlErr}
+ }
+ return url, nil
}
- if opts != nil && opts.Headers != nil {
+ return url, nil
+}
+
+func httpOptionalHeaders(req *http.Request, opts *HTTPOptionalParams) {
+ // Add headers
+ if opts != nil && opts.Headers != nil && req != nil {
for k, v := range *opts.Headers {
req.Header.Add(k, v[0])
}
}
- resp, respErr := client.Do(req)
- if respErr != nil {
- return nil, &HTTPResourceError{URL: url, Err: respErr}
- }
- defer resp.Body.Close()
+}
- body, readErr := ioutil.ReadAll(resp.Body)
- if readErr != nil {
- return nil, &HTTPReadError{URL: url, Err: readErr}
+func httpOptionalBodyReader(opts *HTTPOptionalParams) io.Reader {
+ if opts != nil && opts.Body != nil {
+ return strings.NewReader(opts.Body.Encode())
}
-
- return body, nil
+ return nil
}
-func HTTPPost(url string, body url.Values) ([]byte, error) {
- return HTTPPostWithOptionalParams(url, body, nil)
-}
+func HTTPMethodWithOpts(method string, url string, opts *HTTPOptionalParams) ([]byte, error) {
-func HTTPPostWithOptionalParams(url string, data url.Values, opts *HTTPOptionalParams) ([]byte, error) {
+ // Make sure the url contains all the parameters
+ // This can return an error,
+ // it already has the right error so so we don't wrap it further
+ url, urlErr := httpOptionalURL(url, opts)
+ if urlErr != nil {
+ return nil, urlErr
+ }
+
+ // Create a client
client := &http.Client{}
- req, reqErr := http.NewRequest(http.MethodPost, url, strings.NewReader(data.Encode()))
+
+ // Create request object with the body reader generated from the optional arguments
+ req, reqErr := http.NewRequest(method, url, httpOptionalBodyReader(opts))
if reqErr != nil {
return nil, &HTTPRequestCreateError{URL: url, Err: reqErr}
}
- if opts != nil && opts.Headers != nil {
- for k, v := range *opts.Headers {
- req.Header.Add(k, v[0])
- }
- }
- resp, respErr := client.Do(req)
+ // Make sure the headers contain all the parameters
+ httpOptionalHeaders(req, opts)
+
+ // Do request
+ resp, respErr := client.Do(req)
if respErr != nil {
return nil, &HTTPResourceError{URL: url, Err: respErr}
}
+
+ // Request successful, make sure body is closed at the end
defer resp.Body.Close()
+ // Return a string
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
return nil, &HTTPReadError{URL: url, Err: readErr}
}
+ // Return the body in bytes and signal that there was no error
return body, nil
}
diff --git a/src/oauth.go b/src/oauth.go
index bbe34af..063034b 100644
--- a/src/oauth.go
+++ b/src/oauth.go
@@ -54,8 +54,8 @@ func genVerifier() (string, error) {
}
type OAuth struct {
- Session *OAuthExchangeSession
- Token *OAuthToken
+ Session *OAuthExchangeSession
+ Token *OAuthToken
TokenURL string
}
@@ -65,13 +65,13 @@ type OAuthExchangeSession struct {
CallbackError error
// filled in in initialize
- ClientID string
- State string
- Verifier string
+ ClientID string
+ State string
+ Verifier string
// filled in when constructing the callback
- Context context.Context
- Server *http.Server
+ Context context.Context
+ Server *http.Server
}
func generateTimeSeconds() int64 {
@@ -81,10 +81,10 @@ func generateTimeSeconds() int64 {
// Struct that defines the json format for /.well-known/vpn-user-portal"
type OAuthToken struct {
- Access string `json:"access_token"`
- Refresh string `json:"refresh_token"`
- Type string `json:"token_type"`
- Expires int64 `json:"expires_in"`
+ Access string `json:"access_token"`
+ Refresh string `json:"refresh_token"`
+ Type string `json:"token_type"`
+ Expires int64 `json:"expires_in"`
ExpiredTimestamp int64
}
@@ -121,9 +121,9 @@ func (oauth *OAuth) getTokensWithAuthCode(authCode string) error {
}
headers := &http.Header{
"content-type": {"application/x-www-form-urlencoded"}}
- opts := &HTTPOptionalParams{Headers: headers}
+ opts := &HTTPOptionalParams{Headers: headers, Body: data}
current_time := generateTimeSeconds()
- body, bodyErr := HTTPPostWithOptionalParams(reqURL, data, opts)
+ body, bodyErr := HTTPPostWithOpts(reqURL, opts)
if bodyErr != nil {
return bodyErr
}
@@ -158,9 +158,9 @@ func (oauth *OAuth) getTokensWithRefresh() error {
}
headers := &http.Header{
"content-type": {"application/x-www-form-urlencoded"}}
- opts := &HTTPOptionalParams{Headers: headers}
+ opts := &HTTPOptionalParams{Headers: headers, Body: data}
current_time := generateTimeSeconds()
- body, bodyErr := HTTPPostWithOptionalParams(reqURL, data, opts)
+ body, bodyErr := HTTPPostWithOpts(reqURL, opts)
if bodyErr != nil {
return bodyErr
}
@@ -260,7 +260,6 @@ func (eduvpn *VPNState) InitializeOAuth() (string, error) {
return authURL, nil
}
-
// Error definitions
func (eduvpn *VPNState) FinishOAuth() error {
oauth := eduvpn.Server.OAuth
@@ -277,12 +276,11 @@ func (eduvpn *VPNState) EnsureTokensOAuth() error {
}
if oauth.isTokensExpired() {
- return oauth.getTokensWithRefresh();
+ return oauth.getTokensWithRefresh()
}
return nil
}
-
type OAuthGenStateUnableError struct {
Err error
}
@@ -299,7 +297,6 @@ func (e *OAuthGenVerifierUnableError) Error() string {
return fmt.Sprintf("failed generating verifier with error %v", e.Err)
}
-
type OAuthFailedCallbackError struct {
Addr string
Err error
diff --git a/src/server.go b/src/server.go
index bf1fb3d..6f809c6 100644
--- a/src/server.go
+++ b/src/server.go
@@ -5,9 +5,9 @@ import (
)
type Server struct {
- BaseURL string
+ BaseURL string
Endpoints *ServerEndpoints
- OAuth *OAuth
+ OAuth *OAuth
}
type ServerEndpointList struct {
@@ -25,7 +25,6 @@ type ServerEndpoints struct {
V string `json:"v"`
}
-
func (server *Server) Initialize(url string) error {
server.BaseURL = url
endpointsErr := server.GetEndpoints()
@@ -35,7 +34,6 @@ func (server *Server) Initialize(url string) error {
return nil
}
-
func (server *Server) GetEndpoints() error {
url := server.BaseURL + "/.well-known/vpn-user-portal"
body, bodyErr := HTTPGet(url)
diff --git a/src/state.go b/src/state.go
index 272bbc6..582dd5a 100644
--- a/src/state.go
+++ b/src/state.go
@@ -2,7 +2,7 @@ package eduvpn
type VPNState struct {
// Info passed by the client
- Name string
+ Name string
// The chosen server
Server *Server
diff --git a/src/wireguard.go b/src/wireguard.go
new file mode 100644
index 0000000..9441c51
--- /dev/null
+++ b/src/wireguard.go
@@ -0,0 +1,26 @@
+package eduvpn
+
+import (
+ "fmt"
+ "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+ "regexp"
+)
+
+func WireguardGenerateKey() (wgtypes.Key, error) {
+ key, error := wgtypes.GeneratePrivateKey()
+ return key, error
+}
+
+// FIXME: Instead of doing a regex replace, decide if we should use a parser
+func WireguardConfigAddKey(config string, key wgtypes.Key) string {
+ interface_section := "[Interface]"
+ interface_section_escaped := regexp.QuoteMeta(interface_section)
+
+ // (?m) enables multi line mode
+ // ^ match from beginning of line
+ // $ match till end of line
+ // So it matches [Interface] section exactly
+ interface_re := regexp.MustCompile(fmt.Sprintf("(?m)^%s$", interface_section_escaped))
+ to_replace := fmt.Sprintf("%s\nPrivateKey = %s", interface_section, key.String())
+ return interface_re.ReplaceAllString(config, to_replace)
+}