authenticateWithKey :: Session  -- ^ Session to use
                    -> String   -- ^ Username
                    -> FilePath -- ^ Path to the public key (e.g. ~/.ssh/id_rsa.pub)
                    -> FilePath -- ^ Path to the private key (e.g. ~/.ssh/id_rsa)
                    -> String   -- ^ Passphrase
                    -> SimpleSSH Session
authenticateWithKey session username publicKeyPath privateKeyPath passphrase = liftIOEither $ do
  (usernameC, publicKeyPathC, privateKeyPathC, passphraseC) <-
    (,,,) <$> newCString username
          <*> newCString publicKeyPath
          <*> newCString privateKeyPath
          <*> newCString passphrase

  res <- liftEitherC (return . Session) $ authenticateKeyC session usernameC publicKeyPathC privateKeyPathC passphraseC

  mapM_ free [usernameC, publicKeyPathC, privateKeyPathC, passphraseC]

  return res

-- | Send a command to the server.
--
-- One should be authenticated before sending commands on a 'Session'.
authenticateWithKey :: Session  -- ^ Session to use
                    -> String   -- ^ Username
                    -> FilePath -- ^ Path to the public key (e.g. ~/.ssh/id_rsa.pub)
                    -> FilePath -- ^ Path to the private key (e.g. ~/.ssh/id_rsa)
                    -> String   -- ^ Passphrase
                    -> SimpleSSH Session
authenticateWithKey session username publicKeyPath privateKeyPath passphrase = liftIOEither $ do
  (usernameC, publicKeyPathC, privateKeyPathC, passphraseC) <-
    (,,,) <$> newCString username
          <*> newCString publicKeyPath
          <*> newCString privateKeyPath
          <*> newCString passphrase

  res <- liftEitherC (return . Session) $ authenticateKeyC session usernameC publicKeyPathC privateKeyPathC passphraseC

  mapM_ free [usernameC, publicKeyPathC, privateKeyPathC, passphraseC]

  return res

-- | Send a command to the server.
--
-- One should be authenticated before sending commands on a 'Session'.
authenticateWithKey session username publicKeyPath privateKeyPath passphrase = liftIOEither $ do
  (usernameC, publicKeyPathC, privateKeyPathC, passphraseC) <-
    (,,,) <$> newCString username
          <*> newCString publicKeyPath
          <*> newCString privateKeyPath
          <*> newCString passphrase

  res <- liftEitherC (return . Session) $ authenticateKeyC session usernameC publicKeyPathC privateKeyPathC passphraseC

  mapM_ free [usernameC, publicKeyPathC, privateKeyPathC, passphraseC]

  return res

-- | Send a command to the server.
--
-- One should be authenticated before sending commands on a 'Session'.