mirror of
https://github.com/ngoduykhanh/wireguard-ui.git
synced 2025-04-28 21:19:43 +03:00
Implement Optional Private Keys (#161)
This commit is contained in:
parent
4be3a65691
commit
037a6c56d3
4 changed files with 78 additions and 23 deletions
|
@ -31,7 +31,7 @@ function renderClientList(data) {
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
||||||
data-target="#modal_qr_client" data-clientid="${obj.Client.id}"
|
data-target="#modal_qr_client" data-clientid="${obj.Client.id}"
|
||||||
data-clientname="${obj.Client.name}">Scan</button>
|
data-clientname="${obj.Client.name}" ${obj.QRCode != "" ? '' : ' disabled'}>Scan</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
||||||
|
|
|
@ -171,12 +171,36 @@ func NewClient(db store.IStore) echo.HandlerFunc {
|
||||||
client.ID = guid.String()
|
client.ID = guid.String()
|
||||||
|
|
||||||
// gen Wireguard key pair
|
// gen Wireguard key pair
|
||||||
|
if client.PublicKey == "" {
|
||||||
key, err := wgtypes.GeneratePrivateKey()
|
key, err := wgtypes.GeneratePrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Cannot generate wireguard key pair: ", err)
|
log.Error("Cannot generate wireguard key pair: ", err)
|
||||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
|
||||||
}
|
}
|
||||||
|
client.PrivateKey = key.String()
|
||||||
|
client.PublicKey = key.PublicKey().String()
|
||||||
|
} else {
|
||||||
|
_, err := wgtypes.ParseKey(client.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot verify wireguard public key: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify Wireguard public key"})
|
||||||
|
}
|
||||||
|
// check for duplicates
|
||||||
|
clients, err := db.GetClients(false)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot get clients for duplicate check")
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get clients for duplicate check"})
|
||||||
|
}
|
||||||
|
for _, other := range clients {
|
||||||
|
if other.Client.PublicKey == client.PublicKey {
|
||||||
|
log.Error("Duplicate Public Key")
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Duplicate Public Key"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if client.PresharedKey == "" {
|
||||||
presharedKey, err := wgtypes.GenerateKey()
|
presharedKey, err := wgtypes.GenerateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Cannot generated preshared key: ", err)
|
log.Error("Cannot generated preshared key: ", err)
|
||||||
|
@ -184,10 +208,14 @@ func NewClient(db store.IStore) echo.HandlerFunc {
|
||||||
false, "Cannot generate Wireguard preshared key",
|
false, "Cannot generate Wireguard preshared key",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
client.PrivateKey = key.String()
|
|
||||||
client.PublicKey = key.PublicKey().String()
|
|
||||||
client.PresharedKey = presharedKey.String()
|
client.PresharedKey = presharedKey.String()
|
||||||
|
} else {
|
||||||
|
_, err := wgtypes.ParseKey(client.PresharedKey)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot verify wireguard preshared key: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify Wireguard preshared key"})
|
||||||
|
}
|
||||||
|
}
|
||||||
client.CreatedAt = time.Now().UTC()
|
client.CreatedAt = time.Now().UTC()
|
||||||
client.UpdatedAt = client.CreatedAt
|
client.UpdatedAt = client.CreatedAt
|
||||||
|
|
||||||
|
@ -227,18 +255,25 @@ func EmailClient(db store.IStore, mailer emailer.Emailer, emailSubject, emailCon
|
||||||
config := util.BuildClientConfig(*clientData.Client, server, globalSettings)
|
config := util.BuildClientConfig(*clientData.Client, server, globalSettings)
|
||||||
|
|
||||||
cfg_att := emailer.Attachment{"wg0.conf", []byte(config)}
|
cfg_att := emailer.Attachment{"wg0.conf", []byte(config)}
|
||||||
|
var attachments []emailer.Attachment
|
||||||
|
if clientData.Client.PrivateKey != "" {
|
||||||
qrdata, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(clientData.QRCode, "data:image/png;base64,"))
|
qrdata, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(clientData.QRCode, "data:image/png;base64,"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "decoding: " + err.Error()})
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "decoding: " + err.Error()})
|
||||||
}
|
}
|
||||||
qr_att := emailer.Attachment{"wg.png", qrdata}
|
qr_att := emailer.Attachment{"wg.png", qrdata}
|
||||||
|
attachments = []emailer.Attachment{cfg_att, qr_att}
|
||||||
|
} else {
|
||||||
|
attachments = []emailer.Attachment{cfg_att}
|
||||||
|
}
|
||||||
err = mailer.Send(
|
err = mailer.Send(
|
||||||
clientData.Client.Name,
|
clientData.Client.Name,
|
||||||
payload.Email,
|
payload.Email,
|
||||||
emailSubject,
|
emailSubject,
|
||||||
emailContent,
|
emailContent,
|
||||||
[]emailer.Attachment{cfg_att, qr_att},
|
attachments,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ func (o *JsonDB) GetClients(hasQRCode bool) ([]model.ClientData, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate client qrcode image in base64
|
// generate client qrcode image in base64
|
||||||
if hasQRCode {
|
if hasQRCode && client.PrivateKey != "" {
|
||||||
server, _ := o.GetServer()
|
server, _ := o.GetServer()
|
||||||
globalSettings, _ := o.GetGlobalSettings()
|
globalSettings, _ := o.GetGlobalSettings()
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ func (o *JsonDB) GetClientByID(clientID string, hasQRCode bool) (model.ClientDat
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate client qrcode image in base64
|
// generate client qrcode image in base64
|
||||||
if hasQRCode {
|
if hasQRCode && client.PrivateKey != "" {
|
||||||
server, _ := o.GetServer()
|
server, _ := o.GetServer()
|
||||||
globalSettings, _ := o.GetGlobalSettings()
|
globalSettings, _ := o.GetGlobalSettings()
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,21 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<details>
|
||||||
|
<summary>Public and Preshared Keys</summary>
|
||||||
|
<div class="form-group" style="margin-top: 1rem">
|
||||||
|
<label for="client_public_key" class="control-label">
|
||||||
|
Public Key
|
||||||
|
</label>
|
||||||
|
<input type="text" class="form-control" id="client_public_key" name="client_public_key" placeholder="Autogenerated (insecure)" aria-invalid="false">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="client_preshared_key" class="control-label">
|
||||||
|
Preshared Key
|
||||||
|
</label>
|
||||||
|
<input type="text" class="form-control" id="client_preshared_key" name="client_preshared_key" placeholder="Autogenerated">
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer justify-content-between">
|
<div class="modal-footer justify-content-between">
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
|
@ -314,9 +329,12 @@
|
||||||
if ($("#enabled").is(':checked')){
|
if ($("#enabled").is(':checked')){
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
const public_key = $("#client_public_key").val();
|
||||||
|
const preshared_key = $("#client_preshared_key").val();
|
||||||
|
|
||||||
const data = {"name": name, "email": email, "allocated_ips": allocated_ips, "allowed_ips": allowed_ips,
|
const data = {"name": name, "email": email, "allocated_ips": allocated_ips, "allowed_ips": allowed_ips,
|
||||||
"extra_allowed_ips": extra_allowed_ips, "use_server_dns": use_server_dns, "enabled": enabled};
|
"extra_allowed_ips": extra_allowed_ips, "use_server_dns": use_server_dns, "enabled": enabled,
|
||||||
|
"public_key": public_key, "preshared_key": preshared_key};
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
cache: false,
|
cache: false,
|
||||||
|
@ -434,6 +452,8 @@
|
||||||
$("#modal_new_client").on('shown.bs.modal', function (e) {
|
$("#modal_new_client").on('shown.bs.modal', function (e) {
|
||||||
$("#client_name").val("");
|
$("#client_name").val("");
|
||||||
$("#client_email").val("");
|
$("#client_email").val("");
|
||||||
|
$("#client_public_key").val("");
|
||||||
|
$("#client_preshared_key").val("");
|
||||||
$("#client_allocated_ips").importTags('');
|
$("#client_allocated_ips").importTags('');
|
||||||
$("#client_extra_allowed_ips").importTags('');
|
$("#client_extra_allowed_ips").importTags('');
|
||||||
updateIPAllocationSuggestion();
|
updateIPAllocationSuggestion();
|
||||||
|
|
Loading…
Add table
Reference in a new issue