packages feed

keyring 0.1.0.3 → 0.1.0.4

raw patch · 12 files changed

+277/−249 lines, 12 filesdep ~basedep ~utf8-stringPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, utf8-string

API changes (from Hackage documentation)

Files

CHANGES.md view
@@ -1,3 +1,8 @@+0.1.0.4 (Apr 30, 2015)+======================++- Add support for GHC 7.10+ 0.1.0.3 (Apr 12, 2014) ====================== 
Example.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2014 Sebastian Wiesner <lunaryorn@gmail.com>+-- Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>  -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2014 Sebastian Wiesner <lunaryorn@gmail.com>+Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in
README.md view
@@ -1,9 +1,9 @@ haskell-keyring =============== -[![travis][badge-travis]][travis]-[![hackage][badge-hackage]][hackage]-[![license][badge-license]][license]+[![Available on Hackage][badge-hackage]][hackage]+[![License MIT][badge-license]][license]+[![Build Status][badge-travis]][travis]  Haskell library to access the system's keyring to securely store passwords. @@ -73,7 +73,7 @@ License ------- -Copyright (c) 2014 Sebastian Wiesner <lunaryorn@gmail.com>+Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in
keyring.cabal view
@@ -1,5 +1,5 @@ name:                keyring-version:             0.1.0.3+version:             0.1.0.4 synopsis:            Keyring access description:   keyring provides access to the system's keyring to securely store passwords.@@ -21,8 +21,8 @@ extra-source-files:  README.md,                      CHANGES.md author:              Sebastian Wiesner-maintainer:          lunaryorn@gmail.com-copyright:           (C) 2014 Sebastian Wiesner+maintainer:          swiesner@lunaryorn.com+copyright:           (C) 2014, 2015 Sebastian Wiesner category:            System build-type:          Simple cabal-version:       >=1.10@@ -35,7 +35,7 @@ source-repository this   type:              git   location:          https://github.com/lunaryorn/haskell-keyring.git-  tag:               0.1.0.3+  tag:               0.1.0.4  flag AllBackends   description:         Try to build as many backends as possible@@ -52,14 +52,15 @@   ghc-options:         -Wall   exposed-modules:     System.Keyring   other-modules:       System.Keyring.Types-  build-depends:       base >=4.6 && <4.8+  build-depends:       base >=4.6 && <4.9   default-language:    Haskell2010    if os(darwin)      cpp-options:      -DDARWIN      exposed-modules:  System.Keyring.Darwin+     other-modules:    System.Keyring.Darwin.Native      build-tools:      hsc2hs-     build-depends:    utf8-string >=0.3 && <0.4,+     build-depends:    utf8-string >=1 && <1.1,                        bytestring >=0.10 && <0.11      frameworks:       Security CoreFoundation 
src/System/Keyring.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2014 Sebastian Wiesner <lunaryorn@gmail.com>+-- Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>  -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal
+ src/System/Keyring/Darwin.hs view
@@ -0,0 +1,171 @@+-- Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>++-- Permission is hereby granted, free of charge, to any person obtaining a copy+-- of this software and associated documentation files (the "Software"), to deal+-- in the Software without restriction, including without limitation the rights+-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+-- copies of the Software, and to permit persons to whom the Software is+-- furnished to do so, subject to the following conditions:++-- The above copyright notice and this permission notice shall be included in+-- all copies or substantial portions of the Software.++-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+-- THE SOFTWARE.++{-# LANGUAGE DeriveDataTypeable #-}++-- |Access to the OS X Keychain.+--+-- This module is only available on OS X.  See "System.Keyring.Unix" for keyring+-- support on other Unix systems.+module System.Keyring.Darwin+       (+         -- * Keychain access+         setPassword+       , getPassword+         -- * Error handling+       , KeychainError(..)+       , OSStatus+       ) where++import System.Keyring.Types+import System.Keyring.Darwin.Native++import qualified Data.ByteString.UTF8 as UTF8++import Control.Exception (Exception(..),bracket,throwIO)+import Control.Monad (liftM,when,unless,void)+import Data.ByteString (ByteString,useAsCStringLen,packCString,packCStringLen)+import Data.Typeable (Typeable,cast)+import Foreign.C (CString,CStringLen)+import Foreign.Ptr (Ptr,nullPtr)+import Foreign.Storable (peek)+import Foreign.Marshal.Alloc (alloca,allocaBytes)+import Text.Printf (printf)++data KeychainError =+  -- |@'KeychainError' message status@ denotes an error which occurred when+  -- accessing Keychain.+  --+  -- @message@ is the human-readable error message reported by the system, and+  -- @status@ is the internal status code.+  --+  -- See <https://developer.apple.com/library/mac/documentation/security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898-CH5g-CJBEABHG Keychain Services Result Codes>+  -- for a list of all status codes.+  --+  -- Note that this error is /not/ thrown for the status codes+  -- @errSecItemNotFound@ and @errSecAuthFailed@.  For these status codes,+  -- 'getPassword' simply returns 'Nothing'.+  KeychainError (Maybe String) OSStatus deriving Typeable++instance Show KeychainError where+  show (KeychainError Nothing status) =+    printf "Keychain access failed: status %s" status+  show (KeychainError (Just msg) status) =+    printf "Keychain access failed: %s (status %d)" msg status++instance Exception KeychainError where+  toException = toException . KeyringError+  fromException x = do+    KeyringError e <- fromException x+    cast e++throwKeychainError :: OSStatus -> IO a+throwKeychainError status = do+  messageResult <- secKeychainCopyErrorMessageString status+  let message = fmap UTF8.toString messageResult+  throwIO (KeychainError message status)++secKeychainCopyErrorMessageString :: OSStatus -> IO (Maybe ByteString)+secKeychainCopyErrorMessageString status =+  bracket+  (c_SecCopyErrorMessageString status nullPtr)+  (\s -> when (s /= nullPtr) (c_CFRelease s))+  convertCFString+  where+    convertCFString s | s == nullPtr = return Nothing+    convertCFString s = do+      let encoding = kCFStringEncodingUTF8+      let bufferSize = c_CFStringGetMaximumSizeForEncoding (c_CFStringGetLength s) encoding+      allocaBytes (fromIntegral bufferSize) (getCString s encoding bufferSize)+    getCString s encoding bufferSize buffer = do+      result <- c_CFStringGetCString s buffer bufferSize encoding+      if result+        then liftM Just (packCString buffer)+        else return Nothing++secKeychainFindGenericPassword :: ByteString -> ByteString -> IO (Maybe ByteString)+secKeychainFindGenericPassword service username =+  useAsCStringLen service withService+  where+    withService c_service = useAsCStringLen username (withServiceAndUser c_service)+    withServiceAndUser c_service c_user = alloca (withPwLen c_service c_user)+    withPwLen c_service c_user pwlen = alloca (withAll c_service c_user pwlen)+    withAll :: CStringLen -> CStringLen -> Ptr UInt32 -> Ptr CString -> IO (Maybe ByteString)+    withAll (c_service_b, c_service_l) (c_user_b, c_user_l) password_l_buf password_buf =+      do+        result <- c_SecKeychainFindGenericPassword+                   nullPtr      -- Default keychain+                   (fromIntegral c_service_l) c_service_b+                   (fromIntegral c_user_l) c_user_b+                   password_l_buf password_buf+                   nullPtr      -- Ignore the item reference+        bracket (peek password_buf)+         (\pw -> when (pw /= nullPtr)+                 (void $ c_SecKeychainItemFreeContent nullPtr pw))+         (handleResult result password_l_buf)+    handleResult :: OSStatus -> Ptr UInt32 -> CString -> IO (Maybe ByteString)+    handleResult result password_l_buf password_b = case result of+      _ | result == errSecSuccess -> do+        password_l <- peek password_l_buf+        liftM Just (packCStringLen (password_b, fromIntegral password_l))+      _ | result == errSecItemNotFound ||+          result == errSecAuthFailed -> return Nothing+      _ -> throwKeychainError result++secKeychainAddGenericPassword :: ByteString -> ByteString -> ByteString -> IO ()+secKeychainAddGenericPassword service username password =+  useAsCStringLen service withService+  where+    withService c_service = useAsCStringLen username (withServiceAndUser c_service)+    withServiceAndUser c_service c_username =+      useAsCStringLen password (withAll c_service c_username)+    withAll (c_service_b, c_service_l) (c_user_b, c_user_l) (c_pw_b, c_pw_l) = do+      result <- c_SecKeychainAddGenericPassword+                nullPtr         -- Default keychain+                (fromIntegral c_service_l) c_service_b+                (fromIntegral c_user_l) c_user_b+                (fromIntegral c_pw_l) c_pw_b+                nullPtr         -- Ignore the item+      unless (result == errSecSuccess) (throwKeychainError result)++-- |@'setPassword' service username password@ adds @password@ for @username@+-- to the user's keychain.+--+-- @username@ is the name of the user whose password to set.  @service@+-- identifies the application which sets the password.+--+-- This function throws 'KeychainError' if access to the Keychain failed.+setPassword :: Service -> Username -> Password -> IO ()+setPassword (Service service) (Username username) (Password password) =+  secKeychainAddGenericPassword service_bytes username_bytes password_bytes+  where service_bytes = UTF8.fromString service+        username_bytes = UTF8.fromString username+        password_bytes = UTF8.fromString password++-- |@'getPassword' service username@ gets password for a given @username@ and+-- @service@.  If the password was not found, return 'Nothing' instead.+--+-- This function throws 'KeychainError' if access to the Keychain failed.+getPassword :: Service -> Username -> IO (Maybe Password)+getPassword (Service service) (Username username) = do+  password_bytes <- secKeychainFindGenericPassword service_bytes username_bytes+  return (fmap (Password . UTF8.toString) password_bytes)+  where service_bytes = UTF8.fromString service+        username_bytes = UTF8.fromString username
− src/System/Keyring/Darwin.hsc
@@ -1,233 +0,0 @@--- Copyright (c) 2014 Sebastian Wiesner <lunaryorn@gmail.com>---- Permission is hereby granted, free of charge, to any person obtaining a copy--- of this software and associated documentation files (the "Software"), to deal--- in the Software without restriction, including without limitation the rights--- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell--- copies of the Software, and to permit persons to whom the Software is--- furnished to do so, subject to the following conditions:---- The above copyright notice and this permission notice shall be included in--- all copies or substantial portions of the Software.---- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR--- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,--- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE--- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER--- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,--- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN--- THE SOFTWARE.--{-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE DeriveDataTypeable #-}---- |Access to the OS X Keychain.------ This module is only available on OS X.  See "System.Keyring.Unix" for keyring--- support on other Unix systems.-module System.Keyring.Darwin-       (-         -- * Keychain access-         setPassword-       , getPassword-         -- * Error handling-       , KeychainError(..)-       , OSStatus-       ) where--import System.Keyring.Types--import qualified Data.ByteString.UTF8 as UTF8--import Control.Exception (Exception(..),bracket,throwIO)-import Control.Monad (liftM,when,void)-import Data.ByteString (ByteString,useAsCStringLen,packCString,packCStringLen)-import Data.Int (Int32, Int64)-import Data.Typeable (Typeable,cast)-import Data.Word (Word32)-import Foreign.C (CString,CStringLen)-import Foreign.Ptr (Ptr,nullPtr)-import Foreign.Storable (peek)-import Foreign.Marshal.Alloc (alloca,allocaBytes)-import Text.Printf (printf)---- C declarations--#include <Security/Security.h>--type UInt32 = #type UInt32-type CFTypeRef = Ptr ()-type CFStringRef = Ptr ()-type CFStringEncoding = #type CFStringEncoding-type CFIndex = #type CFIndex-type SecKeychainItemRef = Ptr ()-type SecKeychainRef = Ptr ()---- |An internal OS X status code.-type OSStatus = #type OSStatus--#{enum OSStatus, ,-  errSecSuccess = errSecSuccess,-  errSecItemNotFound = errSecItemNotFound,-  errSecAuthFailed = errSecAuthFailed}--kCFStringEncodingUTF8 :: CFStringEncoding-kCFStringEncodingUTF8 = #const kCFStringEncodingUTF8--foreign import ccall unsafe "CoreFoundation/CoreFoundation.h CFRelease"-  c_CFRelease :: CFTypeRef -> IO ()--foreign import ccall unsafe "CoreFoundation/CoreFoundation.h CFStringGetMaximumSizeForEncoding"-  c_CFStringGetMaximumSizeForEncoding :: CFIndex -> CFStringEncoding -> CFIndex--foreign import ccall unsafe "CoreFoundation/CoreFoundation.h CFStringGetLength"-  c_CFStringGetLength :: CFStringRef -> CFIndex--foreign import ccall unsafe "CoreFoundation/CoreFoundation.h CFStringGetCString"-  c_CFStringGetCString :: CFStringRef -> CString -> CFIndex -> CFStringEncoding-                       -> IO Bool--foreign import ccall unsafe "Security/Security.h SecCopyErrorMessageString"-  c_SecCopyErrorMessageString :: OSStatus -> Ptr () -> IO CFStringRef--foreign import ccall unsafe "Security/Security.h SecKeychainItemFreeContent"-  c_SecKeychainItemFreeContent :: Ptr () -> CString -> IO OSStatus--foreign import ccall unsafe "Security/Security.h SecKeychainFindGenericPassword"-  c_SecKeychainFindGenericPassword :: CFTypeRef-                                   -> UInt32 -> CString-                                   -> UInt32 -> CString-                                   -> Ptr UInt32 -> Ptr CString-                                   -> Ptr SecKeychainItemRef-                                   -> IO OSStatus--foreign import ccall unsafe "Security/Security.h SecKeychainAddGenericPassword"-  c_SecKeychainAddGenericPassword :: SecKeychainRef-                                  -> UInt32 -> CString-                                  -> UInt32 -> CString-                                  -> UInt32 -> CString-                                  -> Ptr SecKeychainItemRef-                                  -> IO OSStatus---- C wrappers--data KeychainError =-  -- |@'KeychainError' message status@ denotes an error which occurred when-  -- accessing Keychain.-  ---  -- @message@ is the human-readable error message reported by the system, and-  -- @status@ is the internal status code.-  ---  -- See <https://developer.apple.com/library/mac/documentation/security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/uid/TP30000898-CH5g-CJBEABHG Keychain Services Result Codes>-  -- for a list of all status codes.-  ---  -- Note that this error is /not/ thrown for the status codes-  -- @errSecItemNotFound@ and @errSecAuthFailed@.  For these status codes,-  -- 'getPassword' simply returns 'Nothing'.-  KeychainError (Maybe String) OSStatus deriving Typeable--instance Show KeychainError where-  show (KeychainError Nothing status) =-    printf "Keychain access failed: status %s" status-  show (KeychainError (Just msg) status) =-    printf "Keychain access failed: %s (status %d)" msg status--instance Exception KeychainError where-  toException = toException . KeyringError-  fromException x = do-    KeyringError e <- fromException x-    cast e--throwKeychainError :: OSStatus -> IO a-throwKeychainError status = do-  messageResult <- secKeychainCopyErrorMessageString status-  let message = (fmap UTF8.toString messageResult)-  throwIO (KeychainError message status)--secKeychainCopyErrorMessageString :: OSStatus -> IO (Maybe ByteString)-secKeychainCopyErrorMessageString status =-  bracket-  (c_SecCopyErrorMessageString status nullPtr)-  (\s -> when (s /= nullPtr) (c_CFRelease s))-  (convertCFString)-  where-    convertCFString s | s == nullPtr = return Nothing-    convertCFString s = do-      let encoding = kCFStringEncodingUTF8-      let bufferSize = c_CFStringGetMaximumSizeForEncoding (c_CFStringGetLength s) encoding-      allocaBytes (fromIntegral bufferSize) (getCString s encoding bufferSize)-    getCString s encoding bufferSize buffer = do-      result <- c_CFStringGetCString s buffer bufferSize encoding-      if result-        then liftM Just (packCString buffer)-        else return Nothing--secKeychainFindGenericPassword :: ByteString -> ByteString -> IO (Maybe ByteString)-secKeychainFindGenericPassword service username = do-  useAsCStringLen service withService-  where-    withService c_service = useAsCStringLen username (withServiceAndUser c_service)-    withServiceAndUser c_service c_user = alloca (withPwLen c_service c_user)-    withPwLen c_service c_user pwlen = alloca (withAll c_service c_user pwlen)-    withAll :: CStringLen -> CStringLen -> Ptr UInt32 -> Ptr CString -> IO (Maybe ByteString)-    withAll (c_service_b, c_service_l) (c_user_b, c_user_l) password_l_buf password_buf =-      do-        result <- c_SecKeychainFindGenericPassword-                   nullPtr      -- Default keychain-                   (fromIntegral c_service_l) c_service_b-                   (fromIntegral c_user_l) c_user_b-                   password_l_buf password_buf-                   nullPtr      -- Ignore the item reference-        (bracket (peek password_buf)-         (\pw -> when (pw /= nullPtr)-                 (void $ c_SecKeychainItemFreeContent nullPtr pw))-         (handleResult result password_l_buf))-    handleResult :: OSStatus -> Ptr UInt32 -> CString -> IO (Maybe ByteString)-    handleResult result password_l_buf password_b = case result of-      _ | result == errSecSuccess -> do-        password_l <- peek password_l_buf-        liftM Just (packCStringLen (password_b, fromIntegral password_l))-      _ | result == errSecItemNotFound ||-          result == errSecAuthFailed -> return Nothing-      _ -> throwKeychainError result--secKeychainAddGenericPassword :: ByteString -> ByteString -> ByteString -> IO ()-secKeychainAddGenericPassword service username password = do-  useAsCStringLen service withService-  where-    withService c_service = useAsCStringLen username (withServiceAndUser c_service)-    withServiceAndUser c_service c_username =-      useAsCStringLen password (withAll c_service c_username)-    withAll (c_service_b, c_service_l) (c_user_b, c_user_l) (c_pw_b, c_pw_l) = do-      result <- c_SecKeychainAddGenericPassword-                nullPtr         -- Default keychain-                (fromIntegral c_service_l) c_service_b-                (fromIntegral c_user_l) c_user_b-                (fromIntegral c_pw_l) c_pw_b-                nullPtr         -- Ignore the item-      if result == errSecSuccess then return () else throwKeychainError result---- |@'setPassword' service username password@ adds @password@ for @username@--- to the user's keychain.------ @username@ is the name of the user whose password to set.  @service@--- identifies the application which sets the password.------ This function throws 'KeychainError' if access to the Keychain failed.-setPassword :: Service -> Username -> Password -> IO ()-setPassword (Service service) (Username username) (Password password) =-  secKeychainAddGenericPassword service_bytes username_bytes password_bytes-  where service_bytes = UTF8.fromString service-        username_bytes = UTF8.fromString username-        password_bytes = UTF8.fromString password---- |@'getPassword' service username@ gets password for a given @username@ and--- @service@.  If the password was not found, return 'Nothing' instead.------ This function throws 'KeychainError' if access to the Keychain failed.-getPassword :: Service -> Username -> IO (Maybe Password)-getPassword (Service service) (Username username) = do-  password_bytes <- secKeychainFindGenericPassword service_bytes username_bytes-  return (fmap Password (fmap (UTF8.toString) password_bytes))-  where service_bytes = UTF8.fromString service-        username_bytes = UTF8.fromString username
+ src/System/Keyring/Darwin/Native.hsc view
@@ -0,0 +1,84 @@+-- Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>++-- Permission is hereby granted, free of charge, to any person obtaining a copy+-- of this software and associated documentation files (the "Software"), to deal+-- in the Software without restriction, including without limitation the rights+-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+-- copies of the Software, and to permit persons to whom the Software is+-- furnished to do so, subject to the following conditions:++-- The above copyright notice and this permission notice shall be included in+-- all copies or substantial portions of the Software.++-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+-- THE SOFTWARE.++{-# LANGUAGE ForeignFunctionInterface #-}++module System.Keyring.Darwin.Native where++import Data.Int (Int32, Int64)+import Data.Word (Word32)+import Foreign.C (CString)+import Foreign.Ptr (Ptr)++#include <Security/Security.h>++type UInt32 = #type UInt32+type CFTypeRef = Ptr ()+type CFStringRef = Ptr ()+type CFStringEncoding = #type CFStringEncoding+type CFIndex = #type CFIndex+type SecKeychainItemRef = Ptr ()+type SecKeychainRef = Ptr ()++-- |An internal OS X status code.+type OSStatus = #type OSStatus++#{enum OSStatus, ,+  errSecSuccess = errSecSuccess,+  errSecItemNotFound = errSecItemNotFound,+  errSecAuthFailed = errSecAuthFailed}++kCFStringEncodingUTF8 :: CFStringEncoding+kCFStringEncodingUTF8 = #const kCFStringEncodingUTF8++foreign import ccall unsafe "CoreFoundation/CoreFoundation.h CFRelease"+  c_CFRelease :: CFTypeRef -> IO ()++foreign import ccall unsafe "CoreFoundation/CoreFoundation.h CFStringGetMaximumSizeForEncoding"+  c_CFStringGetMaximumSizeForEncoding :: CFIndex -> CFStringEncoding -> CFIndex++foreign import ccall unsafe "CoreFoundation/CoreFoundation.h CFStringGetLength"+  c_CFStringGetLength :: CFStringRef -> CFIndex++foreign import ccall unsafe "CoreFoundation/CoreFoundation.h CFStringGetCString"+  c_CFStringGetCString :: CFStringRef -> CString -> CFIndex -> CFStringEncoding+                       -> IO Bool++foreign import ccall unsafe "Security/Security.h SecCopyErrorMessageString"+  c_SecCopyErrorMessageString :: OSStatus -> Ptr () -> IO CFStringRef++foreign import ccall unsafe "Security/Security.h SecKeychainItemFreeContent"+  c_SecKeychainItemFreeContent :: Ptr () -> CString -> IO OSStatus++foreign import ccall safe "Security/Security.h SecKeychainFindGenericPassword"+  c_SecKeychainFindGenericPassword :: CFTypeRef+                                   -> UInt32 -> CString+                                   -> UInt32 -> CString+                                   -> Ptr UInt32 -> Ptr CString+                                   -> Ptr SecKeychainItemRef+                                   -> IO OSStatus++foreign import ccall safe "Security/Security.h SecKeychainAddGenericPassword"+  c_SecKeychainAddGenericPassword :: SecKeychainRef+                                  -> UInt32 -> CString+                                  -> UInt32 -> CString+                                  -> UInt32 -> CString+                                  -> Ptr SecKeychainItemRef+                                  -> IO OSStatus
src/System/Keyring/Types.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2014 Sebastian Wiesner <lunaryorn@gmail.com>+-- Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>  -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal
src/System/Keyring/Unix.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2014 Sebastian Wiesner <lunaryorn@gmail.com>+-- Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>  -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal
src/System/Keyring/Unix/KDE.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2014 Sebastian Wiesner <lunaryorn@gmail.com>+-- Copyright (c) 2014 Sebastian Wiesner <swiesner@lunaryorn.com>  -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal