%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see .
\ignore{
\begin{code}
module DBus.Protocol.Authentication (authenticate) where
import Data.Char (ord)
import Data.Word (Word32)
import Data.List (isPrefixOf)
import System.Posix.User (getRealUserID)
import Text.Printf (printf)
\end{code}
}
\section{Authentication}
\begin{code}
authenticate :: (String -> IO ()) -> (Word32 -> IO String)
-> IO ()
authenticate put get = do
put "\x00"
\end{code}
{\tt EXTERNAL} authentication is performed using the process's real user
ID, converted to a string, and then hex-encoded.
\begin{code}
uid <- getRealUserID
let authToken = concatMap (printf "%02X" . ord) (show uid)
put $ "AUTH EXTERNAL " ++ authToken ++ "\r\n"
\end{code}
If authentication was successful, the server responds with {\tt OK
}. The GUID is intended to enable connection sharing, which
is currently unimplemented, so it's ignored.
\begin{code}
response <- readUntil '\n' get
if "OK" `isPrefixOf` response
then put "BEGIN\r\n"
else do
putStrLn $ "response = " ++ show response
error "Server rejected authentication token."
\end{code}
\begin{code}
readUntil :: Monad m => Char -> (Word32 -> m String) -> m String
readUntil = readUntil' ""
readUntil' :: Monad m => String -> Char -> (Word32 -> m String) -> m String
readUntil' xs c f = do
[x] <- f 1
let xs' = xs ++ [x]
if x == c
then return xs'
else readUntil' xs' c f
\end{code}