64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"os/signal"
|
|
"os/user"
|
|
"strconv"
|
|
"syscall"
|
|
|
|
"git.pcux.cn/xuans/Scert/backend/internal/certstorage"
|
|
)
|
|
|
|
func run(ctx context.Context) error {
|
|
root := flag.String("root", "/ssl", "安装时额外批准的证书存储根目录")
|
|
flag.Parse()
|
|
if flag.NArg() != 0 || os.Geteuid() != 0 || os.Getenv("LISTEN_PID") != strconv.Itoa(os.Getpid()) || os.Getenv("LISTEN_FDS") != "1" {
|
|
return errors.New("目录服务必须由 root 的单个 systemd socket 启动")
|
|
}
|
|
account, err := user.Lookup("Scert")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
uid, err := strconv.ParseUint(account.Uid, 10, 32)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
gid, err := strconv.ParseUint(account.Gid, 10, 32)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
file := os.NewFile(3, "storage-socket")
|
|
if file == nil {
|
|
return errors.New("目录服务监听描述符不存在")
|
|
}
|
|
defer file.Close()
|
|
listener, err := net.FileListener(file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer listener.Close()
|
|
local, ok := listener.(*net.UnixListener)
|
|
if !ok || listener.Addr().Network() != "unix" || listener.Addr().String() != certstorage.SocketPath {
|
|
return errors.New("目录服务拒绝非固定 Unix 通道")
|
|
}
|
|
return (certstorage.Service{
|
|
UID: uint32(uid), GID: uint32(gid), Roots: []string{"/ssl", "/var/lib/scert/certificates", *root},
|
|
Log: func(err error) { fmt.Fprintln(os.Stderr, "证书目录自动准备失败:", err) },
|
|
}).Serve(ctx, local)
|
|
}
|
|
|
|
func main() {
|
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
defer stop()
|
|
if err := run(ctx); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|