diff options
Diffstat (limited to 'internal/server')
| -rw-r--r-- | internal/server/api/database.go | 14 | ||||
| -rw-r--r-- | internal/server/server.go | 86 |
2 files changed, 74 insertions, 26 deletions
diff --git a/internal/server/api/database.go b/internal/server/api/database.go index 0151036..1226410 100644 --- a/internal/server/api/database.go +++ b/internal/server/api/database.go @@ -3,7 +3,7 @@ package api import ( "database/sql" "embed" - "log" + "log/slog" _ "github.com/mattn/go-sqlite3" "github.com/pressly/goose/v3" @@ -20,10 +20,11 @@ func ConnectToDatabase() { var err error db, err = sql.Open("sqlite3", "file:server.db?cache=shared") if err != nil { - log.Fatalln("unable to open db:", err) + slog.Error("unable to open database", "error", err) + assert.Abort("see logs") } assert.AddFlush(db) - log.Println("established connection with the database") + slog.Info("established connection with the database") pragmas := []string{ "PRAGMA journal_mode = WAL;", @@ -36,7 +37,7 @@ func ConnectToDatabase() { assert.NoError(err, "DB pragmas should always execute with no errors") } - log.Println("opened database, running up migrations...") + slog.Info("opened database, running migrations...") goose.SetBaseFS(embedMigrations) if err := goose.SetDialect("sqlite3"); err != nil { @@ -44,10 +45,11 @@ func ConnectToDatabase() { } if err := goose.Up(db, "migrations"); err != nil { _ = db.Close() - log.Fatalln("error running up migrations:", err) + slog.Error("error running migrations", "error", err) + assert.Abort("see logs") } - log.Println("database connection ready to be used") + slog.Info("database connection ready to be used") } func DB() *sql.DB { diff --git a/internal/server/server.go b/internal/server/server.go index 92d10f9..81085d7 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -3,18 +3,23 @@ package server import ( "context" "crypto/ed25519" + "crypto/rand" + "crypto/rsa" "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" "errors" "io" - "log" "log/slog" + "math/big" "net" "os" "strconv" "sync" "time" - "github.com/kyren223/eko/certs" + "github.com/kyren223/eko/embeds" "github.com/kyren223/eko/internal/packet" "github.com/kyren223/eko/internal/server/api" "github.com/kyren223/eko/internal/server/ctxkeys" @@ -23,32 +28,71 @@ import ( "github.com/kyren223/eko/pkg/snowflake" ) -var ( - nodeId int64 = 0 - tlsConfig *tls.Config -) +var nodeId int64 = 0 + +const CertFile = "EKO_SERVER_CERT_FILE" -func init() { - path, ok := os.LookupEnv("EKO_SERVER_CERT_FILE") +func getTlsConfig() *tls.Config { + path, ok := os.LookupEnv(CertFile) if !ok { - path = "certs/server.key" + // DEV MODE ONLY, DUMMY CERT + cert, err := generateDummyCert() + if err != nil { + slog.Error("failed to generate dummy cert", "error", err) + assert.Abort("see logs") + } + + return &tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + } } keyPEM, err := os.ReadFile(path) // #nosec 304 if err != nil { - log.Fatalln("failed to read certificate key from", path) + slog.Error("failed to read certificate key", "path", path) + assert.Abort("see logs") } - cert, err := tls.X509KeyPair(certs.CertPEM, keyPEM) + cert, err := tls.X509KeyPair(embeds.ServerCertificate, keyPEM) if err != nil { - log.Fatalln("error loading certificate:", err) + slog.Error("error loading certificate", "error", err) + assert.Abort("see logs") } - tlsConfig = &tls.Config{ + return &tls.Config{ Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12, } } +func generateDummyCert() (tls.Certificate, error) { + priv, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return tls.Certificate{}, err + } + + serial, _ := rand.Int(rand.Reader, big.NewInt(1<<62)) + + template := x509.Certificate{ + SerialNumber: serial, + NotBefore: time.Now().Add(-time.Hour), + NotAfter: time.Now().Add(365 * 24 * time.Hour), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + Subject: pkix.Name{CommonName: "localhost"}, + } + + der, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) + if err != nil { + return tls.Certificate{}, err + } + + certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der}) + keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) + + return tls.X509KeyPair(certPEM, keyPEM) +} + type server struct { ctx context.Context node *snowflake.Node @@ -133,9 +177,13 @@ func (s *server) Node() *snowflake.Node { // Run starts listening and accepting clients, // blocking until it gets terminated by cancelling the context. func (s *server) Run() { - listener, err := tls.Listen("tcp4", ":"+strconv.Itoa(int(s.Port)), tlsConfig) + slog.Info("starting eko-server...") + + listener, err := tls.Listen("tcp4", ":"+strconv.Itoa(int(s.Port)), getTlsConfig()) if err != nil { - log.Fatalf("error starting server: %s", err) + // TODO: we need certs even for dev + slog.Error("error starting server", "error", err) + os.Exit(1) } assert.AddFlush(listener) @@ -436,11 +484,9 @@ func timeout[T packet.Payload]( } func sendTosInfo(ctx context.Context, sess *session.Session) bool { - // FIXME: ===== REPLACE WITH ACTUAL TOS ===== - // TODO: Get TOS and privacy policy - tos := "WIP Terms of Service" - privacy := "WIP Privacy Policy" - date := "2025-07-03" + tos := embeds.TermsOfService.Load().(string) + privacy := embeds.PrivacyPolicy.Load().(string) + date := embeds.TosPrivacyHash.Load().(string) payload := &packet.TosInfo{ Tos: tos, |
