package hvpnnode3 import ( "encoding/json" "fmt" "log/slog" "net" "net/http" "github.com/felixge/httpsnoop" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "gitea.hbanafa.com/HeshamTB/hvpn-node3/proto" ) func HandleGetPeer(wgLink *WGLink) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) slog.Info("GET Peer is not implemented") } } func HandleGetPeers(wgLink *WGLink) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { dev, err := wgLink.Device(wgLink.Name) if err != nil { w.WriteHeader(http.StatusInternalServerError) slog.Error(err.Error()) return } var peers []proto.Peer for _, peer := range dev.Peers { p := proto.Peer{ Address: peer.AllowedIPs[0].IP, PublicKey: peer.PublicKey.String(), PersistentKeepalive: peer.PersistentKeepaliveInterval, TX: peer.TransmitBytes, RX: peer.ReceiveBytes, } peers = append(peers, p) } err = json.NewEncoder(w).Encode(peers) if err != nil { w.WriteHeader(http.StatusInternalServerError) } return } } func HandlePostPeer(IPPool IPPool, wgLink *WGLink) http.HandlerFunc { return func(w http.ResponseWriter, r* http.Request) { peerRequest := proto.CreatePeerRequest{} err := json.NewDecoder(r.Body).Decode(&peerRequest) if err != nil { w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode( &proto.ErrJSONResponse{Message: "Invalid request JSON"}, ) return } // TODO: Check if pubkey is already registered dev, err := wgLink.Device(wgLink.Name) if err != nil { slog.Error(err.Error()) w.WriteHeader(http.StatusInternalServerError) return } for _, peer := range dev.Peers { if peer.PublicKey.String() == peerRequest.PublicKey { w.WriteHeader(http.StatusAccepted) return } } newIP, err := IPPool.Allocate() if err != nil { slog.Error(err.Error()) w.WriteHeader(http.StatusInternalServerError) return } // TODO: Add peer to wg device // TODO: Declare subnet mask for the service pkey, _ := wgtypes.GeneratePrivateKey() newPeer := wgtypes.PeerConfig{ PublicKey: pkey.PublicKey(), ReplaceAllowedIPs: true, AllowedIPs: []net.IPNet{ { IP: newIP, Mask: net.IPv4Mask(255, 255, 255, 255), }, }, } err = wgLink.ConfigureDevice( wgLink.Name, wgtypes.Config{ Peers: []wgtypes.PeerConfig{ newPeer, }, ReplacePeers: false, }, ) if err != nil { slog.Error(err.Error()) w.WriteHeader(http.StatusInternalServerError) return } json.NewEncoder(w).Encode( &proto.Peer{ Address: newIP, MTU: 1384, PublicKey: peerRequest.PublicKey, Endpoint: "vpn.test.com:8487", AllowedIPs: net.ParseIP("0.0.0.0/0"), PersistentKeepalive: 25, }, ) } } func HttpLogHandler2(h http.Handler) http.Handler { // https://blog.kowalczyk.info/article/e00e89c3841e4f8c8c769a78b8a90b47/logging-http-requests-in-go.html fn := func(w http.ResponseWriter, r* http.Request) { m := httpsnoop.CaptureMetrics(h, w, r) msg := fmt.Sprintf( "%s %s %s %d %s", r.RemoteAddr, r.Method, r.URL.String(),m.Code, m.Duration) slog.Info(msg) } return http.HandlerFunc(fn) }