aboutsummaryrefslogtreecommitdiff
path: root/forged/internal
diff options
context:
space:
mode:
authorRunxi Yu <me@runxiyu.org>2025-08-17 03:43:08 +0800
committerRunxi Yu <me@runxiyu.org>2025-08-17 03:48:28 +0800
commit6da9e99a221c814c50804783c598ec12f78e38d8 (patch)
treeb118745279163baf8979cfa5b445831b3c4ba4f8 /forged/internal
parentSome mass renaming (diff)
downloadforge-6da9e99a221c814c50804783c598ec12f78e38d8.tar.gz
forge-6da9e99a221c814c50804783c598ec12f78e38d8.tar.zst
forge-6da9e99a221c814c50804783c598ec12f78e38d8.zip
Add some stubs
Diffstat (limited to 'forged/internal')
-rw-r--r--forged/internal/common/misc/net.go (renamed from forged/internal/common/misc/usock.go)15
-rw-r--r--forged/internal/incoming/hooks/hooks.go10
-rw-r--r--forged/internal/incoming/lmtp/config.go10
-rw-r--r--forged/internal/incoming/ssh/ssh.go58
-rw-r--r--forged/internal/incoming/web/web.go57
-rw-r--r--forged/internal/server/server.go25
6 files changed, 149 insertions, 26 deletions
diff --git a/forged/internal/common/misc/usock.go b/forged/internal/common/misc/net.go
index 357fa43..2c6b0a5 100644
--- a/forged/internal/common/misc/usock.go
+++ b/forged/internal/common/misc/net.go
@@ -21,3 +21,18 @@ func ListenUnixSocket(path string) (listener net.Listener, replaced bool, err er
}
return listener, replaced, nil
}
+
+func Listen(net_, addr string) (listener net.Listener, err error) {
+ if net_ == "unix" {
+ listener, _, err = ListenUnixSocket(addr)
+ if err != nil {
+ return listener, fmt.Errorf("listen unix socket for web: %w", err)
+ }
+ } else {
+ listener, err = net.Listen(net_, addr)
+ if err != nil {
+ return listener, fmt.Errorf("listen %s for web: %w", net_, err)
+ }
+ }
+ return listener, nil
+}
diff --git a/forged/internal/incoming/hooks/hooks.go b/forged/internal/incoming/hooks/hooks.go
index 64e1cbe..18b9742 100644
--- a/forged/internal/incoming/hooks/hooks.go
+++ b/forged/internal/incoming/hooks/hooks.go
@@ -33,15 +33,15 @@ type hookInfo struct {
contribReq string
}
-func New(config Config) (pool *Server) {
+func New(config Config) (server *Server) {
return &Server{
socketPath: config.Socket,
executablesPath: config.Execs,
}
}
-func (pool *Server) Run() error {
- listener, _, err := misc.ListenUnixSocket(pool.socketPath)
+func (server *Server) Run() error {
+ listener, _, err := misc.ListenUnixSocket(server.socketPath)
if err != nil {
return fmt.Errorf("listen unix socket for hooks: %w", err)
}
@@ -52,10 +52,10 @@ func (pool *Server) Run() error {
return fmt.Errorf("accept conn: %w", err)
}
- go pool.handleConn(conn)
+ go server.handleConn(conn)
}
}
-func (pool *Server) handleConn(conn net.Conn) {
+func (server *Server) handleConn(conn net.Conn) {
panic("TODO: handle hook connection")
}
diff --git a/forged/internal/incoming/lmtp/config.go b/forged/internal/incoming/lmtp/config.go
index 767f0e4..e6db5a6 100644
--- a/forged/internal/incoming/lmtp/config.go
+++ b/forged/internal/incoming/lmtp/config.go
@@ -23,7 +23,7 @@ type Config struct {
ReadTimeout uint32 `scfg:"read_timeout"`
}
-func New(config Config) (pool *Server) {
+func New(config Config) (server *Server) {
return &Server{
socket: config.Socket,
domain: config.Domain,
@@ -33,8 +33,8 @@ func New(config Config) (pool *Server) {
}
}
-func (pool *Server) Run() error {
- listener, _, err := misc.ListenUnixSocket(pool.socket)
+func (server *Server) Run() error {
+ listener, _, err := misc.ListenUnixSocket(server.socket)
if err != nil {
return fmt.Errorf("listen unix socket for LMTP: %w", err)
}
@@ -45,10 +45,10 @@ func (pool *Server) Run() error {
return fmt.Errorf("accept conn: %w", err)
}
- go pool.handleConn(conn)
+ go server.handleConn(conn)
}
}
-func (pool *Server) handleConn(conn net.Conn) {
+func (server *Server) handleConn(conn net.Conn) {
panic("TODO: handle LMTP connection")
}
diff --git a/forged/internal/incoming/ssh/ssh.go b/forged/internal/incoming/ssh/ssh.go
index 74bd99b..b0269e5 100644
--- a/forged/internal/incoming/ssh/ssh.go
+++ b/forged/internal/incoming/ssh/ssh.go
@@ -1,6 +1,13 @@
package ssh
-type Server struct{}
+import (
+ "fmt"
+ "os"
+
+ gliderssh "github.com/gliderlabs/ssh"
+ "go.lindenii.runxiyu.org/forge/forged/internal/common/misc"
+ gossh "golang.org/x/crypto/ssh"
+)
type Config struct {
Net string `scfg:"net"`
@@ -8,3 +15,52 @@ type Config struct {
Key string `scfg:"key"`
Root string `scfg:"root"`
}
+
+type Server struct {
+ gliderServer *gliderssh.Server
+ privkey gossh.Signer
+ pubkeyString string
+ pubkeyFP string
+ net string
+ addr string
+ root string
+}
+
+func New(config Config) (server *Server, err error) {
+ server = &Server{
+ net: config.Net,
+ addr: config.Addr,
+ root: config.Root,
+ }
+
+ var privkeyBytes []byte
+ if privkeyBytes, err = os.ReadFile(config.Key); err != nil {
+ return server, fmt.Errorf("read SSH private key: %w", err)
+ }
+ if server.privkey, err = gossh.ParsePrivateKey(privkeyBytes); err != nil {
+ return server, fmt.Errorf("parse SSH private key: %w", err)
+ }
+ server.pubkeyString = misc.BytesToString(gossh.MarshalAuthorizedKey(server.privkey.PublicKey()))
+ server.pubkeyFP = gossh.FingerprintSHA256(server.privkey.PublicKey())
+
+ server.gliderServer = &gliderssh.Server{
+ Handler: handle,
+ PublicKeyHandler: func(ctx gliderssh.Context, key gliderssh.PublicKey) bool { return true },
+ KeyboardInteractiveHandler: func(ctx gliderssh.Context, challenge gossh.KeyboardInteractiveChallenge) bool { return true },
+ }
+ server.gliderServer.AddHostKey(server.privkey)
+
+ return
+}
+
+func (server *Server) Run() (err error) {
+ listener, err := misc.Listen(server.net, server.addr)
+ if err = server.gliderServer.Serve(listener); err != nil {
+ return fmt.Errorf("serve SSH: %w", err)
+ }
+ panic("unreachable")
+}
+
+func handle(session gliderssh.Session) {
+ panic("SSH server handler not implemented yet")
+}
diff --git a/forged/internal/incoming/web/web.go b/forged/internal/incoming/web/web.go
index e338ef2..e4675f0 100644
--- a/forged/internal/incoming/web/web.go
+++ b/forged/internal/incoming/web/web.go
@@ -1,18 +1,57 @@
package web
-import "net/http"
+import (
+ "fmt"
+ "net/http"
+ "time"
+
+ "go.lindenii.runxiyu.org/forge/forged/internal/common/misc"
+)
type Server struct {
+ net string
+ addr string
+ root string
httpServer *http.Server
}
+type handler struct{}
+
+func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+}
+
type Config struct {
- Net string `scfg:"net"`
- Addr string `scfg:"addr"`
- CookieExpiry int `scfg:"cookie_expiry"`
- Root string `scfg:"root"`
- ReadTimeout uint32 `scfg:"read_timeout"`
- WriteTimeout uint32 `scfg:"write_timeout"`
- IdleTimeout uint32 `scfg:"idle_timeout"`
- ReverseProxy bool `scfg:"reverse_proxy"`
+ Net string `scfg:"net"`
+ Addr string `scfg:"addr"`
+ Root string `scfg:"root"`
+ CookieExpiry int `scfg:"cookie_expiry"`
+ ReadTimeout uint32 `scfg:"read_timeout"`
+ WriteTimeout uint32 `scfg:"write_timeout"`
+ IdleTimeout uint32 `scfg:"idle_timeout"`
+ MaxHeaderBytes int `scfg:"max_header_bytes"`
+ ReverseProxy bool `scfg:"reverse_proxy"`
+}
+
+func New(config Config) (server *Server) {
+ handler := &handler{}
+ return &Server{
+ net: config.Net,
+ addr: config.Addr,
+ root: config.Root,
+ httpServer: &http.Server{
+ Handler: handler,
+ ReadTimeout: time.Duration(config.ReadTimeout) * time.Second,
+ WriteTimeout: time.Duration(config.WriteTimeout) * time.Second,
+ IdleTimeout: time.Duration(config.IdleTimeout) * time.Second,
+ MaxHeaderBytes: config.MaxHeaderBytes,
+ },
+ }
+}
+
+func (server *Server) Run() (err error) {
+ listener, err := misc.Listen(server.net, server.addr)
+ if err = server.httpServer.Serve(listener); err != nil {
+ return fmt.Errorf("serve web: %w", err)
+ }
+ panic("unreachable")
}
diff --git a/forged/internal/server/server.go b/forged/internal/server/server.go
index 1f2cce6..b3cd92a 100644
--- a/forged/internal/server/server.go
+++ b/forged/internal/server/server.go
@@ -37,17 +37,18 @@ func New(ctx context.Context, configPath string) (server *Server, err error) {
return server, fmt.Errorf("open config: %w", err)
}
- // TODO: Should this belong here, or in Run()?
server.database, err = database.Open(ctx, server.config.DB)
if err != nil {
return server, fmt.Errorf("open database: %w", err)
}
server.hookServer = hooks.New(server.config.Hooks)
-
server.lmtpServer = lmtp.New(server.config.LMTP)
-
- // TODO: Add HTTP and SSH servers
+ server.webServer = web.New(server.config.Web)
+ server.sshServer, err = ssh.New(server.config.SSH)
+ if err != nil {
+ return server, fmt.Errorf("create SSH server: %w", err)
+ }
return server, nil
}
@@ -58,13 +59,25 @@ func (s *Server) Run() error {
go func() {
if err := s.hookServer.Run(); err != nil {
- log.Fatalf("run hook pool: %v", err)
+ log.Fatalf("run hook server: %v", err)
}
}()
go func() {
if err := s.lmtpServer.Run(); err != nil {
- log.Fatalf("run LMTP pool: %v", err)
+ log.Fatalf("run LMTP server: %v", err)
+ }
+ }()
+
+ go func() {
+ if err := s.webServer.Run(); err != nil {
+ log.Fatalf("run web server: %v", err)
+ }
+ }()
+
+ go func() {
+ if err := s.sshServer.Run(); err != nil {
+ log.Fatalf("run SSH server: %v", err)
}
}()