mirror of
https://github.com/ngoduykhanh/wireguard-ui.git
synced 2025-04-18 19:49:30 +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">
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
||||
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 class="btn-group">
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
||||
|
|
|
@ -171,23 +171,51 @@ func NewClient(db store.IStore) echo.HandlerFunc {
|
|||
client.ID = guid.String()
|
||||
|
||||
// gen Wireguard key pair
|
||||
key, err := wgtypes.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
log.Error("Cannot generate wireguard key pair: ", err)
|
||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
|
||||
if client.PublicKey == "" {
|
||||
key, err := wgtypes.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
log.Error("Cannot generate wireguard key pair: ", err)
|
||||
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"})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
presharedKey, err := wgtypes.GenerateKey()
|
||||
if err != nil {
|
||||
log.Error("Cannot generated preshared key: ", err)
|
||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
|
||||
false, "Cannot generate Wireguard preshared key",
|
||||
})
|
||||
if client.PresharedKey == "" {
|
||||
presharedKey, err := wgtypes.GenerateKey()
|
||||
if err != nil {
|
||||
log.Error("Cannot generated preshared key: ", err)
|
||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
|
||||
false, "Cannot generate Wireguard preshared key",
|
||||
})
|
||||
}
|
||||
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.PrivateKey = key.String()
|
||||
client.PublicKey = key.PublicKey().String()
|
||||
client.PresharedKey = presharedKey.String()
|
||||
client.CreatedAt = time.Now().UTC()
|
||||
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)
|
||||
|
||||
cfg_att := emailer.Attachment{"wg0.conf", []byte(config)}
|
||||
qrdata, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(clientData.QRCode, "data:image/png;base64,"))
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "decoding: " + err.Error()})
|
||||
var attachments []emailer.Attachment
|
||||
if clientData.Client.PrivateKey != "" {
|
||||
qrdata, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(clientData.QRCode, "data:image/png;base64,"))
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "decoding: " + err.Error()})
|
||||
}
|
||||
qr_att := emailer.Attachment{"wg.png", qrdata}
|
||||
attachments = []emailer.Attachment{cfg_att, qr_att}
|
||||
} else {
|
||||
attachments = []emailer.Attachment{cfg_att}
|
||||
}
|
||||
qr_att := emailer.Attachment{"wg.png", qrdata}
|
||||
err = mailer.Send(
|
||||
clientData.Client.Name,
|
||||
payload.Email,
|
||||
emailSubject,
|
||||
emailContent,
|
||||
[]emailer.Attachment{cfg_att, qr_att},
|
||||
attachments,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
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
|
||||
if hasQRCode {
|
||||
if hasQRCode && client.PrivateKey != "" {
|
||||
server, _ := o.GetServer()
|
||||
globalSettings, _ := o.GetGlobalSettings()
|
||||
|
||||
|
@ -185,7 +185,7 @@ func (o *JsonDB) GetClientByID(clientID string, hasQRCode bool) (model.ClientDat
|
|||
}
|
||||
|
||||
// generate client qrcode image in base64
|
||||
if hasQRCode {
|
||||
if hasQRCode && client.PrivateKey != "" {
|
||||
server, _ := o.GetServer()
|
||||
globalSettings, _ := o.GetGlobalSettings()
|
||||
|
||||
|
|
|
@ -184,6 +184,21 @@
|
|||
</label>
|
||||
</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 class="modal-footer justify-content-between">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
|
@ -314,9 +329,12 @@
|
|||
if ($("#enabled").is(':checked')){
|
||||
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,
|
||||
"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({
|
||||
cache: false,
|
||||
|
@ -434,6 +452,8 @@
|
|||
$("#modal_new_client").on('shown.bs.modal', function (e) {
|
||||
$("#client_name").val("");
|
||||
$("#client_email").val("");
|
||||
$("#client_public_key").val("");
|
||||
$("#client_preshared_key").val("");
|
||||
$("#client_allocated_ips").importTags('');
|
||||
$("#client_extra_allowed_ips").importTags('');
|
||||
updateIPAllocationSuggestion();
|
||||
|
|
Loading…
Add table
Reference in a new issue