hvpn-node3/handlers.go

138 lines
4.0 KiB
Go
Raw Normal View History

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)
}