Cleanup, hub updates

This commit is contained in:
jdl 2024-12-23 09:34:11 +01:00
parent a6e022e570
commit 6a6e30feb9
17 changed files with 108 additions and 147 deletions

View File

@ -15,7 +15,6 @@ import (
"git.crumpington.com/lib/go/sqliteutil" "git.crumpington.com/lib/go/sqliteutil"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"golang.org/x/crypto/nacl/box" "golang.org/x/crypto/nacl/box"
"golang.org/x/crypto/nacl/sign"
) )
//go:embed migrations //go:embed migrations
@ -146,7 +145,7 @@ type PeerCreateArgs struct {
Name string Name string
PublicIP []byte PublicIP []byte
Port uint16 Port uint16
Mediator bool Relay bool
} }
// Create the intention to add a peer. The returned code is used to complete // Create the intention to add a peer. The returned code is used to complete
@ -184,11 +183,6 @@ func (a *API) Peer_Create(creationCode string) (*m.PeerConfig, error) {
return nil, err return nil, err
} }
signPubKey, signPrivKey, err := sign.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
// Get peer IP. // Get peer IP.
peerIP := byte(0) peerIP := byte(0)
@ -208,15 +202,14 @@ func (a *API) Peer_Create(creationCode string) (*m.PeerConfig, error) {
} }
peer := &Peer{ peer := &Peer{
PeerIP: peerIP, PeerIP: peerIP,
Version: idgen.NextID(0), Version: idgen.NextID(0),
APIKey: idgen.NewToken(), APIKey: idgen.NewToken(),
Name: args.Name, Name: args.Name,
PublicIP: args.PublicIP, PublicIP: args.PublicIP,
Port: args.Port, Port: args.Port,
Mediator: args.Mediator, Relay: args.Relay,
EncPubKey: encPubKey[:], PubKey: encPubKey[:],
SignPubKey: signPubKey[:],
} }
if err := db.Peer_Insert(a.db, peer); err != nil { if err := db.Peer_Insert(a.db, peer); err != nil {
@ -226,17 +219,15 @@ func (a *API) Peer_Create(creationCode string) (*m.PeerConfig, error) {
conf := a.Config_Get() conf := a.Config_Get()
return &m.PeerConfig{ return &m.PeerConfig{
PeerIP: peer.PeerIP, PeerIP: peer.PeerIP,
HubAddress: conf.HubAddress, HubAddress: conf.HubAddress,
APIKey: peer.APIKey, APIKey: peer.APIKey,
Network: conf.VPNNetwork, Network: conf.VPNNetwork,
PublicIP: peer.PublicIP, PublicIP: peer.PublicIP,
Port: peer.Port, Port: peer.Port,
Mediator: peer.Mediator, Relay: peer.Relay,
EncPubKey: encPubKey[:], PubKey: encPubKey[:],
EncPrivKey: encPrivKey[:], PrivKey: encPrivKey[:],
SignPubKey: signPubKey[:],
SignPrivKey: signPrivKey[:],
}, nil }, nil
} }

View File

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

View File

@ -51,7 +51,7 @@ func Peer_Sanitize(p *Peer) {
} }
} }
if p.Port == 0 { if p.Port == 0 {
p.Port = 515 p.Port = 456
} }
} }

View File

@ -20,7 +20,6 @@ TABLE peers OF Peer (
Name string, Name string,
PublicIP []byte, PublicIP []byte,
Port uint16, Port uint16,
Mediator bool, Relay bool,
EncPubKey []byte NoUpdate, PubKey []byte NoUpdate
SignPubKey []byte NoUpdate
); );

View File

@ -22,7 +22,6 @@ CREATE TABLE peers (
Name TEXT NOT NULL UNIQUE, -- For humans. Name TEXT NOT NULL UNIQUE, -- For humans.
PublicIP BLOB NOT NULL, PublicIP BLOB NOT NULL,
Port INTEGER NOT NULL, Port INTEGER NOT NULL,
Mediator INTEGER NOT NULL DEFAULT 0, -- Boolean if peer will forward packets. Must also have public address. Relay INTEGER NOT NULL DEFAULT 0, -- Boolean if peer will forward packets. Must also have public address.
EncPubKey BLOB NOT NULL, PubKey BLOB NOT NULL
SignPubKey BLOB NOT NULL
) WITHOUT ROWID; ) WITHOUT ROWID;

View File

