diff --git a/hosts/by-name/servo/services/export/sftpgo.nix b/hosts/by-name/servo/services/export/sftpgo.nix index f30a2ad1f..e49550f0f 100644 --- a/hosts/by-name/servo/services/export/sftpgo.nix +++ b/hosts/by-name/servo/services/export/sftpgo.nix @@ -56,6 +56,29 @@ in services.sftpgo = { enable = true; group = "export"; + + package = lib.warnIf (lib.versionOlder "2.5.6" pkgs.sftpgo.version) "sftpgo update: safe to use nixpkgs' sftpgo but keep my own `patches`" pkgs.buildGoModule { + inherit (pkgs.sftpgo) name ldflags nativeBuildInputs doCheck subPackages postInstall passthru meta; + version = "2.5.6-unstable-2024-04-18"; + src = pkgs.fetchFromGitHub { + # need to use > 2.5.6 for sftpgo_safe_fileinfo.patch to apply + owner = "drakkan"; + repo = "sftpgo"; + rev = "950cf67e4c03a12c7e439802cabbb0b42d4ee5f5"; + hash = "sha256-UfiFd9NK3DdZ1J+FPGZrM7r2mo9xlKi0dsSlLEinYXM="; + }; + vendorHash = "sha256-n1/9A2em3BCtFX+132ualh4NQwkwewMxYIMOphJEamg="; + patches = (pkgs.sftpgo.patches or []) ++ [ + # fix for compatibility with kodi: + # ftp LIST operation returns entries over-the-wire like: + # - dgrwxrwxr-x 1 ftp ftp 9 Apr 9 15:05 Videos + # however not all clients understand all mode bits (like that `g`, indicating SGID / group sticky bit). + # instead, only send mode bits which are well-understood. + # the full set of bits, from which i filter, is found here: + ./sftpgo_safe_fileinfo.patch + ]; + }; + settings = { ftpd = { bindings = [ diff --git a/hosts/by-name/servo/services/export/sftpgo_safe_fileinfo.patch b/hosts/by-name/servo/services/export/sftpgo_safe_fileinfo.patch new file mode 100644 index 000000000..15a9a4f81 --- /dev/null +++ b/hosts/by-name/servo/services/export/sftpgo_safe_fileinfo.patch @@ -0,0 +1,32 @@ +diff --git a/internal/ftpd/handler.go b/internal/ftpd/handler.go +index 036c3977..33211261 100644 +--- a/internal/ftpd/handler.go ++++ b/internal/ftpd/handler.go +@@ -169,7 +169,7 @@ func (c *Connection) Stat(name string) (os.FileInfo, error) { + } + return nil, err + } +- return fi, nil ++ return vfs.NewFileInfo(name, fi.IsDir(), fi.Size(), fi.ModTime(), false), nil + } + + // Name returns the name of this connection +@@ -315,7 +315,17 @@ func (c *Connection) ReadDir(name string) (ftpserver.DirLister, error) { + }, nil + } + +- return c.ListDir(name) ++ lister, err := c.ListDir(name) ++ if err != nil { ++ return nil, err ++ } ++ return &patternDirLister{ ++ DirLister: lister, ++ pattern: "*", ++ lastCommand: c.clientContext.GetLastCommand(), ++ dirName: name, ++ connectionPath: c.clientContext.Path(), ++ }, nil + } + + // GetHandle implements ClientDriverExtentionFileTransfer