2022-09-15 02:44:43 +00:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
2023-04-25 06:34:16 +00:00
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
2022-09-15 02:44:43 +00:00
|
|
|
"encoding/json"
|
2023-04-25 06:34:16 +00:00
|
|
|
"encoding/pem"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
2023-07-27 07:52:25 +00:00
|
|
|
"path"
|
2022-09-16 08:00:49 +00:00
|
|
|
"strconv"
|
2023-04-25 06:34:16 +00:00
|
|
|
"strings"
|
2022-09-09 09:17:02 +00:00
|
|
|
"time"
|
2022-09-15 02:44:43 +00:00
|
|
|
|
2022-10-17 08:32:31 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
2023-03-07 10:20:52 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
2022-10-17 08:32:31 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
|
|
|
"github.com/1Panel-dev/1Panel/backend/global"
|
2023-01-29 08:38:34 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
2023-03-07 10:20:52 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
2022-10-17 08:32:31 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
2023-05-05 10:31:30 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
2023-05-22 09:45:39 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/ntp"
|
2023-04-25 06:34:16 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/ssl"
|
2022-09-08 10:47:15 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
2023-05-25 10:02:17 +00:00
|
|
|
"github.com/robfig/cron/v3"
|
2022-09-15 02:44:43 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type SettingService struct{}
|
|
|
|
|
|
|
|
type ISettingService interface {
|
|
|
|
GetSettingInfo() (*dto.SettingInfo, error)
|
2023-05-22 09:45:39 +00:00
|
|
|
LoadTimeZone() ([]string, error)
|
2023-02-10 10:07:29 +00:00
|
|
|
Update(key, value string) error
|
2022-09-08 10:47:15 +00:00
|
|
|
UpdatePassword(c *gin.Context, old, new string) error
|
2023-01-29 08:38:34 +00:00
|
|
|
UpdatePort(port uint) error
|
2023-04-25 06:34:16 +00:00
|
|
|
UpdateSSL(c *gin.Context, req dto.SSLUpdate) error
|
|
|
|
LoadFromCert() (*dto.SSLInfo, error)
|
2022-09-29 08:15:59 +00:00
|
|
|
HandlePasswordExpired(c *gin.Context, old, new string) error
|
2023-05-24 07:43:21 +00:00
|
|
|
SyncTime(req dto.SyncTime) error
|
2023-09-28 07:40:17 +00:00
|
|
|
|
|
|
|
SystemScan() dto.CleanData
|
|
|
|
SystemClean(req []dto.Clean)
|
2022-09-15 02:44:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewISettingService() ISettingService {
|
|
|
|
return &SettingService{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) {
|
2022-09-08 10:47:15 +00:00
|
|
|
setting, err := settingRepo.GetList()
|
2022-09-15 02:44:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, constant.ErrRecordNotFound
|
|
|
|
}
|
|
|
|
settingMap := make(map[string]string)
|
|
|
|
for _, set := range setting {
|
|
|
|
settingMap[set.Key] = set.Value
|
|
|
|
}
|
|
|
|
var info dto.SettingInfo
|
|
|
|
arr, err := json.Marshal(settingMap)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-12-22 10:06:49 +00:00
|
|
|
if err := json.Unmarshal(arr, &info); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-12-28 10:35:53 +00:00
|
|
|
info.LocalTime = time.Now().Format("2006-01-02 15:04:05 MST -0700")
|
2022-09-15 02:44:43 +00:00
|
|
|
return &info, err
|
|
|
|
}
|
|
|
|
|
2023-05-22 09:45:39 +00:00
|
|
|
func (u *SettingService) LoadTimeZone() ([]string, error) {
|
|
|
|
std, err := cmd.Exec("timedatectl list-timezones")
|
|
|
|
if err != nil {
|
|
|
|
return []string{}, nil
|
|
|
|
}
|
|
|
|
return strings.Split(std, "\n"), err
|
|
|
|
}
|
|
|
|
|
2023-02-10 10:07:29 +00:00
|
|
|
func (u *SettingService) Update(key, value string) error {
|
2023-05-25 10:02:17 +00:00
|
|
|
switch key {
|
|
|
|
case "MonitorStatus":
|
|
|
|
if value == "enable" && global.MonitorCronID == 0 {
|
|
|
|
interval, err := settingRepo.Get(settingRepo.WithByKey("MonitorInterval"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := StartMonitor(false, interval.Value); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if value == "disable" && global.MonitorCronID != 0 {
|
2023-10-10 09:30:28 +00:00
|
|
|
monitorCancel()
|
2023-05-25 10:02:17 +00:00
|
|
|
global.Cron.Remove(cron.EntryID(global.MonitorCronID))
|
|
|
|
global.MonitorCronID = 0
|
|
|
|
}
|
|
|
|
case "MonitorInterval":
|
|
|
|
status, err := settingRepo.Get(settingRepo.WithByKey("MonitorStatus"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if status.Value == "enable" && global.MonitorCronID != 0 {
|
|
|
|
if err := StartMonitor(true, value); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case "TimeZone":
|
|
|
|
if err := ntp.UpdateSystemTimeZone(value); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-08-28 08:18:13 +00:00
|
|
|
case "AppStoreLastModified":
|
|
|
|
exist, _ := settingRepo.Get(settingRepo.WithByKey("AppStoreLastModified"))
|
|
|
|
if exist.ID == 0 {
|
|
|
|
_ = settingRepo.Create("AppStoreLastModified", value)
|
|
|
|
return nil
|
|
|
|
}
|
2023-05-25 10:02:17 +00:00
|
|
|
}
|
|
|
|
|
2023-05-24 07:43:21 +00:00
|
|
|
if err := settingRepo.Update(key, value); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-05-25 10:02:17 +00:00
|
|
|
|
2023-05-24 07:43:21 +00:00
|
|
|
switch key {
|
|
|
|
case "ExpirationDays":
|
2022-09-29 08:15:59 +00:00
|
|
|
timeout, _ := strconv.Atoi(value)
|
2022-12-02 02:23:35 +00:00
|
|
|
if err := settingRepo.Update("ExpirationTime", time.Now().AddDate(0, 0, timeout).Format("2006-01-02 15:04:05")); err != nil {
|
2022-09-29 08:15:59 +00:00
|
|
|
return err
|
|
|
|
}
|
2023-05-24 07:43:21 +00:00
|
|
|
case "TimeZone":
|
|
|
|
go func() {
|
|
|
|
_, err := cmd.Exec("systemctl restart 1panel.service")
|
|
|
|
if err != nil {
|
|
|
|
global.LOG.Errorf("restart system for new time zone failed, err: %v", err)
|
|
|
|
}
|
|
|
|
}()
|
2023-06-05 05:47:21 +00:00
|
|
|
case "BindDomain":
|
|
|
|
if len(value) != 0 {
|
|
|
|
_ = global.SESSION.Clean()
|
|
|
|
}
|
2023-05-24 07:43:21 +00:00
|
|
|
case "UserName", "Password":
|
2023-03-11 03:33:21 +00:00
|
|
|
_ = global.SESSION.Clean()
|
2023-08-28 08:18:13 +00:00
|
|
|
|
2023-03-11 03:33:21 +00:00
|
|
|
}
|
2023-05-24 07:43:21 +00:00
|
|
|
|
2022-09-29 08:15:59 +00:00
|
|
|
return nil
|
2022-09-15 02:44:43 +00:00
|
|
|
}
|
2022-09-08 10:47:15 +00:00
|
|
|
|
2023-05-24 07:43:21 +00:00
|
|
|
func (u *SettingService) SyncTime(req dto.SyncTime) error {
|
|
|
|
if err := settingRepo.Update("NtpSite", req.NtpSite); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-05-22 09:45:39 +00:00
|
|
|
ntime, err := ntp.GetRemoteTime(req.NtpSite)
|
|
|
|
if err != nil {
|
2023-05-24 07:43:21 +00:00
|
|
|
return err
|
2023-05-22 09:45:39 +00:00
|
|
|
}
|
|
|
|
ts := ntime.Format("2006-01-02 15:04:05")
|
2023-05-24 07:43:21 +00:00
|
|
|
if err := ntp.UpdateSystemTime(ts); err != nil {
|
|
|
|
return err
|
2023-05-22 09:45:39 +00:00
|
|
|
}
|
2023-05-24 07:43:21 +00:00
|
|
|
return nil
|
2023-05-22 09:45:39 +00:00
|
|
|
}
|
|
|
|
|
2023-01-29 08:38:34 +00:00
|
|
|
func (u *SettingService) UpdatePort(port uint) error {
|
2023-03-07 10:20:52 +00:00
|
|
|
if common.ScanPort(int(port)) {
|
|
|
|
return buserr.WithDetail(constant.ErrPortInUsed, port, nil)
|
|
|
|
}
|
2023-03-31 16:51:25 +00:00
|
|
|
serverPort, err := settingRepo.Get(settingRepo.WithByKey("ServerPort"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
portValue, _ := strconv.Atoi(serverPort.Value)
|
|
|
|
if err := OperateFirewallPort([]int{portValue}, []int{int(port)}); err != nil {
|
|
|
|
global.LOG.Errorf("set system firewall ports failed, err: %v", err)
|
|
|
|
}
|
2023-02-02 07:01:37 +00:00
|
|
|
if err := settingRepo.Update("ServerPort", strconv.Itoa(int(port))); err != nil {
|
2023-01-29 08:38:34 +00:00
|
|
|
return err
|
|
|
|
}
|
2023-02-02 07:01:37 +00:00
|
|
|
go func() {
|
|
|
|
_, err := cmd.Exec("systemctl restart 1panel.service")
|
|
|
|
if err != nil {
|
2023-02-05 15:48:37 +00:00
|
|
|
global.LOG.Errorf("restart system port failed, err: %v", err)
|
2023-02-02 07:01:37 +00:00
|
|
|
}
|
|
|
|
}()
|
2023-01-29 08:38:34 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-04-25 06:34:16 +00:00
|
|
|
func (u *SettingService) UpdateSSL(c *gin.Context, req dto.SSLUpdate) error {
|
2023-08-09 03:18:12 +00:00
|
|
|
secretDir := path.Join(global.CONF.System.BaseDir, "1panel/secret")
|
2023-04-25 06:34:16 +00:00
|
|
|
if req.SSL == "disable" {
|
|
|
|
if err := settingRepo.Update("SSL", "disable"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := settingRepo.Update("SSLType", "self"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-08-09 03:18:12 +00:00
|
|
|
_ = os.Remove(path.Join(secretDir, "server.crt"))
|
|
|
|
_ = os.Remove(path.Join(secretDir, "server.key"))
|
2023-04-25 06:34:16 +00:00
|
|
|
go func() {
|
|
|
|
_, err := cmd.Exec("systemctl restart 1panel.service")
|
|
|
|
if err != nil {
|
|
|
|
global.LOG.Errorf("restart system failed, err: %v", err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-05-05 10:31:30 +00:00
|
|
|
if _, err := os.Stat(secretDir); err != nil && os.IsNotExist(err) {
|
|
|
|
if err = os.MkdirAll(secretDir, os.ModePerm); err != nil {
|
2023-04-25 06:34:16 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err := settingRepo.Update("SSLType", req.SSLType); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if req.SSLType == "self" {
|
|
|
|
if len(req.Domain) == 0 {
|
|
|
|
return fmt.Errorf("load domain failed")
|
|
|
|
}
|
|
|
|
if err := ssl.GenerateSSL(req.Domain); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if req.SSLType == "select" {
|
|
|
|
sslInfo, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(req.SSLID))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
req.Cert = sslInfo.Pem
|
|
|
|
req.Key = sslInfo.PrivateKey
|
|
|
|
req.SSLType = "import"
|
|
|
|
if err := settingRepo.Update("SSLID", strconv.Itoa(int(req.SSLID))); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if req.SSLType == "import" {
|
2023-08-09 03:18:12 +00:00
|
|
|
cert, err := os.OpenFile(path.Join(secretDir, "server.crt.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
2023-04-25 06:34:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer cert.Close()
|
|
|
|
if _, err := cert.WriteString(req.Cert); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-08-09 03:18:12 +00:00
|
|
|
key, err := os.OpenFile(path.Join(secretDir, "server.key.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
2023-04-25 06:34:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if _, err := key.WriteString(req.Key); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer key.Close()
|
|
|
|
}
|
|
|
|
if err := checkCertValid(req.Domain); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-05-05 10:31:30 +00:00
|
|
|
|
|
|
|
fileOp := files.NewFileOp()
|
2023-08-09 03:18:12 +00:00
|
|
|
if err := fileOp.Rename(path.Join(secretDir, "server.crt.tmp"), path.Join(secretDir, "server.crt")); err != nil {
|
2023-05-05 10:31:30 +00:00
|
|
|
return err
|
|
|
|
}
|
2023-08-09 03:18:12 +00:00
|
|
|
if err := fileOp.Rename(path.Join(secretDir, "server.key.tmp"), path.Join(secretDir, "server.key")); err != nil {
|
2023-05-05 10:31:30 +00:00
|
|
|
return err
|
|
|
|
}
|
2023-04-25 06:34:16 +00:00
|
|
|
if err := settingRepo.Update("SSL", req.SSL); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
go func() {
|
|
|
|
_, err := cmd.Exec("systemctl restart 1panel.service")
|
|
|
|
if err != nil {
|
|
|
|
global.LOG.Errorf("restart system failed, err: %v", err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *SettingService) LoadFromCert() (*dto.SSLInfo, error) {
|
|
|
|
ssl, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if ssl.Value == "disable" {
|
|
|
|
return &dto.SSLInfo{}, nil
|
|
|
|
}
|
|
|
|
sslType, err := settingRepo.Get(settingRepo.WithByKey("SSLType"))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
data, err := loadInfoFromCert()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
switch sslType.Value {
|
|
|
|
case "import":
|
2023-07-27 07:52:25 +00:00
|
|
|
if _, err := os.Stat(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt")); err != nil {
|
2023-04-25 06:34:16 +00:00
|
|
|
return nil, fmt.Errorf("load server.crt file failed, err: %v", err)
|
|
|
|
}
|
2023-07-27 07:52:25 +00:00
|
|
|
certFile, _ := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt"))
|
2023-04-25 06:34:16 +00:00
|
|
|
data.Cert = string(certFile)
|
|
|
|
|
2023-07-27 07:52:25 +00:00
|
|
|
if _, err := os.Stat(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key")); err != nil {
|
2023-04-25 06:34:16 +00:00
|
|
|
return nil, fmt.Errorf("load server.key file failed, err: %v", err)
|
|
|
|
}
|
2023-07-27 07:52:25 +00:00
|
|
|
keyFile, _ := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key"))
|
2023-04-25 06:34:16 +00:00
|
|
|
data.Key = string(keyFile)
|
|
|
|
case "select":
|
|
|
|
sslID, err := settingRepo.Get(settingRepo.WithByKey("SSLID"))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
id, _ := strconv.Atoi(sslID.Value)
|
|
|
|
data.SSLID = uint(id)
|
|
|
|
}
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
2022-09-29 08:15:59 +00:00
|
|
|
func (u *SettingService) HandlePasswordExpired(c *gin.Context, old, new string) error {
|
2022-09-08 10:47:15 +00:00
|
|
|
setting, err := settingRepo.Get(settingRepo.WithByKey("Password"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
passwordFromDB, err := encrypt.StringDecrypt(setting.Value)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if passwordFromDB == old {
|
|
|
|
newPassword, err := encrypt.StringEncrypt(new)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := settingRepo.Update("Password", newPassword); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-09-29 08:15:59 +00:00
|
|
|
|
|
|
|
expiredSetting, err := settingRepo.Get(settingRepo.WithByKey("ExpirationDays"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
timeout, _ := strconv.Atoi(expiredSetting.Value)
|
2022-12-02 02:23:35 +00:00
|
|
|
if err := settingRepo.Update("ExpirationTime", time.Now().AddDate(0, 0, timeout).Format("2006-01-02 15:04:05")); err != nil {
|
2022-09-29 08:15:59 +00:00
|
|
|
return err
|
2022-09-08 10:47:15 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return constant.ErrInitialPassword
|
|
|
|
}
|
2022-09-29 08:15:59 +00:00
|
|
|
|
|
|
|
func (u *SettingService) UpdatePassword(c *gin.Context, old, new string) error {
|
|
|
|
if err := u.HandlePasswordExpired(c, old, new); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-03-11 03:33:21 +00:00
|
|
|
_ = global.SESSION.Clean()
|
2022-09-29 08:15:59 +00:00
|
|
|
return nil
|
|
|
|
}
|
2023-04-25 06:34:16 +00:00
|
|
|
|
|
|
|
func loadInfoFromCert() (*dto.SSLInfo, error) {
|
|
|
|
var info dto.SSLInfo
|
2023-07-27 07:52:25 +00:00
|
|
|
certFile := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt")
|
2023-04-25 06:34:16 +00:00
|
|
|
if _, err := os.Stat(certFile); err != nil {
|
|
|
|
return &info, err
|
|
|
|
}
|
|
|
|
certData, err := os.ReadFile(certFile)
|
|
|
|
if err != nil {
|
|
|
|
return &info, err
|
|
|
|
}
|
|
|
|
certBlock, _ := pem.Decode(certData)
|
|
|
|
if certBlock == nil {
|
|
|
|
return &info, err
|
|
|
|
}
|
|
|
|
certObj, err := x509.ParseCertificate(certBlock.Bytes)
|
|
|
|
if err != nil {
|
|
|
|
return &info, err
|
|
|
|
}
|
|
|
|
var domains []string
|
|
|
|
if len(certObj.IPAddresses) != 0 {
|
|
|
|
for _, ip := range certObj.IPAddresses {
|
|
|
|
domains = append(domains, ip.String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(certObj.DNSNames) != 0 {
|
|
|
|
domains = append(domains, certObj.DNSNames...)
|
|
|
|
}
|
|
|
|
return &dto.SSLInfo{
|
|
|
|
Domain: strings.Join(domains, ","),
|
|
|
|
Timeout: certObj.NotAfter.Format("2006-01-02 15:04:05"),
|
2023-08-02 14:36:37 +00:00
|
|
|
RootPath: path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt"),
|
2023-04-25 06:34:16 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkCertValid(domain string) error {
|
2023-07-27 07:52:25 +00:00
|
|
|
certificate, err := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt.tmp"))
|
2023-04-25 06:34:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-07-27 07:52:25 +00:00
|
|
|
key, err := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key.tmp"))
|
2023-04-25 06:34:16 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if _, err = tls.X509KeyPair(certificate, key); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-04-26 00:04:10 +00:00
|
|
|
certBlock, _ := pem.Decode(certificate)
|
|
|
|
if certBlock == nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-05-05 10:31:30 +00:00
|
|
|
if _, err := x509.ParseCertificate(certBlock.Bytes); err != nil {
|
2023-04-25 06:34:16 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-05-05 10:31:30 +00:00
|
|
|
return nil
|
2023-04-25 06:34:16 +00:00
|
|
|
}
|