@ -4,6 +4,8 @@ import (
"errors" "errors"
"log" "log"
"net/http" "net/http"
"net/netip"
"strings"
"vppn/hub/api" "vppn/hub/api"
"vppn/m" "vppn/m"
@ -155,6 +157,29 @@ func (a *App) _adminPeerList(s *api.Session, w http.ResponseWriter, r *http.Requ
}) })
} }
func (a *App) _adminHosts(s *api.Session, w http.ResponseWriter, r *http.Request) error {
conf := a.api.Config_Get()
peers, err := a.api.Peer_List()
if err != nil {
return err
}
b := strings.Builder{}
for _, peer := range peers {
ip := conf.VPNNetwork
ip[3] = peer.PeerIP
b.WriteString(netip.AddrFrom4([4]byte(ip)).String())
b.WriteString(" ")
b.WriteString(peer.Name)
b.WriteString("\n")
}
w.Write([]byte(b.String()))
return nil
}
func (a *App) _adminPeerCreate(s *api.Session, w http.ResponseWriter, r *http.Request) error { func (a *App) _adminPeerCreate(s *api.Session, w http.ResponseWriter, r *http.Request) error {
return a.render("/admin-peer-create.html", w, struct{ Session *api.Session }{s}) return a.render("/admin-peer-create.html", w, struct{ Session *api.Session }{s})
} }
@ -167,7 +192,7 @@ func (a *App) _adminPeerCreateSubmit(s *api.Session, w http.ResponseWriter, r *h
Scan("Name", &args.Name). Scan("Name", &args.Name).
Scan("PublicIP", &ipStr). Scan("PublicIP", &ipStr).
Scan("Port", &args.Port). Scan("Port", &args.Port).
Scan("Mediator", &args.Mediator). Scan("Relay", &args.Relay).
Error() Error()
if err != nil { if err != nil {
return err return err
@ -249,7 +274,7 @@ func (a *App) _adminPeerEditSubmit(s *api.Session, w http.ResponseWriter, r *htt
Scan("Name", &peer.Name). Scan("Name", &peer.Name).
Scan("PublicIP", &ipStr). Scan("PublicIP", &ipStr).
Scan("Port", &peer.Port). Scan("Port", &peer.Port).
Scan("Mediator", &peer.Mediator). Scan("Relay", &peer.Relay).
Error() Error()
if err != nil { if err != nil {
return err return err
@ -311,19 +336,16 @@ func (a *App) _peerCreate(w http.ResponseWriter, r *http.Request) error {
func (a *App) _peerFetchState(w http.ResponseWriter, r *http.Request) error { func (a *App) _peerFetchState(w http.ResponseWriter, r *http.Request) error {
_, apiKey, ok := r.BasicAuth() _, apiKey, ok := r.BasicAuth()
if !ok { if !ok {
log.Printf("1")
return api.ErrNotAuthorized return api.ErrNotAuthorized
} }
peer, err := a.api.Peer_GetByAPIKey(apiKey) peer, err := a.api.Peer_GetByAPIKey(apiKey)
if err != nil { if err != nil {
log.Printf("2")
return err return err
} }
peers, err := a.api.Peer_List() peers, err := a.api.Peer_List()
if err != nil { if err != nil {
log.Printf("3")
return err return err
} }
@ -339,14 +361,13 @@ func (a *App) _peerFetchState(w http.ResponseWriter, r *http.Request) error {
for _, p := range peers { for _, p := range peers {
state.Peers[p.PeerIP] = &m.Peer{ state.Peers[p.PeerIP] = &m.Peer{
PeerIP: p.PeerIP, PeerIP: p.PeerIP,
Version: p.Version, Version: p.Version,
Name: p.Name, Name: p.Name,
PublicIP: p.PublicIP, PublicIP: p.PublicIP,
Port: p.Port, Port: p.Port,
Mediator: p.Mediator, Relay: p.Relay,
EncPubKey: p.EncPubKey, PubKey: p.PubKey,
SignPubKey: p.SignPubKey,
} }
} }

View File

@ -17,6 +17,7 @@ func (a *App) registerRoutes() {
a.handleSignedIn("GET /admin/password/edit/", a._adminPasswordEdit) a.handleSignedIn("GET /admin/password/edit/", a._adminPasswordEdit)
a.handleSignedIn("POST /admin/password/edit/", a._adminPasswordSubmit) a.handleSignedIn("POST /admin/password/edit/", a._adminPasswordSubmit)
a.handleSignedIn("GET /admin/peer/list/", a._adminPeerList) a.handleSignedIn("GET /admin/peer/list/", a._adminPeerList)
a.handleSignedIn("GET /admin/peer/hosts/", a._adminHosts)
a.handleSignedIn("GET /admin/peer/create/", a._adminPeerCreate) a.handleSignedIn("GET /admin/peer/create/", a._adminPeerCreate)
a.handleSignedIn("POST /admin/peer/create/", a._adminPeerCreateSubmit) a.handleSignedIn("POST /admin/peer/create/", a._adminPeerCreateSubmit)
a.handleSignedIn("GET /admin/peer/intent-created/", a._adminPeerIntentCreated) a.handleSignedIn("GET /admin/peer/intent-created/", a._adminPeerIntentCreated)

View File

@ -13,12 +13,12 @@
</p> </p>
<p> <p>
<label>Port</label><br> <label>Port</label><br>
<input type="number" name="Port" value="515"> <input type="number" name="Port" value="456">
</p> </p>
<p> <p>
<label> <label>
<input type="checkbox" name="Mediator"> <input type="checkbox" name="Relay">
Mediator Relay
</label> </label>
</p> </p>
<p> <p>

View File

@ -22,8 +22,8 @@
</p> </p>
<p> <p>
<label> <label>
<input type="checkbox" {{if .Mediator}}checked{{end}} disabled> <input type="checkbox" {{if .Relay}}checked{{end}} disabled>
Mediator Relay
</label> </label>
</p> </p>
<p> <p>

View File

@ -22,8 +22,8 @@
</p> </p>
<p> <p>
<label> <label>
<input type="checkbox" name="Mediator" {{if .Mediator}}checked{{end}}> <input type="checkbox" name="Relay" {{if .Relay}}checked{{end}}>
Mediator Relay
</label> </label>
</p> </p>
<p> <p>

View File

@ -2,7 +2,8 @@
<h2>Peers</h2> <h2>Peers</h2>
<p> <p>
<a href="/admin/peer/create/">Add Peer</a> <a href="/admin/peer/create/">Add Peer</a> /
<a href="/admin/peer/hosts/">Hosts</a>
</p> </p>
{{if .Peers -}} {{if .Peers -}}
@ -13,7 +14,7 @@
<th>Name</th> <th>Name</th>
<th>Public IP</th> <th>Public IP</th>
<th>Port</th> <th>Port</th>
<th>Mediator</th> <th>Relay</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -27,7 +28,7 @@
<td>{{.Name}}</td> <td>{{.Name}}</td>
<td>{{ipToString .PublicIP}}</td> <td>{{ipToString .PublicIP}}</td>
<td>{{.Port}}</td> <td>{{.Port}}</td>
<td>{{if .Mediator}}T{{else}}F{{end}}</td> <td>{{if .Relay}}T{{else}}F{{end}}</td>
</tr> </tr>
</tbody> </tbody>
{{- end}} {{- end}}

View File

@ -12,7 +12,7 @@
<tr><td>Name</td><td>{{.Name}}</td></tr> <tr><td>Name</td><td>{{.Name}}</td></tr>
<tr><td>Public IP</td><td>{{ipToString .PublicIP}}</td></tr> <tr><td>Public IP</td><td>{{ipToString .PublicIP}}</td></tr>
<tr><td>Port</td><td>{{.Port}}</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>Relay</td><td>{{if .Relay}}T{{else}}F{{end}}</td></tr>
<tr><td>API Key</td><td>{{.APIKey}}</td></tr> <tr><td>API Key</td><td>{{.APIKey}}</td></tr>
</table> </table>
{{- end}} {{- end}}

View File

@ -2,28 +2,25 @@
package m package m
type PeerConfig struct { type PeerConfig struct {
PeerIP byte PeerIP byte
HubAddress string HubAddress string
Network []byte Network []byte
APIKey string APIKey string
PublicIP []byte PublicIP []byte
Port uint16 Port uint16
Mediator bool Relay bool
EncPubKey []byte PubKey []byte
EncPrivKey []byte PrivKey []byte
SignPubKey []byte
SignPrivKey []byte
} }
type Peer struct { type Peer struct {
PeerIP byte PeerIP byte
Version int64 Version int64
Name string Name string
PublicIP []byte PublicIP []byte
Port uint16 Port uint16
Mediator bool Relay bool
EncPubKey []byte PubKey []byte
SignPubKey []byte
} }
type NetworkState struct { type NetworkState struct {

View File

@ -106,7 +106,7 @@ func main(listenIP string, port uint16) {
// Intialize globals. // Intialize globals.
localIP = config.PeerIP localIP = config.PeerIP
localPub = addrIsValid(config.PublicIP) localPub = addrIsValid(config.PublicIP)
privateKey = config.EncPrivKey privateKey = config.PrivKey
_iface = newIFWriter(iface) _iface = newIFWriter(iface)
_conn = newConnWriter(conn) _conn = newConnWriter(conn)

View File

@ -14,8 +14,6 @@ const (
packetTypeSyn = iota + 1 packetTypeSyn = iota + 1
packetTypeSynAck packetTypeSynAck
packetTypeAck packetTypeAck
packetTypeAddrReq
packetTypeAddrResp
) )
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -34,10 +32,6 @@ func (p *controlPacket) ParsePayload(buf []byte) (err error) {
p.Payload, err = parseSynAckPacket(buf) p.Payload, err = parseSynAckPacket(buf)
case packetTypeAck: case packetTypeAck:
p.Payload, err = parseAckPacket(buf) p.Payload, err = parseAckPacket(buf)
case packetTypeAddrReq:
p.Payload, err = parseAddrReqPacket(buf)
case packetTypeAddrResp:
p.Payload, err = parseAddrRespPacket(buf)
default: default:
return errUnknownPacketType return errUnknownPacketType
} }
@ -118,46 +112,3 @@ func parseAckPacket(buf []byte) (p ackPacket, err error) {
Error() Error()
return return
} }
// ----------------------------------------------------------------------------
type addrReqPacket struct {
TraceID uint64
}
func (p addrReqPacket) Marshal(buf []byte) []byte {
return newBinWriter(buf).
Byte(packetTypeAddrReq).
Uint64(p.TraceID).
Build()
}
func parseAddrReqPacket(buf []byte) (p addrReqPacket, err error) {
err = newBinReader(buf[1:]).
Uint64(&p.TraceID).
Error()
return
}
// ----------------------------------------------------------------------------
type addrRespPacket struct {
TraceID uint64
Addr netip.AddrPort
}
func (p addrRespPacket) Marshal(buf []byte) []byte {
return newBinWriter(buf).
Byte(packetTypeAddrResp).
Uint64(p.TraceID).
AddrPort(p.Addr).
Build()
}
func parseAddrRespPacket(buf []byte) (p addrRespPacket, err error) {
err = newBinReader(buf[1:]).
Uint64(&p.TraceID).
AddrPort(&p.Addr).
Error()
return
}

View File

@ -2,6 +2,7 @@ package node
import ( import (
"crypto/rand" "crypto/rand"
"net/netip"
"reflect" "reflect"
"testing" "testing"
) )
@ -24,7 +25,8 @@ func TestPacketSyn(t *testing.T) {
func TestPacketSynAck(t *testing.T) { func TestPacketSynAck(t *testing.T) {
in := synAckPacket{ in := synAckPacket{
TraceID: newTraceID(), TraceID: newTraceID(),
RecvAddr: netip.AddrPort{},
} }
out, err := parseSynAckPacket(in.Marshal(make([]byte, bufferSize))) out, err := parseSynAckPacket(in.Marshal(make([]byte, bufferSize)))

View File

@ -102,12 +102,12 @@ func (s *peerSupervisor) _peerUpdate(peer *m.Peer) stateFunc {
} }
s.staged.IP = s.remoteIP s.staged.IP = s.remoteIP
s.staged.ControlCipher = newControlCipher(privateKey, peer.EncPubKey) s.staged.ControlCipher = newControlCipher(privateKey, peer.PubKey)
s.staged.DataCipher = newDataCipher() s.staged.DataCipher = newDataCipher()
if ip, isValid := netip.AddrFromSlice(peer.PublicIP); isValid { if ip, isValid := netip.AddrFromSlice(peer.PublicIP); isValid {
s.remotePub = true s.remotePub = true
s.staged.Relay = peer.Mediator s.staged.Relay = peer.Relay
s.staged.RemoteAddr = netip.AddrPortFrom(ip, peer.Port) s.staged.RemoteAddr = netip.AddrPortFrom(ip, peer.Port)
} }