spacecookie 0.2.1.0 → 0.2.1.1
raw patch · 9 files changed
+64/−30 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +16/−0
- README.md +19/−7
- etc/spacecookie.json +3/−3
- etc/spacecookie.service +2/−0
- etc/spacecookie.socket +1/−0
- server/Config.hs +7/−6
- server/Main.hs +1/−1
- spacecookie.cabal +2/−2
- src/Network/Gopher.hs +13/−11
CHANGELOG.md view
@@ -1,5 +1,21 @@ # Revision history for spacecookie +## 0.2.1.1 Fixed Privilege Dropping++* Server+ * Make `user` parameter in config optional. If it is not given or set to `null`, `spacecookie` won't attempt+ to change its UID and GID. This is especially useful, if socket activation is used. In that case it is not+ necessary to start spacecookie as `root` since systemd sets up the socket, so `spacecookie` can be already+ started by the right user and doesn't need to change UID.+ * Example Systemd config files+ * `SocketMode` is now `660` instead of default `666`.+ * Set `User` and `Group` for `spacecookie.service` as well.+ * Set `"user": null` in `spacecookie.json`+* Library+ * Fixed issue that led to `runGopher*` trying to change UID even if it wasn't possible (not running as root).+ This especially affected the `spacecookie` server, since `cRunUserName` would always be `Just`.+ * Made logging related to `dropPrivileges` clearer.+ ## 0.2.1.0 Systemd Support * Improved systemd support.
README.md view
@@ -29,8 +29,8 @@ option | meaning -----------|---------------------------------------------------------------------------------------------------------`hostname` | The hostname your spacecookie will be reachable through.-`user` | The user that just run spacecookie. It is used to drop root priveleges after binding the server socket.+`hostname` | The hostname your spacecookie will be reachable through. This should be accurate as gopher clients use it for their subsequent requests.+`user` | The user that just run spacecookie. It is used to drop root priveleges after binding the server socket. Can be omitted or set to `null`, if root privileges are not needed (e. g. if systemd socket activation or a non well-known port is used). `port` | The port spacecookie should listen on. The well-known port for gopher is 70. `root` | The directory which the files to serve via gopher are located in. @@ -54,8 +54,8 @@ systemctl start spacecookie.socket systemctl start spacecookie.service # optional, started by the socket automatically if needed -Don't forget to change the paths in the systemd files and match the user name in-`spacecookie.socket` with the one in `spacecookie.json`!+You'll have to ensure that the paths are correct and the user and group specified+in `spacecookie.socket` and `spacecookie.service` exist. ### Without systemd @@ -64,9 +64,8 @@ is very lightweight and can be utilized without using a systemd library or dbus. -Spacecookie currently fully supports any GNU/Linux. It should be pretty-easy to, for example, write a [runit](http://smarden.org/runit/) service-file.+For example, it should be pretty easy to write a [runit](http://smarden.org/runit/)+service file. ## Adding Content @@ -95,6 +94,19 @@ * "Links" to other servers are like file/directory menu entries but the server's hostname and its port must be added (tab-separated). The file type characters are defined in [RFC1436](https://tools.ietf.org/html/rfc1436#page-10). Detailed documentation on the gophermap format [can be found here](./docs/gophermap-pygopherd.txt).++## Portability++Spacecookie's portability is mostly limited by [haskell-socket](https://github.com/lpeterse/haskell-socket).+`haskell-socket` should work on any POSIX-compliant Operating system, so Spacecookie should support those+platforms as well.++However I personally have only tested Spacecookie on GNU/Linux (with and without+systemd) so far. Feel free to send me an email or generate a [build report](http://hackage.haskell.org/package/spacecookie/reports/)+if you've built spacecookie (or failed to do so) on another platform!++Windows is currently not supported as we use some Unix-specific features, but there is probably+little demand for it as well. ## HTTP Support?
etc/spacecookie.json view
@@ -1,6 +1,6 @@ { "hostname" : "localhost",- "user" : "lukas",- "port" : 7070,- "root" : "./tmp"+ "port" : 70,+ "user" : null,+ "root" : "/srv/gopher" }
etc/spacecookie.service view
@@ -8,6 +8,8 @@ FileDescriptorStoreMax=1 NotifyAccess=main StandardError=journal+User=spacecookie+Group=spacecookie [Install] WantedBy=multi-user.target
etc/spacecookie.socket view
@@ -5,5 +5,6 @@ BindIPv6Only=both SocketGroup=spacecookie SocketUser=spacecookie+SocketMode=0660 ListenStream=[::]:70
server/Config.hs view
@@ -9,11 +9,12 @@ import Data.Aeson.Types import Data.ByteString (ByteString ()) import qualified Data.ByteString as B+import Data.Maybe import Network.Gopher.Util data Config = Config { serverName :: ByteString , serverPort :: Integer- , runUserName :: String+ , runUserName :: Maybe String , rootDirectory :: FilePath } @@ -21,21 +22,21 @@ parseJSON (Object v) = Config <$> v .: "hostname" <*> v .: "port" <*>- v .: "user" <*>+ v .:? "user" <*> v .: "root" parseJSON _ = mzero instance ToJSON Config where- toJSON (Config host port user root) = object+ toJSON (Config host port user root) = object $ [ "hostname" .= host , "port" .= port- , "user" .= user , "root" .= root- ]+ ] +++ maybe [] ((:[]) . ("user" .=)) user -- auxiliary instances for types that have no default instance instance FromJSON ByteString where- parseJSON (String s) = uEncode <$> (parseJSON (String s))+ parseJSON s@(String _) = uEncode <$> parseJSON s parseJSON _ = mzero instance ToJSON ByteString where
server/Main.hs view
@@ -32,7 +32,7 @@ case config' of Just config -> do changeWorkingDirectory (rootDirectory config)- let cfg = GopherConfig (serverName config) (serverPort config) ((Just (runUserName config)))+ let cfg = GopherConfig (serverName config) (serverPort config) (runUserName config) runGopherManual (systemdSocket cfg) (notifyReady >> pure ()) (\s -> notifyStopping >> systemdStoreOrClose s)
spacecookie.cabal view
@@ -1,5 +1,6 @@+cabal-version: >= 2.0 name: spacecookie-version: 0.2.1.0+version: 0.2.1.1 synopsis: Gopher Library and Server Daemon description: Simple gopher library that allows writing custom gopher applications. Also includes a fully-featured gopher server@@ -10,7 +11,6 @@ maintainer: git@lukasepple.de category: Network build-type: Simple-cabal-version: >=2.0 homepage: https://github.com/sternenseemann/spacecookie bug-reports: https://github.com/sternenseemann/spacecookie/issues extra-source-files: CHANGELOG.md
src/Network/Gopher.hs view
@@ -136,14 +136,16 @@ then return (acc `B.append` bs) else receiveRequest' sock (acc `B.append` bs) -dropPrivileges :: String -> IO ()+dropPrivileges :: String -> IO Bool dropPrivileges username = do uid <- getRealUserID- when (uid /= 0) $ return ()-- user <- getUserEntryForName username- setGroupID $ userGroupID user- setUserID $ userID user+ if (uid /= 0)+ then return False+ else do+ user <- getUserEntryForName username+ setGroupID $ userGroupID user+ setUserID $ userID user+ return True -- | Auxiliary function that sets up the listening socket for -- 'runGopherManual' correctly and starts to listen.@@ -185,11 +187,11 @@ log . LogInfo $ "Now listening on " ++ prettyAddr addr -- Change UID and GID if necessary- if isJust (cRunUserName cfg)- then do- liftIO (dropPrivileges (fromJust (cRunUserName cfg)))- log . LogInfo $ "Dropped privileges to " ++ fromJust (cRunUserName cfg)- else log .LogInfo $ "Privileges were not dropped"+ when (isJust (cRunUserName cfg)) $ do+ success <- liftIO (dropPrivileges (fromJust (cRunUserName cfg)))+ if success+ then log . LogInfo $ "Changed to user " ++ fromJust (cRunUserName cfg)+ else log . LogError $ "Could not change UID: not started as root!" liftIO $ ready