mirror of
https://github.com/putyy/res-downloader.git
synced 2026-01-12 06:04:55 +08:00
perf: Install certificates and optimize proxy settings
This commit is contained in:
72
core/aes.go
Normal file
72
core/aes.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
type AESCipher struct {
|
||||
key []byte
|
||||
}
|
||||
|
||||
func NewAESCipher(key string) *AESCipher {
|
||||
return &AESCipher{key: []byte(key)}
|
||||
}
|
||||
|
||||
func (a *AESCipher) Encrypt(plainText string) (string, error) {
|
||||
block, err := aes.NewCipher(a.key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
padding := block.BlockSize() - len(plainText)%block.BlockSize()
|
||||
padText := bytes.Repeat([]byte{byte(padding)}, padding)
|
||||
plainText = plainText + string(padText)
|
||||
|
||||
cipherText := make([]byte, aes.BlockSize+len(plainText))
|
||||
iv := cipherText[:aes.BlockSize]
|
||||
|
||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(cipherText[aes.BlockSize:], []byte(plainText))
|
||||
|
||||
return base64.StdEncoding.EncodeToString(cipherText), nil
|
||||
}
|
||||
|
||||
func (a *AESCipher) Decrypt(cipherText string) (string, error) {
|
||||
cipherTextBytes, err := base64.StdEncoding.DecodeString(cipherText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(a.key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(cipherTextBytes) < aes.BlockSize {
|
||||
return "", errors.New("ciphertext too short")
|
||||
}
|
||||
|
||||
iv := cipherTextBytes[:aes.BlockSize]
|
||||
cipherTextBytes = cipherTextBytes[aes.BlockSize:]
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(cipherTextBytes, cipherTextBytes)
|
||||
|
||||
padding := int(cipherTextBytes[len(cipherTextBytes)-1])
|
||||
if padding > len(cipherTextBytes) || padding > aes.BlockSize {
|
||||
return "", errors.New("padding size error")
|
||||
}
|
||||
plainText := cipherTextBytes[:len(cipherTextBytes)-padding]
|
||||
|
||||
return string(plainText), nil
|
||||
}
|
||||
45
core/app.go
45
core/app.go
@@ -3,14 +3,12 @@ package core
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"github.com/vrischmann/userdir"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
sysRuntime "runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -109,6 +107,10 @@ ILKEQKmPPzKs7kp/7Nz+2cT3
|
||||
`),
|
||||
}
|
||||
appOnce.UserDir = filepath.Join(userdir.GetConfigHome(), appOnce.AppName)
|
||||
err := os.MkdirAll(appOnce.UserDir, 0750)
|
||||
if err != nil {
|
||||
fmt.Println("Mkdir UserDir err: ", err.Error())
|
||||
}
|
||||
appOnce.LockFile = filepath.Join(appOnce.UserDir, "install.lock")
|
||||
initLogger()
|
||||
initConfig()
|
||||
@@ -123,22 +125,6 @@ ILKEQKmPPzKs7kp/7Nz+2cT3
|
||||
func (a *App) Startup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
go httpServerOnce.run()
|
||||
time.AfterFunc(200*time.Millisecond, func() {
|
||||
if globalConfig.AutoProxy {
|
||||
appOnce.OpenSystemProxy()
|
||||
}
|
||||
})
|
||||
|
||||
go func() {
|
||||
if a.isInstall() {
|
||||
return
|
||||
}
|
||||
err := os.MkdirAll(a.UserDir, 0750)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
a.installCert()
|
||||
}()
|
||||
}
|
||||
|
||||
func (a *App) OnExit() {
|
||||
@@ -146,24 +132,17 @@ func (a *App) OnExit() {
|
||||
globalLogger.Close()
|
||||
}
|
||||
|
||||
func (a *App) installCert() {
|
||||
if res, err := systemOnce.installCert(); err != nil {
|
||||
if sysRuntime.GOOS == "darwin" {
|
||||
_ = runtime.ClipboardSetText(appOnce.ctx, `echo "输入本地登录密码" && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "`+systemOnce.CertFile+`" && touch `+a.LockFile+` && echo "安装完成"`)
|
||||
DialogErr("证书安装失败,请打开终端执行安装(命令已复制到剪切板),err:" + err.Error() + ", " + res)
|
||||
} else if sysRuntime.GOOS == "windows" && strings.Contains(err.Error(), "Access is denied.") {
|
||||
DialogErr("首次启用本软件,请使用鼠标右键选择以管理员身份运行")
|
||||
} else if sysRuntime.GOOS == "linux" && strings.Contains(err.Error(), "Access is denied.") {
|
||||
DialogErr("证书路径: " + systemOnce.CertFile + ", 请手动安装,安装完成后请执行: touch" + a.LockFile + " err:" + err.Error() + ", " + res)
|
||||
} else {
|
||||
globalLogger.Esg(err, res)
|
||||
DialogErr("err:" + err.Error() + ", " + res)
|
||||
}
|
||||
func (a *App) installCert() (string, error) {
|
||||
out, err := systemOnce.installCert()
|
||||
if err != nil {
|
||||
globalLogger.Esg(err, out)
|
||||
return out, err
|
||||
} else {
|
||||
if err := a.lock(); err != nil {
|
||||
globalLogger.err(err)
|
||||
globalLogger.Err(err)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (a *App) OpenSystemProxy() error {
|
||||
|
||||
56
core/http.go
56
core/http.go
@@ -37,10 +37,11 @@ func initHttpServer() *HttpServer {
|
||||
func (h *HttpServer) run() {
|
||||
listener, err := net.Listen("tcp", globalConfig.Host+":"+globalConfig.Port)
|
||||
if err != nil {
|
||||
log.Fatalf("无法启动监听: %v", err)
|
||||
globalLogger.Err(err)
|
||||
log.Fatalf("Service cannot start: %v", err)
|
||||
}
|
||||
fmt.Println("服务已启动,监听 http://" + globalConfig.Host + ":" + globalConfig.Port)
|
||||
if err := http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("Service started, listening http://" + globalConfig.Host + ":" + globalConfig.Port)
|
||||
if err1 := http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Host == "127.0.0.1:"+globalConfig.Port && strings.Contains(r.URL.Path, "/cert") {
|
||||
w.Header().Set("Content-Type", "application/x-x509-ca-data")
|
||||
w.Header().Set("Content-Disposition", "attachment;filename=res-downloader-public.crt")
|
||||
@@ -51,8 +52,9 @@ func (h *HttpServer) run() {
|
||||
} else {
|
||||
proxyOnce.Proxy.ServeHTTP(w, r) // 代理
|
||||
}
|
||||
})); err != nil {
|
||||
fmt.Printf("服务器异常: %v", err)
|
||||
})); err1 != nil {
|
||||
globalLogger.Err(err1)
|
||||
fmt.Printf("Service startup exception: %v", err1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +120,7 @@ func (h *HttpServer) writeJson(w http.ResponseWriter, data ResponseData) {
|
||||
w.WriteHeader(200)
|
||||
err := json.NewEncoder(w).Encode(data)
|
||||
if err != nil {
|
||||
globalLogger.err(err)
|
||||
globalLogger.Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,14 +208,10 @@ func (h *HttpServer) openFolder(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
switch sysRuntime.GOOS {
|
||||
case "darwin":
|
||||
// macOS
|
||||
cmd = exec.Command("open", "-R", filePath)
|
||||
case "windows":
|
||||
// Windows
|
||||
cmd = exec.Command("explorer", "/select,", filePath)
|
||||
case "linux":
|
||||
// linux
|
||||
// 尝试使用不同的文件管理器
|
||||
cmd = exec.Command("nautilus", filePath)
|
||||
if err := cmd.Start(); err != nil {
|
||||
cmd = exec.Command("thunar", filePath)
|
||||
@@ -222,7 +220,7 @@ func (h *HttpServer) openFolder(w http.ResponseWriter, r *http.Request) {
|
||||
if err := cmd.Start(); err != nil {
|
||||
cmd = exec.Command("pcmanfm", filePath)
|
||||
if err := cmd.Start(); err != nil {
|
||||
globalLogger.err(err)
|
||||
globalLogger.Err(err)
|
||||
h.error(w, err.Error())
|
||||
return
|
||||
}
|
||||
@@ -236,23 +234,45 @@ func (h *HttpServer) openFolder(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
globalLogger.err(err)
|
||||
globalLogger.Err(err)
|
||||
h.error(w, err.Error())
|
||||
return
|
||||
}
|
||||
h.success(w)
|
||||
}
|
||||
|
||||
func (h *HttpServer) install(w http.ResponseWriter, r *http.Request) {
|
||||
if appOnce.isInstall() {
|
||||
h.success(w, respData{
|
||||
"isPass": systemOnce.Password == "",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
out, err := appOnce.installCert()
|
||||
if err != nil {
|
||||
h.error(w, err.Error()+"\n"+out, respData{
|
||||
"isPass": systemOnce.Password == "",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
h.success(w, respData{
|
||||
"isPass": systemOnce.Password == "",
|
||||
})
|
||||
}
|
||||
|
||||
func (h *HttpServer) setSystemPassword(w http.ResponseWriter, r *http.Request) {
|
||||
var data struct {
|
||||
Password string `json:"password"`
|
||||
IsCache bool `json:"isCache"`
|
||||
}
|
||||
err := json.NewDecoder(r.Body).Decode(&data)
|
||||
if err != nil {
|
||||
h.error(w, err.Error())
|
||||
return
|
||||
}
|
||||
systemOnce.SetPassword(data.Password)
|
||||
systemOnce.SetPassword(data.Password, data.IsCache)
|
||||
h.success(w)
|
||||
}
|
||||
|
||||
@@ -260,12 +280,12 @@ func (h *HttpServer) openSystemProxy(w http.ResponseWriter, r *http.Request) {
|
||||
err := appOnce.OpenSystemProxy()
|
||||
if err != nil {
|
||||
h.error(w, err.Error(), respData{
|
||||
"isProxy": appOnce.IsProxy,
|
||||
"value": appOnce.IsProxy,
|
||||
})
|
||||
return
|
||||
}
|
||||
h.success(w, respData{
|
||||
"isProxy": appOnce.IsProxy,
|
||||
"value": appOnce.IsProxy,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -273,18 +293,18 @@ func (h *HttpServer) unsetSystemProxy(w http.ResponseWriter, r *http.Request) {
|
||||
err := appOnce.UnsetSystemProxy()
|
||||
if err != nil {
|
||||
h.error(w, err.Error(), respData{
|
||||
"isProxy": appOnce.IsProxy,
|
||||
"value": appOnce.IsProxy,
|
||||
})
|
||||
return
|
||||
}
|
||||
h.success(w, respData{
|
||||
"isProxy": appOnce.IsProxy,
|
||||
"value": appOnce.IsProxy,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *HttpServer) isProxy(w http.ResponseWriter, r *http.Request) {
|
||||
h.success(w, respData{
|
||||
"isProxy": appOnce.IsProxy,
|
||||
"value": appOnce.IsProxy,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ func (l *Logger) Close() {
|
||||
_ = l.logFile.Close()
|
||||
}
|
||||
|
||||
func (l *Logger) err(err error) {
|
||||
func (l *Logger) Err(err error) {
|
||||
l.Error().Stack().Err(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,12 @@ func HandleApi(w http.ResponseWriter, r *http.Request) bool {
|
||||
return true
|
||||
}
|
||||
switch r.URL.Path {
|
||||
case "/api/preview":
|
||||
httpServerOnce.preview(w, r)
|
||||
case "/api/install":
|
||||
httpServerOnce.install(w, r)
|
||||
case "/api/set-system-password":
|
||||
httpServerOnce.setSystemPassword(w, r)
|
||||
case "/api/preview":
|
||||
httpServerOnce.preview(w, r)
|
||||
case "/api/proxy-open":
|
||||
httpServerOnce.openSystemProxy(w, r)
|
||||
case "/api/proxy-unset":
|
||||
|
||||
@@ -7,8 +7,6 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/elazarl/goproxy"
|
||||
gonanoid "github.com/matoous/go-nanoid/v2"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -17,6 +15,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
gonanoid "github.com/matoous/go-nanoid/v2"
|
||||
)
|
||||
|
||||
type Proxy struct {
|
||||
@@ -221,16 +222,16 @@ func (p *Proxy) handleWechatRequest(r *http.Request, ctx *goproxy.ProxyCtx) (*ht
|
||||
}
|
||||
|
||||
func (p *Proxy) buildEmptyResponse(r *http.Request) *http.Response {
|
||||
body := "内容不存在"
|
||||
body := "The content does not exist"
|
||||
resp := &http.Response{
|
||||
Status: "200 OK",
|
||||
Status: http.StatusText(http.StatusOK),
|
||||
StatusCode: http.StatusOK,
|
||||
Header: make(http.Header),
|
||||
Body: io.NopCloser(strings.NewReader(body)),
|
||||
ContentLength: int64(len(body)),
|
||||
Request: r,
|
||||
}
|
||||
resp.Header.Set("Content-Type", "text/plain")
|
||||
resp.Header.Set("Content-Type", "text/plain; charset=utf-8")
|
||||
return resp
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SystemSetup struct {
|
||||
CertFile string
|
||||
Password string
|
||||
CertFile string
|
||||
CacheFile string
|
||||
Password string
|
||||
aesCipher *AESCipher
|
||||
}
|
||||
|
||||
func initSystem() *SystemSetup {
|
||||
if systemOnce == nil {
|
||||
systemOnce = &SystemSetup{
|
||||
CertFile: filepath.Join(appOnce.UserDir, "cert.crt"),
|
||||
aesCipher: NewAESCipher("resd48w2d7er95627d447c490a8f02ff"),
|
||||
CertFile: filepath.Join(appOnce.UserDir, "cert.crt"),
|
||||
CacheFile: filepath.Join(appOnce.UserDir, "pass.cache"),
|
||||
}
|
||||
systemOnce.checkPasswordFile()
|
||||
}
|
||||
return systemOnce
|
||||
}
|
||||
@@ -35,6 +42,42 @@ func (s *SystemSetup) initCert() ([]byte, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SystemSetup) SetPassword(password string) {
|
||||
func (s *SystemSetup) SetPassword(password string, isCache bool) {
|
||||
s.Password = password
|
||||
if isCache {
|
||||
encrypted, err := s.aesCipher.Encrypt(password)
|
||||
if err == nil {
|
||||
err1 := os.WriteFile(s.CacheFile, []byte(encrypted), 0750)
|
||||
if err1 != nil {
|
||||
fmt.Println("Failed to write password: ", err1.Error())
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Failed to Encrypt password: ", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SystemSetup) checkPasswordFile() {
|
||||
fileInfo, err := os.Stat(s.CacheFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
lastModified := fileInfo.ModTime()
|
||||
oneMonthAgo := time.Now().AddDate(0, -1, 0)
|
||||
if lastModified.Before(oneMonthAgo) {
|
||||
os.Remove(s.CacheFile)
|
||||
return
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(s.CacheFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
password, err := s.aesCipher.Decrypt(string(content))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s.Password = password
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func (s *SystemSetup) setProxy() error {
|
||||
}
|
||||
for _, args := range cmds {
|
||||
if output, err := s.runCommand(args); err != nil {
|
||||
errs = errs + "\n output:" + string(output) + "err:" + err.Error()
|
||||
errs = errs + "output:" + string(output) + " err:" + err.Error() + "\n"
|
||||
fmt.Println("setProxy:", output, " err:", err.Error())
|
||||
} else {
|
||||
is = true
|
||||
@@ -85,7 +85,7 @@ func (s *SystemSetup) setProxy() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("failed to set proxy for any active network service, errs: %s", errs)
|
||||
return fmt.Errorf("failed to set proxy for any active network service, errs:%s", errs)
|
||||
}
|
||||
|
||||
func (s *SystemSetup) unsetProxy() error {
|
||||
@@ -103,7 +103,7 @@ func (s *SystemSetup) unsetProxy() error {
|
||||
}
|
||||
for _, args := range cmds {
|
||||
if output, err := s.runCommand(args); err != nil {
|
||||
errs = errs + "\n output:" + string(output) + "err:" + err.Error()
|
||||
errs = errs + "output:" + string(output) + " err:" + err.Error() + "\n"
|
||||
fmt.Println("unsetProxy:", output, " err:", err.Error())
|
||||
} else {
|
||||
is = true
|
||||
@@ -115,7 +115,7 @@ func (s *SystemSetup) unsetProxy() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("failed to unset proxy for any active network service, errs: %s", errs)
|
||||
return fmt.Errorf("failed to unset proxy for any active network service, errs:%s", errs)
|
||||
}
|
||||
|
||||
func (s *SystemSetup) installCert() (string, error) {
|
||||
@@ -123,19 +123,7 @@ func (s *SystemSetup) installCert() (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
getPasswordCmd := exec.Command("osascript", "-e", `tell app "System Events" to display dialog "请输入你的电脑密码,用于安装证书文件:" default answer "" with hidden answer`, "-e", `text returned of result`)
|
||||
passwordOutput, err := getPasswordCmd.Output()
|
||||
if err != nil {
|
||||
return string(passwordOutput), err
|
||||
}
|
||||
|
||||
password := strings.TrimSpace(string(passwordOutput))
|
||||
s.SetPassword(password)
|
||||
|
||||
cmd := exec.Command("sudo", "-S", "security", "add-trusted-cert", "-d", "-r", "trustRoot", "-k", "/Library/Keychains/System.keychain", s.CertFile)
|
||||
cmd.Stdin = bytes.NewReader([]byte(password + "\n"))
|
||||
output, err := cmd.CombinedOutput()
|
||||
output, err := s.runCommand([]string{"sudo", "-S", "security", "add-trusted-cert", "-d", "-r", "trustRoot", "-k", "/Library/Keychains/System.keychain", s.CertFile})
|
||||
if err != nil {
|
||||
return string(output), err
|
||||
}
|
||||
|
||||
@@ -3,10 +3,28 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func (s *SystemSetup) runCommand(args []string) ([]byte, error) {
|
||||
if len(args) == 0 {
|
||||
return nil, fmt.Errorf("no command provided")
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
if s.Password != "" {
|
||||
cmd = exec.Command("sudo", append([]string{"-S"}, args...)...)
|
||||
cmd.Stdin = bytes.NewReader([]byte(s.Password + "\n"))
|
||||
} else {
|
||||
cmd = exec.Command(args[0], args[1:]...)
|
||||
}
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
return output, err
|
||||
}
|
||||
|
||||
func (s *SystemSetup) setProxy() error {
|
||||
commands := [][]string{
|
||||
{"gsettings", "set", "org.gnome.system.proxy", "mode", "manual"},
|
||||
@@ -16,8 +34,10 @@ func (s *SystemSetup) setProxy() error {
|
||||
{"gsettings", "set", "org.gnome.system.proxy.https", "port", globalConfig.Port},
|
||||
}
|
||||
is := false
|
||||
errs := ""
|
||||
for _, cmd := range commands {
|
||||
if err := exec.Command(cmd[0], cmd[1:]...).Run(); err != nil {
|
||||
if output, err := s.runCommand(cmd); err != nil {
|
||||
errs = errs + "output:" + string(output) + " err:" + err.Error() + "\n"
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
is = true
|
||||
@@ -26,12 +46,14 @@ func (s *SystemSetup) setProxy() error {
|
||||
if is {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Failed to activate proxy")
|
||||
|
||||
return fmt.Errorf("failed to set proxy for any active network service, errs:%s", errs)
|
||||
}
|
||||
|
||||
func (s *SystemSetup) unsetProxy() error {
|
||||
cmd := []string{"gsettings", "set", "org.gnome.system.proxy", "mode", "none"}
|
||||
return exec.Command(cmd[0], cmd[1:]...).Run()
|
||||
output, err := s.runCommand(cmd)
|
||||
return fmt.Errorf("failed to unset proxy for any active network service, errs output:" + string(output) + " err:" + err.Error())
|
||||
}
|
||||
|
||||
func (s *SystemSetup) installCert() (string, error) {
|
||||
@@ -41,34 +63,34 @@ func (s *SystemSetup) installCert() (string, error) {
|
||||
}
|
||||
|
||||
actions := [][]string{
|
||||
{"/usr/local/share/ca-certificates/", "update-ca-certificates"},
|
||||
{"/usr/share/ca-certificates/trust-source/anchors/", "update-ca-trust"},
|
||||
{"/usr/share/ca-certificates/trust-source/anchors/", "trust extract-compat"},
|
||||
{"/etc/pki/ca-trust/source/anchors/", "update-ca-trust"},
|
||||
{"/etc/ssl/ca-certificates/", "update-ca-certificates"},
|
||||
{"cp", "-f", s.CertFile, "/usr/local/share/ca-certificates/" + appOnce.AppName + ".crt"},
|
||||
{"update-ca-certificates"},
|
||||
{"cp", "-f", s.CertFile, "/usr/share/ca-certificates/trust-source/anchors/" + appOnce.AppName + ".crt"},
|
||||
{"update-ca-trust"},
|
||||
{"trust", "extract-compat"},
|
||||
{"cp", "-f", s.CertFile, "/etc/pki/ca-trust/source/anchors/" + appOnce.AppName + ".crt"},
|
||||
{"update-ca-trust"},
|
||||
{"cp", "-f", s.CertFile, "/etc/ssl/ca-certificates/" + appOnce.AppName + ".crt"},
|
||||
{"update-ca-certificates"},
|
||||
}
|
||||
|
||||
is := false
|
||||
|
||||
outs := ""
|
||||
errs := ""
|
||||
for _, action := range actions {
|
||||
dir := action[0]
|
||||
if err := exec.Command("sudo", "cp", "-f", s.CertFile, dir+appOnce.AppName+".crt").Run(); err != nil {
|
||||
fmt.Printf("Failed to copy to %s: %v\n", dir, err)
|
||||
continue
|
||||
}
|
||||
|
||||
cmd := action[1]
|
||||
if err := exec.Command("sudo", cmd).Run(); err != nil {
|
||||
fmt.Printf("Failed to refresh certificates using %s: %v\n", cmd, err)
|
||||
if output, err1 := s.runCommand(action); err1 != nil {
|
||||
outs += string(output) + "\n"
|
||||
errs += err1.Error() + "\n"
|
||||
fmt.Printf("Failed to execute %v: %v\n", action, err1)
|
||||
continue
|
||||
}
|
||||
|
||||
is = true
|
||||
}
|
||||
|
||||
if !is {
|
||||
return "", fmt.Errorf("Certificate installation failed")
|
||||
if is {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
return outs, fmt.Errorf("Certificate installation failed, errs:%s", errs)
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func Empty(data interface{}) {
|
||||
}
|
||||
|
||||
func DialogErr(message string) {
|
||||
_, _ = runtime.MessageDialog(appOnce.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.ErrorDialog,
|
||||
@@ -28,14 +25,11 @@ func IsDevelopment() bool {
|
||||
}
|
||||
|
||||
func FileExist(file string) bool {
|
||||
_, err := os.Stat(file)
|
||||
info, err := os.Stat(file)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
func CreateDirIfNotExist(dir string) error {
|
||||
@@ -55,14 +49,6 @@ func TypeSuffix(mime string) (string, string) {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func BuildReferer(rawURL string) string {
|
||||
u, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return u.Scheme + "://" + u.Host + "/"
|
||||
}
|
||||
|
||||
func Md5(data string) string {
|
||||
hashNew := md5.New()
|
||||
hashNew.Write([]byte(data))
|
||||
|
||||
Reference in New Issue
Block a user