auth :: Auth -> (S.ByteString -> IO a) -> Failure a -> Handle -> IO a
auth (Plain u w) success next h = do
    sendRequest  opSaslAuth "PLAIN" 0 nop (S.length u + S.length w + 2) pokeCred 0 (CAS 0) h
    peekResponse consumeResponse next h
  where
    ul = S.length u
    pokeCred p = do
        pokeWord8 p 0
        pokeByteString (plusPtr p        1) u
        pokeWord8      (plusPtr p $ ul + 1) 0
        pokeByteString (plusPtr p $ ul + 2) w

    consumeResponse p = do
        l <- getTotalLength p
        success =<< S.hGet h (fromIntegral l)
auth :: Auth -> (S.ByteString -> IO a) -> Failure a -> Handle -> IO a
auth (Plain u w) success next h = do
    sendRequest  opSaslAuth "PLAIN" 0 nop (S.length u + S.length w + 2) pokeCred 0 (CAS 0) h
    peekResponse consumeResponse next h
  where
    ul = S.length u
    pokeCred p = do
        pokeWord8 p 0
        pokeByteString (plusPtr p        1) u
        pokeWord8      (plusPtr p $ ul + 1) 0
        pokeByteString (plusPtr p $ ul + 2) w

    consumeResponse p = do
        l <- getTotalLength p
        success =<< S.hGet h (fromIntegral l)
auth (Plain u w) success next h = do
    sendRequest  opSaslAuth "PLAIN" 0 nop (S.length u + S.length w + 2) pokeCred 0 (CAS 0) h
    peekResponse consumeResponse next h
  where
    ul = S.length u
    pokeCred p = do
        pokeWord8 p 0
        pokeByteString (plusPtr p        1) u
        pokeWord8      (plusPtr p $ ul + 1) 0
        pokeByteString (plusPtr p $ ul + 2) w

    consumeResponse p = do
        l <- getTotalLength p
        success =<< S.hGet h (fromIntegral l)