sftpd

package
v0.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: AGPL-3.0 Imports: 18 Imported by: 0

Documentation

Overview

Package sftpd serves SFTP for game servers. It runs as a user of its own with no access to the volumes: the panel says who may log in and to which server, and every file operation goes to the core as a typed request. It speaks only the sftp subsystem, with no shell, no commands and no forwarding.

Index

Constants

View Source
const DefaultPanelSocket = "/run/zelie-panel/panel.sock"

DefaultPanelSocket is where the panel listens.

Variables

View Source
var ErrDenied = errors.New("login refused")

ErrDenied is what a login that is not allowed comes back with. It says nothing about why, so it cannot be used to find out who has an account.

Functions

This section is empty.

Types

type AuthRequest

type AuthRequest struct {
	Server   string `json:"server"`
	Password string `json:"password,omitempty"`
	Key      []byte `json:"key,omitempty"` // SSH wire format
	IP       string `json:"ip"`
}

The requests and answers of the panel's SFTP routes, which only this process may call.

type Files

type Files interface {
	ListFiles(ctx context.Context, ref core.FileRef, dir string) (core.FileList, error)
	StatFile(ctx context.Context, ref core.FileRef, p string) (core.FileEntry, error)
	DownloadRange(ctx context.Context, ref core.FileRef, p string, offset, length int64) (io.ReadCloser, int64, error)
	UploadFile(ctx context.Context, ref core.FileRef, p string, size int64, body io.Reader) error
	MakeFolder(ctx context.Context, ref core.FileRef, p string) error
	RenameFile(ctx context.Context, ref core.FileRef, from, to string) error
	RemoveFile(ctx context.Context, ref core.FileRef, p string) error
}

Files is the part of the core's file API that SFTP uses.

type Grant

type Grant struct {
	Server string `json:"server"`
	Volume string `json:"volume"`
	UID    uint32 `json:"uid"`
	GID    uint32 `json:"gid"`
	// Account is who logged in, for the log. It is 0 for a password, which
	// belongs to the server and not to a person.
	Account int64 `json:"account,omitempty"`
}

Grant is what the panel lets a login use: one server's files.

type Panel

type Panel interface {
	// Password checks a server's SFTP password.
	Password(ctx context.Context, server, password, ip string) (Grant, error)
	// Key checks that the key belongs to an account that may use the
	// server. The caller has not seen the client sign anything yet.
	Key(ctx context.Context, server string, key ssh.PublicKey, ip string) (Grant, error)
	// Room is how many more bytes the server's disk limit leaves, or nil
	// when that is not known.
	Room(ctx context.Context, server string) (*int64, error)
}

Panel is what the SFTP service asks of the panel. The panel decides who may log in; this process only holds the connection.

type PanelClient

type PanelClient struct {
	// contains filtered or unexported fields
}

PanelClient is Panel over the panel's Unix socket.

func NewPanelClient

func NewPanelClient(socket string) *PanelClient

func (*PanelClient) Key

func (c *PanelClient) Key(ctx context.Context, server string, key ssh.PublicKey, ip string) (Grant, error)

func (*PanelClient) Password

func (c *PanelClient) Password(ctx context.Context, server, password, ip string) (Grant, error)

func (*PanelClient) Room

func (c *PanelClient) Room(ctx context.Context, server string) (*int64, error)

type RoomRequest

type RoomRequest struct {
	Server string `json:"server"`
}

The requests and answers of the panel's SFTP routes, which only this process may call.

type RoomResponse

type RoomResponse struct {
	Room *int64 `json:"room,omitempty"`
}

The requests and answers of the panel's SFTP routes, which only this process may call.

type Server

type Server struct {
	Panel Panel
	Files Files
	Log   *slog.Logger
	// HostKeyPath is where the host key is kept; it is made on first use.
	HostKeyPath string
	// MaxPerIP is how many connections one address may hold open. Zero
	// means the default of 8.
	MaxPerIP int
	// IdleExit is how long the server stays up with no connection open.
	// Zero means five minutes.
	IdleExit time.Duration
	// contains filtered or unexported fields
}

Server is the SFTP service.

func (*Server) Fingerprint

func (s *Server) Fingerprint() string

Fingerprint is the SHA-256 fingerprint of the host key, as ssh shows it.

func (*Server) LoadHostKey

func (s *Server) LoadHostKey() error

LoadHostKey reads the host key, or makes one if there is none yet.

func (*Server) Serve

func (s *Server) Serve(ctx context.Context, l net.Listener) error

Serve accepts connections on l until l is closed, ctx ends, or no connection has been open for IdleExit. It returns nil in each case. The listener belongs to systemd, which keeps the port and starts the server again when someone connects, so closing it here loses nothing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL