diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 LIBS=-lssh2
-GHC=ghc $(LIBS) --make
+GHC=ghc $(LIBS) -isrc/ --make
 C2HS=c2hs -C"-Iinclude/"
-HSFILES=Network/SSH/Client/LibSSH2.hs Network/SSH/Client/LibSSH2/Types.hs Network/SSH/Client/LibSSH2/Errors.hs Network/SSH/Client/LibSSH2/Foreign.hs
+HSFILES=src/Network/SSH/Client/LibSSH2.hs src/Network/SSH/Client/LibSSH2/Types.hs src/Network/SSH/Client/LibSSH2/Errors.hs src/Network/SSH/Client/LibSSH2/Foreign.hs
 
 all: ssh-client
 
diff --git a/libssh2.cabal b/libssh2.cabal
--- a/libssh2.cabal
+++ b/libssh2.cabal
@@ -1,6 +1,6 @@
 Name:                libssh2
 
-Version:             0.2.0.1
+Version:             0.2.0.2
 
 Synopsis:            FFI bindings to libssh2 SSH2 client library (http://libssh2.org/)
 
@@ -42,6 +42,10 @@
 -- Constraint on the version of Cabal needed to build this package.
 Cabal-version:       >=1.8
 
+flag gcrypt
+  description: add hack that allows to run threaded program when libssh2 is built against gcrypt
+  default: False
+
 flag example-client
   description: Build the example client
   default: False
@@ -68,10 +72,16 @@
   
   Build-tools:         c2hs
   HS-Source-Dirs:      src
+
+  if flag(gcrypt)
+      c-sources:           src/Network/SSH/Client/LibSSH2/FFI/gcrypt-fix.c
+      Includes:            gcrypt-fix.h
+      Exposed-modules:     Network.SSH.Client.LibSSH2.GCrypt
+      Cpp-options:         -DGCRYPT
   
 Executable hs-ssh-client
   if flag(example-client)
-    Build-depends: base, utf8-string, libssh2 >= 0.2, syb, network, filepath, bytestring
+    Build-depends: base, utf8-string, libssh2 >= 0.2, syb, network, filepath, bytestring, time
   else
     buildable: False
   Main-Is: ssh-client.hs
diff --git a/src/Network/SSH/Client/LibSSH2.hs b/src/Network/SSH/Client/LibSSH2.hs
--- a/src/Network/SSH/Client/LibSSH2.hs
+++ b/src/Network/SSH/Client/LibSSH2.hs
@@ -5,6 +5,7 @@
 
    -- * Functions
    withSSH2,
+   withSSH2User,
    withSession,
    withChannel,
    withChannelBy,
@@ -17,12 +18,14 @@
    execCommands,
 
    -- * Utilities
-   socketConnect
+   socketConnect,
+   sessionInit,
+   sessionClose,
   ) where
 
 import Control.Monad
 import Control.Exception as E
-import Network
+import Network  hiding (sClose)
 import Network.BSD
 import Network.Socket
 import System.IO
@@ -62,20 +65,46 @@
     publicKeyAuthFile s login public private passphrase 
     fn s
 
+-- | Execute some actions within SSH2 connection.
+-- Uses username/password authentication.
+withSSH2User :: FilePath          -- ^ Path to known_hosts file
+         -> String            -- ^ Remote user name
+         -> String            -- ^ Remote password
+         -> String            -- ^ Remote host name
+         -> Int               -- ^ Remote port number (usually 22)
+         -> (Session -> IO a) -- ^ Actions to perform on session
+         -> IO a
+withSSH2User known_hosts login password hostname port fn =
+  withSession hostname port $ \s -> do
+    r <- checkHost s hostname port known_hosts
+    when (r == MISMATCH) $
+      error $ "Host key mismatch for host " ++ hostname
+    usernamePasswordAuth s login password
+    fn s
+
 -- | Execute some actions within SSH2 session
 withSession :: String            -- ^ Remote host name
             -> Int               -- ^ Remote port number (usually 22)
             -> (Session -> IO a) -- ^ Actions to perform on handle and session
             -> IO a
