Fix nil-pointer crash generating QR codes for non-default servers

GetClients, GetClientByID, and SendRequestedConfigsToTelegram all
looked up the legacy "wg0" server unconditionally when building a
client's QR code / config, ignoring which server the client actually
belongs to. On any multi-server setup without a migrated wg0, the
server lookup returned a zero-value model.Server (error discarded),
and BuildClientConfig then dereferenced its nil KeyPair pointer,
panicking whenever a client's QR code was rendered.

Now looks up the client's own ServerID (falling back to wg0 only for
legacy clients with no ServerID set) and surfaces the lookup error
instead of silently continuing with an empty server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-07-12 23:42:36 +02:00
co-authored by Claude Sonnet 5
parent 067d0af323
commit 0dbb916866
2 changed files with 45 additions and 21 deletions
+36 -20
View File
@@ -412,14 +412,22 @@ func (o *JsonDB) GetClients(hasQRCode bool) ([]model.ClientData, error) {
// generate client qrcode image in base64 // generate client qrcode image in base64
if hasQRCode && client.PrivateKey != "" { if hasQRCode && client.PrivateKey != "" {
server, _ := o.GetServerByID(util.DefaultServerID) serverID := client.ServerID
globalSettings, _ := o.GetGlobalSettings() if serverID == "" {
serverID = util.DefaultServerID
png, err := qrcode.Encode(util.BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256) }
if err == nil { server, err := o.GetServerByID(serverID)
clientData.QRCode = "data:image/png;base64," + base64.StdEncoding.EncodeToString(png) if err != nil {
fmt.Printf("Cannot generate QR code: server %s not found: %v\n", serverID, err)
} else { } else {
fmt.Print("Cannot generate QR code: ", err) globalSettings, _ := o.GetGlobalSettings()
png, err := qrcode.Encode(util.BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256)
if err == nil {
clientData.QRCode = "data:image/png;base64," + base64.StdEncoding.EncodeToString(png)
} else {
fmt.Print("Cannot generate QR code: ", err)
}
} }
} }
@@ -442,21 +450,29 @@ func (o *JsonDB) GetClientByID(clientID string, qrCodeSettings model.QRCodeSetti
// generate client qrcode image in base64 // generate client qrcode image in base64
if qrCodeSettings.Enabled && client.PrivateKey != "" { if qrCodeSettings.Enabled && client.PrivateKey != "" {
server, _ := o.GetServerByID(util.DefaultServerID) serverID := client.ServerID
globalSettings, _ := o.GetGlobalSettings() if serverID == "" {
client := client serverID = util.DefaultServerID
if !qrCodeSettings.IncludeDNS {
globalSettings.DNSServers = []string{}
} }
if !qrCodeSettings.IncludeMTU { server, err := o.GetServerByID(serverID)
globalSettings.MTU = 0 if err != nil {
} fmt.Printf("Cannot generate QR code: server %s not found: %v\n", serverID, err)
png, err := qrcode.Encode(util.BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256)
if err == nil {
clientData.QRCode = "data:image/png;base64," + base64.StdEncoding.EncodeToString(png)
} else { } else {
fmt.Print("Cannot generate QR code: ", err) globalSettings, _ := o.GetGlobalSettings()
client := client
if !qrCodeSettings.IncludeDNS {
globalSettings.DNSServers = []string{}
}
if !qrCodeSettings.IncludeMTU {
globalSettings.MTU = 0
}
png, err := qrcode.Encode(util.BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256)
if err == nil {
clientData.QRCode = "data:image/png;base64," + base64.StdEncoding.EncodeToString(png)
} else {
fmt.Print("Cannot generate QR code: ", err)
}
} }
} }
+9 -1
View File
@@ -633,7 +633,15 @@ func SendRequestedConfigsToTelegram(db store.IStore, userid int64) []string {
} }
// build config // build config
server, _ := db.GetServerByID(DefaultServerID) serverID := clientData.Client.ServerID
if serverID == "" {
serverID = DefaultServerID
}
server, err := db.GetServerByID(serverID)
if err != nil {
failedList = append(failedList, clientData.Client.Name)
continue
}
globalSettings, _ := db.GetGlobalSettings() globalSettings, _ := db.GetGlobalSettings()
config := BuildClientConfig(*clientData.Client, server, globalSettings) config := BuildClientConfig(*clientData.Client, server, globalSettings)
configData := []byte(config) configData := []byte(config)