Pārlūkot izejas kodu

更新 newCert 函数以支持目录参数

在 `newCert` 函数中添加了目录参数,以便保存和加载账户信息。同时新增了 `saveAccount` 和 `loadAccount` 函数来处理账户的保存和加载。
SongZihuan 3 mēneši atpakaļ
vecāks
revīzija
c2addd9c8a
2 mainītis faili ar 50 papildinājumiem un 6 dzēšanām
  1. 2 2
      src/acme/ctrl.go
  2. 48 4
      src/acme/newcert.go

+ 2 - 2
src/acme/ctrl.go

@@ -26,7 +26,7 @@ func GetCertificateAndPrivateKey(dir string, email string, httpsAddress string,
 		return privateKey, cert, nil
 	}
 
-	privateKey, resource, err := newCert(email, httpsAddress, domain)
+	privateKey, resource, err := newCert(dir, email, httpsAddress, domain)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -99,7 +99,7 @@ func watchCertificateAndPrivateKey(dir string, email string, httpsAddress string
 		return nil, nil, nil
 	}
 
-	privateKey, resource, err := newCert(email, httpsAddress, domain)
+	privateKey, resource, err := newCert(dir, email, httpsAddress, domain)
 	if err != nil {
 		return nil, nil, err
 	}

+ 48 - 4
src/acme/newcert.go

@@ -1,11 +1,13 @@
 package acme
 
 import (
+	"bytes"
 	"crypto"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
 	"crypto/x509"
+	"encoding/gob"
 	"encoding/pem"
 	"fmt"
 	"github.com/go-acme/lego/v4/certcrypto"
@@ -19,7 +21,41 @@ import (
 	"time"
 )
 
-func newCert(email string, httpsAddress string, domain string) (crypto.PrivateKey, *certificate.Resource, error) {
+func saveAccount(dir string, email string, reg *registration.Resource) error {
+	filepath := path.Join(dir, fmt.Sprintf("%s.account", email))
+
+	var buff bytes.Buffer
+	enc := gob.NewEncoder(&buff)
+	err := enc.Encode(reg)
+	if err != nil {
+		return err
+	}
+
+	return os.WriteFile(filepath, buff.Bytes(), 0644)
+}
+
+func loadAccount(dir string, email string) (*registration.Resource, error) {
+	filepath := path.Join(dir, fmt.Sprintf("%s.account", email))
+	file, err := os.Open(filepath)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		_ = file.Close()
+	}()
+
+	var reg registration.Resource
+	dec := gob.NewDecoder(file)
+
+	err = dec.Decode(&reg)
+	if err != nil {
+		return nil, err
+	}
+
+	return &reg, nil
+}
+
+func newCert(dir string, email string, httpsAddress string, domain string) (crypto.PrivateKey, *certificate.Resource, error) {
 	privateKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
 	if err != nil {
 		return nil, nil, err
@@ -49,11 +85,19 @@ func newCert(email string, httpsAddress string, domain string) (crypto.PrivateKe
 		TermsOfServiceAgreed: true,
 	}
 
-	reg, err := client.Registration.Register(regOption)
+	reg, err := loadAccount(path.Join(dir, "account"), email)
 	if err != nil {
-		return nil, nil, err
-	}
+		// 尝试注册
+		reg, err = client.Registration.Register(regOption)
+		if err != nil {
+			return nil, nil, err
+		}
 
+		err = saveAccount(dir, email, reg)
+		if err != nil {
+			return nil, nil, err
+		}
+	}
 	user.setRegistration(reg)
 
 	if domain == "" {