This commit is contained in:
jdl
2024-12-12 21:11:17 +01:00
parent 03ff1aac80
commit fdf0066fc2
35 changed files with 1138 additions and 331 deletions

View File

@@ -144,7 +144,7 @@ func (a *API) Session_SignIn(s *Session, pwd string) error {
type PeerCreateArgs struct {
Name string
IP []byte
PublicIP []byte
Port uint16
Mediator bool
}
@@ -209,9 +209,10 @@ func (a *API) Peer_Create(creationCode string) (*m.PeerConfig, error) {
peer := &Peer{
PeerIP: peerIP,
Version: idgen.NextID(0),
APIKey: idgen.NewToken(),
Name: args.Name,
IP: args.IP,
PublicIP: args.PublicIP,
Port: args.Port,
Mediator: args.Mediator,
EncPubKey: encPubKey[:],
@@ -229,7 +230,7 @@ func (a *API) Peer_Create(creationCode string) (*m.PeerConfig, error) {
HubAddress: conf.HubAddress,
APIKey: peer.APIKey,
Network: conf.VPNNetwork,
IP: peer.IP,
PublicIP: peer.PublicIP,
Port: peer.Port,
Mediator: peer.Mediator,
EncPubKey: encPubKey[:],
@@ -240,6 +241,10 @@ func (a *API) Peer_Create(creationCode string) (*m.PeerConfig, error) {
}
func (a *API) Peer_Update(p *Peer) error {
a.lock.Lock()
defer a.lock.Unlock()
p.Version = idgen.NextID(0)
return db.Peer_Update(a.db, p)
}

View File

@@ -308,16 +308,17 @@ func Session_List(
type Peer struct {
PeerIP byte
Version int64
APIKey string
Name string
IP []byte
PublicIP []byte
Port uint16
Mediator bool
EncPubKey []byte
SignPubKey []byte
}
const Peer_SelectQuery = "SELECT PeerIP,APIKey,Name,IP,Port,Mediator,EncPubKey,SignPubKey FROM peers"
const Peer_SelectQuery = "SELECT PeerIP,Version,APIKey,Name,PublicIP,Port,Mediator,EncPubKey,SignPubKey FROM peers"
func Peer_Insert(
tx TX,
@@ -328,7 +329,7 @@ func Peer_Insert(
return err
}
_, err = tx.Exec("INSERT INTO peers(PeerIP,APIKey,Name,IP,Port,Mediator,EncPubKey,SignPubKey) VALUES(?,?,?,?,?,?,?,?)", row.PeerIP, row.APIKey, row.Name, row.IP, row.Port, row.Mediator, row.EncPubKey, row.SignPubKey)
_, err = tx.Exec("INSERT INTO peers(PeerIP,Version,APIKey,Name,PublicIP,Port,Mediator,EncPubKey,SignPubKey) VALUES(?,?,?,?,?,?,?,?,?)", row.PeerIP, row.Version, row.APIKey, row.Name, row.PublicIP, row.Port, row.Mediator, row.EncPubKey, row.SignPubKey)
return err
}
@@ -341,7 +342,7 @@ func Peer_Update(
return err
}
result, err := tx.Exec("UPDATE peers SET Name=?,IP=?,Port=?,Mediator=? WHERE PeerIP=?", row.Name, row.IP, row.Port, row.Mediator, row.PeerIP)
result, err := tx.Exec("UPDATE peers SET Version=?,Name=?,PublicIP=?,Port=?,Mediator=? WHERE PeerIP=?", row.Version, row.Name, row.PublicIP, row.Port, row.Mediator, row.PeerIP)
if err != nil {
return err
}
@@ -369,7 +370,7 @@ func Peer_UpdateFull(
return err
}
result, err := tx.Exec("UPDATE peers SET APIKey=?,Name=?,IP=?,Port=?,Mediator=?,EncPubKey=?,SignPubKey=? WHERE PeerIP=?", row.APIKey, row.Name, row.IP, row.Port, row.Mediator, row.EncPubKey, row.SignPubKey, row.PeerIP)
result, err := tx.Exec("UPDATE peers SET Version=?,APIKey=?,Name=?,PublicIP=?,Port=?,Mediator=?,EncPubKey=?,SignPubKey=? WHERE PeerIP=?", row.Version, row.APIKey, row.Name, row.PublicIP, row.Port, row.Mediator, row.EncPubKey, row.SignPubKey, row.PeerIP)
if err != nil {
return err
}
@@ -419,8 +420,8 @@ func Peer_Get(
err error,
) {
row = &Peer{}
r := tx.QueryRow("SELECT PeerIP,APIKey,Name,IP,Port,Mediator,EncPubKey,SignPubKey FROM peers WHERE PeerIP=?", PeerIP)
err = r.Scan(&row.PeerIP, &row.APIKey, &row.Name, &row.IP, &row.Port, &row.Mediator, &row.EncPubKey, &row.SignPubKey)
r := tx.QueryRow("SELECT PeerIP,Version,APIKey,Name,PublicIP,Port,Mediator,EncPubKey,SignPubKey FROM peers WHERE PeerIP=?", PeerIP)
err = r.Scan(&row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Mediator, &row.EncPubKey, &row.SignPubKey)
return
}
@@ -434,7 +435,7 @@ func Peer_GetWhere(
) {
row = &Peer{}
r := tx.QueryRow(query, args...)
err = r.Scan(&row.PeerIP, &row.APIKey, &row.Name, &row.IP, &row.Port, &row.Mediator, &row.EncPubKey, &row.SignPubKey)
err = r.Scan(&row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Mediator, &row.EncPubKey, &row.SignPubKey)
return
}
@@ -454,7 +455,7 @@ func Peer_Iterate(
defer rows.Close()
for rows.Next() {
row := &Peer{}
err := rows.Scan(&row.PeerIP, &row.APIKey, &row.Name, &row.IP, &row.Port, &row.Mediator, &row.EncPubKey, &row.SignPubKey)
err := rows.Scan(&row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Mediator, &row.EncPubKey, &row.SignPubKey)
if !yield(row, err) {
return
}

View File

@@ -44,10 +44,10 @@ func Session_Validate(s *Session) error {
func Peer_Sanitize(p *Peer) {
p.Name = strings.TrimSpace(p.Name)
if len(p.IP) != 0 {
addr, ok := netip.AddrFromSlice(p.IP)
if len(p.PublicIP) != 0 {
addr, ok := netip.AddrFromSlice(p.PublicIP)
if ok && addr.Is4() {
p.IP = addr.AsSlice()
p.PublicIP = addr.AsSlice()
}
}
if p.Port == 0 {
@@ -56,8 +56,8 @@ func Peer_Sanitize(p *Peer) {
}
func Peer_Validate(p *Peer) error {
if len(p.IP) > 0 {
_, ok := netip.AddrFromSlice(p.IP)
if len(p.PublicIP) > 0 {
_, ok := netip.AddrFromSlice(p.PublicIP)
if !ok {
return ErrInvalidIP
}

View File

@@ -15,9 +15,10 @@ TABLE sessions OF Session NoUpdate (
TABLE peers OF Peer (
PeerIP byte PK,
Version int64,
APIKey string NoUpdate,
Name string,
IP []byte,
PublicIP []byte,
Port uint16,
Mediator bool,
EncPubKey []byte NoUpdate,

View File

@@ -17,9 +17,10 @@ CREATE INDEX sessions_last_seen_index ON sessions(LastSeenAt);
CREATE TABLE peers (
PeerIP INTEGER NOT NULL PRIMARY KEY, -- Final byte.
Version INTEGER NOT NULL,
APIKey TEXT NOT NULL UNIQUE,
Name TEXT NOT NULL UNIQUE, -- For humans.
IP BLOB NOT NULL,
PublicIP BLOB NOT NULL,
Port INTEGER NOT NULL,
Mediator INTEGER NOT NULL DEFAULT 0, -- Boolean if peer will forward packets. Must also have public address.
EncPubKey BLOB NOT NULL,

View File

@@ -64,3 +64,18 @@ func (app *App) handleSignedIn(pattern string, fn handlerFunc) {
return fn(s, w, r)
})
}
type peerHandlerFunc func(w http.ResponseWriter, r *http.Request) error
func (app *App) handlePeer(pattern string, fn peerHandlerFunc) {
wrapped := func(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
if err := fn(w, r); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
app.mux.HandleFunc(pattern,
webutil.WithLogging(
wrapped))
}

View File

@@ -165,7 +165,7 @@ func (a *App) _adminPeerCreateSubmit(s *api.Session, w http.ResponseWriter, r *h
args := api.PeerCreateArgs{}
err := webutil.NewFormScanner(r.Form).
Scan("Name", &args.Name).
Scan("IP", &ipStr).
Scan("PublicIP", &ipStr).
Scan("Port", &args.Port).
Scan("Mediator", &args.Mediator).
Error()
@@ -173,7 +173,7 @@ func (a *App) _adminPeerCreateSubmit(s *api.Session, w http.ResponseWriter, r *h
return err
}
if args.IP, err = stringToIP(ipStr); err != nil {
if args.PublicIP, err = stringToIP(ipStr); err != nil {
return err
}
@@ -247,7 +247,7 @@ func (a *App) _adminPeerEditSubmit(s *api.Session, w http.ResponseWriter, r *htt
}
err = webutil.NewFormScanner(r.Form).
Scan("Name", &peer.Name).
Scan("IP", &ipStr).
Scan("PublicIP", &ipStr).
Scan("Port", &peer.Port).
Scan("Mediator", &peer.Mediator).
Error()
@@ -255,7 +255,7 @@ func (a *App) _adminPeerEditSubmit(s *api.Session, w http.ResponseWriter, r *htt
return err
}
if peer.IP, err = stringToIP(ipStr); err != nil {
if peer.PublicIP, err = stringToIP(ipStr); err != nil {
return err
}
@@ -298,7 +298,7 @@ func (a *App) _adminPeerDeleteSubmit(s *api.Session, w http.ResponseWriter, r *h
return a.redirect(w, r, "/admin/peer/list/")
}
func (a *App) _peerCreate(s *api.Session, w http.ResponseWriter, r *http.Request) error {
func (a *App) _peerCreate(w http.ResponseWriter, r *http.Request) error {
code := r.FormValue("Code")
conf, err := a.api.Peer_Create(code)
if err != nil {
@@ -308,7 +308,7 @@ func (a *App) _peerCreate(s *api.Session, w http.ResponseWriter, r *http.Request
return a.sendJSON(w, conf)
}
func (a *App) _peerFetchState(s *api.Session, w http.ResponseWriter, r *http.Request) error {
func (a *App) _peerFetchState(w http.ResponseWriter, r *http.Request) error {
_, apiKey, ok := r.BasicAuth()
if !ok {
log.Printf("1")
@@ -333,15 +333,16 @@ func (a *App) _peerFetchState(s *api.Session, w http.ResponseWriter, r *http.Req
HubAddress: conf.HubAddress,
Network: conf.VPNNetwork,
PeerIP: peer.PeerIP,
IP: peer.IP,
PublicIP: peer.PublicIP,
Port: peer.Port,
}
for _, p := range peers {
state.Peers[p.PeerIP] = &m.Peer{
PeerIP: p.PeerIP,
Version: p.Version,
Name: p.Name,
IP: p.IP,
PublicIP: p.PublicIP,
Port: p.Port,
Mediator: p.Mediator,
EncPubKey: p.EncPubKey,

View File

@@ -26,6 +26,6 @@ func (a *App) registerRoutes() {
a.handleSignedIn("GET /admin/peer/delete/", a._adminPeerDelete)
a.handleSignedIn("POST /admin/peer/delete/", a._adminPeerDeleteSubmit)
a.handleNotSignedIn("GET /peer/create/", a._peerCreate)
a.handleNotSignedIn("GET /peer/fetch-state/", a._peerFetchState)
a.handlePeer("GET /peer/create/", a._peerCreate)
a.handlePeer("GET /peer/fetch-state/", a._peerFetchState)
}

View File

@@ -8,8 +8,8 @@
<input type="text" name="Name">
</p>
<p>
<label>IP</label><br>
<input type="text" name="IP">
<label>Public IP</label><br>
<input type="text" name="PublicIP">
</p>
<p>
<label>Port</label><br>

View File

@@ -13,8 +13,8 @@
<input type="text" value="{{.Name}}" disabled>
</p>
<p>
<label>IP</label><br>
<input type="text" value="{{ipToString .IP}}" disabled>
<label>Public IP</label><br>
<input type="text" value="{{ipToString .PublicIP}}" disabled>
</p>
<p>
<label>Port</label><br>

View File

@@ -13,8 +13,8 @@
<input type="text" name="Name" value="{{.Name}}">
</p>
<p>
<label>IP</label><br>
<input type="text" name="IP" value="{{ipToString .IP}}">
<label>Public IP</label><br>
<input type="text" name="PublicIP" value="{{ipToString .PublicIP}}">
</p>
<p>
<label>Port</label><br>

View File

@@ -11,7 +11,7 @@
<tr>
<th>PeerIP</th>
<th>Name</th>
<th>IP</th>
<th>Public IP</th>
<th>Port</th>
<th>Mediator</th>
</tr>
@@ -25,7 +25,7 @@
</a>
</td>
<td>{{.Name}}</td>
<td>{{ipToString .IP}}</td>
<td>{{ipToString .PublicIP}}</td>
<td>{{.Port}}</td>
<td>{{if .Mediator}}T{{else}}F{{end}}</td>
</tr>

View File

@@ -10,7 +10,7 @@
<table class="def-list">
<tr><td>Peer IP</td><td>{{.PeerIP}}</td></tr>
<tr><td>Name</td><td>{{.Name}}</td></tr>
<tr><td>IP</td><td>{{ipToString .IP}}</td></tr>
<tr><td>Public IP</td><td>{{ipToString .PublicIP}}</td></tr>
<tr><td>Port</td><td>{{.Port}}</td></tr>
<tr><td>Mediator</td><td>{{if .Mediator}}T{{else}}F{{end}}</td></tr>
<tr><td>API Key</td><td>{{.APIKey}}</td></tr>