-withSession hostname port fn = do
-  sock <- socketConnect hostname port
-  session <- initSession
-  setBlocking session False
-  handshake session sock
-  result <- fn session
-  disconnectSession session "Done."
-  freeSession session
-  return result
+withSession hostname port = E.bracket (sessionInit hostname port) sessionClose
+
+--  | Initialize session to the gived host
+sessionInit :: String -> Int -> IO Session
+sessionInit hostname port = do
+      sock <- socketConnect hostname port
+      session <- initSession
+      setBlocking session False
+      handshake session sock
+      return session
+
+--  | Close active session
+sessionClose :: Session -> IO ()
+sessionClose session = do
+      disconnectSession session "Done."
+      freeSession session
+
+
 
 --  | Check remote host against known hosts list
 checkHost :: Session
diff --git a/src/Network/SSH/Client/LibSSH2/Errors.chs b/src/Network/SSH/Client/LibSSH2/Errors.chs
--- a/src/Network/SSH/Client/LibSSH2/Errors.chs
+++ b/src/Network/SSH/Client/LibSSH2/Errors.chs
@@ -79,6 +79,7 @@
   | SOCKET_RECV
   | ENCRYPT
   | BAD_SOCKET
+  | ERROR_KNOWN_HOSTS
   deriving (Eq, Show, Ord, Enum, Data, Typeable)
 
 instance Exception ErrorCode
diff --git a/src/Network/SSH/Client/LibSSH2/FFI/gcrypt-fix.c b/src/Network/SSH/Client/LibSSH2/FFI/gcrypt-fix.c
new file mode 100644
--- /dev/null
+++ b/src/Network/SSH/Client/LibSSH2/FFI/gcrypt-fix.c
@@ -0,0 +1,11 @@
+#include <gcrypt.h>
+#include <pthread.h>
+#include <error.h>
+#include <errno.h>
+#include "gcrypt-fix.h"
+
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+
+void gcrypt_fix() {
+   gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+}
diff --git a/src/Network/SSH/Client/LibSSH2/Foreign.chs b/src/Network/SSH/Client/LibSSH2/Foreign.chs
--- a/src/Network/SSH/Client/LibSSH2/Foreign.chs
+++ b/src/Network/SSH/Client/LibSSH2/Foreign.chs
@@ -21,6 +21,7 @@
 
    -- * Authentication
    publicKeyAuthFile,
+   usernamePasswordAuth,
 
    -- * Channel functions
    openChannelSession, closeChannel, freeChannel,
@@ -47,6 +48,9 @@
 
 import Network.SSH.Client.LibSSH2.Types
 import Network.SSH.Client.LibSSH2.Errors
+#ifdef GCRYPT
+import Network.SSH.Client.LibSSH2.GCrypt
+#endif
 
 -- Known host flags. See libssh2 documentation.
 data KnownHostType =
@@ -123,7 +127,11 @@
 -- | Initialize libssh2. Pass True to enable encryption
 -- or False to disable it.
 initialize :: Bool -> IO ()
+#ifdef GCRYPT
+initialize flags = void . handleInt Nothing $ gcryptFix >> initialize_ flags
+#else
 initialize flags = void . handleInt Nothing $ initialize_ flags
+#endif
 
 -- | Deinitialize libssh2.
 #ifdef mingw32_HOST_OS
@@ -229,6 +237,17 @@
                   -> IO ()
 publicKeyAuthFile session username public private passphrase = void . handleInt (Just session) $ 
   publicKeyAuthFile_ session username public private passphrase
+
+-- | Perform username/password authentication.
+usernamePasswordAuth :: Session -- ^ Session
+                     -> String  -- ^ Username
+                     -> String  -- ^ Password
+                     -> IO ()
+usernamePasswordAuth session username password =
+  withCString username $ \usernameptr -> do
+    withCString password $ \passwordptr -> do
+      void . handleInt (Just session) $
+        {# call userauth_password_ex #} (toPointer session) usernameptr (toEnum $ length username) passwordptr (toEnum $ length password) nullFunPtr
 
 {# fun channel_open_ex as openSessionChannelEx
   { toPointer `Session',
diff --git a/src/Network/SSH/Client/LibSSH2/GCrypt.hs b/src/Network/SSH/Client/LibSSH2/GCrypt.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/SSH/Client/LibSSH2/GCrypt.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+module Network.SSH.Client.LibSSH2.GCrypt 
+  ( gcryptFix )
+  where
+
+foreign import ccall "gcrypt_fix" gcryptFix :: IO ()
+
