packages feed

strongswan-sql 1.0.0.0 → 1.0.1.0

raw patch · 11 files changed

+530/−95 lines, 11 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- StrongSwan.SQL: Any :: AuthMethod
+ StrongSwan.SQL: ASN1ID :: Maybe Int -> [ASN1] -> Identity
+ StrongSwan.SQL: AnyAuth :: AuthMethod
+ StrongSwan.SQL: AnyID :: Maybe Int -> Identity
+ StrongSwan.SQL: EmailID :: Maybe Int -> String -> String -> Identity
+ StrongSwan.SQL: IPv4AddrID :: Maybe Int -> IPv4 -> Identity
+ StrongSwan.SQL: IPv6AddrID :: Maybe Int -> IPv6 -> Identity
+ StrongSwan.SQL: NameID :: Maybe Int -> String -> Identity
+ StrongSwan.SQL: OpaqueID :: Maybe Int -> ByteString -> Identity
+ StrongSwan.SQL: SharedEAP :: SharedSecretType
+ StrongSwan.SQL: SharedIKE :: SharedSecretType
+ StrongSwan.SQL: SharedPIN :: SharedSecretType
+ StrongSwan.SQL: SharedRSA :: SharedSecretType
+ StrongSwan.SQL: SharedSecret :: Maybe Int -> SharedSecretType -> ByteString -> SharedSecret
+ StrongSwan.SQL: SharedSecretIdentity :: Int -> Int -> SharedSecretIdentity
+ StrongSwan.SQL: [_identityId] :: SharedSecretIdentity -> Int
+ StrongSwan.SQL: [_sharedSecretId] :: SharedSecretIdentity -> Int
+ StrongSwan.SQL: [_ssData] :: SharedSecret -> ByteString
+ StrongSwan.SQL: [_ssId] :: SharedSecret -> Maybe Int
+ StrongSwan.SQL: [_ssType] :: SharedSecret -> SharedSecretType
+ StrongSwan.SQL: addSecret :: (Failable m, MonadIO m) => Identity -> SharedSecret -> Context -> m Identity
+ StrongSwan.SQL: data Identity
+ StrongSwan.SQL: data SharedSecret
+ StrongSwan.SQL: data SharedSecretIdentity
+ StrongSwan.SQL: data SharedSecretType
+ StrongSwan.SQL: deleteIdentity :: (Failable m, MonadIO m) => Int -> Context -> m (Result Int)
+ StrongSwan.SQL: deleteSSIdentity :: (Failable m, MonadIO m) => SharedSecretIdentity -> Context -> m (Result (Int, Int))
+ StrongSwan.SQL: deleteSharedSecret :: (Failable m, MonadIO m) => Int -> Context -> m (Result Int)
+ StrongSwan.SQL: findIdentity :: (Failable m, MonadIO m) => Int -> Context -> m Identity
+ StrongSwan.SQL: findIdentityBySelf :: (Failable m, MonadIO m) => Identity -> Context -> m Identity
+ StrongSwan.SQL: findSSIdentity :: (Failable m, MonadIO m) => Int -> Context -> m [SharedSecretIdentity]
+ StrongSwan.SQL: findSharedSecret :: (Failable m, MonadIO m) => Int -> Context -> m SharedSecret
+ StrongSwan.SQL: identityId :: Lens' SharedSecretIdentity Int
+ StrongSwan.SQL: removeIdentity :: (Failable m, MonadIO m) => Identity -> Context -> m ()
+ StrongSwan.SQL: removeSecret :: (Failable m, MonadIO m) => Identity -> SharedSecretType -> Context -> m ()
+ StrongSwan.SQL: sharedSecretId :: Lens' SharedSecretIdentity Int
+ StrongSwan.SQL: ssData :: Lens' SharedSecret ByteString
+ StrongSwan.SQL: ssId :: Lens' SharedSecret (Maybe Int)
+ StrongSwan.SQL: ssType :: Lens' SharedSecret SharedSecretType
+ StrongSwan.SQL: writeIdentity :: (Failable m, MonadIO m) => Identity -> Context -> m (Result Int)
+ StrongSwan.SQL: writeSSIdentity :: (Failable m, MonadIO m) => SharedSecretIdentity -> Context -> m (Result (Int, Int))
+ StrongSwan.SQL: writeSharedSecret :: (Failable m, MonadIO m) => SharedSecret -> Context -> m (Result Int)

Files

app/CLI/Commands.hs view
@@ -4,6 +4,7 @@  import CLI.Commands.ChildSA import CLI.Commands.Common+import CLI.Commands.Identity import CLI.Commands.PeerCfg import CLI.Commands.TrafficSelector import CLI.Types@@ -48,7 +49,13 @@           showTrafficSelector' getRemoteTrafficSelector       exitCmd     showConnection+    command "remove" "Wipes out this connection from the DB" $ do+      db       <- use dbContext+      ipsecCfg <- use ipsecSettings+      void . runMaybeT $ deleteIPSecSettings ipsecCfg db+      return NoAction     exitCmd+  cfgIdentity   where setConnection name = do           db <- use dbContext           result <- runMaybeT $ findIPSecSettings name db
app/CLI/Commands/Common.hs view
@@ -9,23 +9,34 @@ import Control.Monad.Trans.Maybe           (MaybeT(..), runMaybeT) import Control.Monad.State.Strict          (StateT, lift) import Data.Bool                           (bool)-import Data.IP                             (IP)+import Data.ByteString.Char8               (ByteString)+import Data.IP                             (IP, IPv4, IPv6) import Data.List                           (find) import Data.Text                           (Text, pack) import Text.Read                           (readMaybe) import StrongSwan.SQL                      (SQLRow) import System.Console.StructuredCLI hiding (Commands) -import qualified StrongSwan.SQL as SQL+import qualified Data.ByteString.Char8 as B+import qualified StrongSwan.SQL        as SQL  string :: (Monad m) => String -> m (Maybe Text) string = return . Just . pack +bytes :: (Monad m) => String -> m (Maybe ByteString)+bytes = return . Just . B.pack+ integer :: (Monad m, Integral n ) => String -> m (Maybe n) integer = return . fmap fromIntegral . readMaybe @Integer  ipAddress :: (Monad m) => String -> m (Maybe IP) ipAddress = return . readMaybe++ipV4Address :: (Monad m) => String -> m (Maybe IPv4)+ipV4Address = return . readMaybe++ipV6Address :: (Monad m) => String -> m (Maybe IPv6)+ipV6Address = return . readMaybe  boolean :: (Monad m) => String -> String -> String -> m (Maybe Bool) boolean yes no str | str == yes = return $ Just True
+ app/CLI/Commands/Identity.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE FlexibleContexts #-}++module CLI.Commands.Identity where++import Control.Lens                        ((.=), use)+import Control.Monad                       (void)+import Control.Monad.Trans.Maybe           (MaybeT(..), runMaybeT)+import CLI.Commands.Common+import CLI.Types+import Data.Default                        (def)+import Data.Maybe                          (fromMaybe)+import Control.Monad.State.Strict          (StateT, lift)+import StrongSwan.SQL+import System.Console.StructuredCLI hiding (Commands)++secretType' :: (Monad m) => Validator m SharedSecretType+secretType' = return . fromName++cfgIdentity :: Commands ()+cfgIdentity =+  command "identity" "Identity configuration" newLevel >+ do+    command "any" "Matches any ID" (setIdentity $ AnyID Nothing) >+ do+      identityCmds+    param "ipv4" "<IPv4 address>" ipV4Address (setIdentity . IPv4AddrID Nothing) >+ do+      identityCmds+    param "ipv4" "<IPv6 address>" ipV6Address (setIdentity . IPv6AddrID Nothing) >+ do+      identityCmds++cfgSecret :: Commands ()+cfgSecret =+  param "shared-secret" "<shared secret>" bytes setSecret >+ do+    param "type" "<psk|eap|rsa|pin>" secretType' $ \sType -> do+      db    <- use dbContext+      ident <- use identity+      str   <- use secretStr+      let secret = def { _ssData = str, _ssType = sType }+      ident' <- lift $ addSecret ident secret db+      identity .= ident'+      return NoAction+        where setSecret str = do+                secretStr .= str+                return NewLevel++setIdentity :: Identity -> StateT AppState IO Action+setIdentity ident = do+  db <- use dbContext+  result <- runMaybeT $ findIdentityBySelf ident db+  identity .= fromMaybe ident result+  return NewLevel++removeIdent :: Commands ()+removeIdent =+  command "remove" "delete identity from DB and all associated secrets, etc" $ do+    db <- use dbContext+    ident <- use identity+    void . runMaybeT $ removeIdentity ident db+    return NoAction++identityCmds :: Commands ()+identityCmds = do+  removeIdent+  cfgSecret+  exitCmd
app/CLI/Types.hs view
@@ -7,6 +7,7 @@ import Control.Monad.Failable       (Failable(..)) import Control.Monad.State.Strict   (StateT) import Control.Exception            (Exception)+import Data.ByteString              (ByteString) import Data.Char                    (toLower) import Data.Default import Data.Text                    (Text)@@ -36,6 +37,8 @@                   _options       :: Options,                   _dbContext     :: SQL.Context,                   _ipsecSettings :: SQL.IPSecSettings,+                  _identity      :: SQL.Identity,+                  _secretStr     :: ByteString,                   _flush         :: Maybe (StateT AppState IO Action)                 } @@ -110,7 +113,7 @@  instance Nameable SQL.AuthMethod where     nameOf = fmap toLower . show-    fromName "any"   = return SQL.Any+    fromName "any"   = return SQL.AnyAuth     fromName "rsa"   = return SQL.PubKey     fromName "psk"   = return SQL.PSK     fromName "eap"   = return SQL.EAP@@ -123,4 +126,18 @@     fromName "ipv4" = return SQL.IPv4AddrRange     fromName "ipv6" = return SQL.IPv6AddrRange     fromName str    = failure $ InvalidValue str++instance Nameable SQL.SharedSecretType where+    nameOf SQL.SharedIKE = "psk"+    nameOf SQL.SharedEAP = "eap"+    nameOf SQL.SharedRSA = "rsa"+    nameOf SQL.SharedPIN = "pin"+    fromName "psk" = return SQL.SharedIKE+    fromName "eap" = return SQL.SharedEAP+    fromName "rsa" = return SQL.SharedRSA+    fromName "pin" = return SQL.SharedPIN+    fromName str    = failure $ InvalidValue str+++ 
app/Main.hs view
@@ -42,9 +42,13 @@         let state = AppState { _options       = options',                                _dbContext     = db,                                _ipsecSettings = def,-                               _flush         = Nothing }-        runCLI "strongswan SQL" def commands `evalStateT` state >>= hoist FatalError+                               _flush         = Nothing,+                               _identity      = def,+                               _secretStr     = "" }+        runCLI "strongswan SQL" cliSettings commands `evalStateT` state >>= hoist FatalError           where mkContext' Options{..} = SQL.mkContext _settings+                cliSettings = def { getHistory = Just ".strongswan-sql.history" }+ modifySettings :: (SQL.Settings -> SQL.Settings) -> ArgsParser () modifySettings = (settings %=) 
src/StrongSwan/SQL.hs view
@@ -37,6 +37,9 @@                         writeIPSecSettings,                         findIPSecSettings,                         deleteIPSecSettings,+                        addSecret,+                        removeSecret,+                        removeIdentity, -- * Manual API -- | The different strongswan configuration elements are mapped to a Haskell type and they -- can be manually written or read from the SQL database. This offers utmost control in@@ -65,21 +68,31 @@                          writeChild2TSConfig,                         writeChildSAConfig,+                        writeIdentity,                         writeIKEConfig,                         writePeerConfig,                         writePeer2ChildConfig,+                        writeSharedSecret,+                        writeSSIdentity,                         writeTrafficSelector,                         lookupChild2TSConfig,                         findChildSAConfig,                         findChildSAConfigByName,+                        findIdentity,+                        findIdentityBySelf,                         findIKEConfig,                         findPeerConfig,                         findPeerConfigByName,                         findPeer2ChildConfig,+                        findSharedSecret,+                        findSSIdentity,                         findTrafficSelector,                         deleteChild2TSConfig,                         deleteChildSAConfig,+                        deleteIdentity,                         deleteIKEConfig,+                        deleteSharedSecret,+                        deleteSSIdentity,                         deletePeer2ChildConfig,                         deletePeerConfig, -- #Lenses#@@ -100,6 +113,7 @@                         CertPolicy(..),                         Context,                         EAPType(..),+                        Identity(..),                         IKEConfig(..),                         IPSecSettings(..),                         PeerConfig(..),@@ -108,6 +122,9 @@                         SAAction(..),                         SAMode(..),                         Settings(..),+                        SharedSecret(..),+                        SharedSecretIdentity(..),+                        SharedSecretType(..),                         SQL.OK(..),                         SQLRow,                         TrafficSelector(..),@@ -117,13 +134,13 @@  import Control.Concurrent.MVar      (MVar, newMVar, withMVar) import Control.Lens                 ((^.), (.=), makeLenses, use)-import Control.Monad                (void, when)+import Control.Monad                (mapM_, void, when) import Control.Monad.IO.Class       (MonadIO) import Control.Monad.Trans.Maybe    (MaybeT(..), runMaybeT) import Control.Monad.State.Strict   (MonadTrans, StateT, execStateT, get, lift) import Data.ByteString.Char8        (pack, unpack) import Data.Default                 (Default(..))-import Data.Maybe                   (isNothing, isJust, fromJust, listToMaybe)+import Data.Maybe                   (catMaybes, isNothing, isJust, fromJust, listToMaybe) import Data.Text                    (Text) import Database.MySQL.Base          (MySQLConn) import Control.Monad.Failable@@ -352,6 +369,50 @@                 tsCfgId <- MaybeT . return $ _tsId sel                 lift $ inContext deleteTrafficSelector tsCfgId +-- | Adds a shared secret to a given identity. If the identity doesn't exist it will get created.+-- If the identity already exists and it already has a secret of the same type, it will be overwritten.+-- This means there can only be one secret of any given type per identity (which makes sense of course+-- from strongswan's perspective).+addSecret :: (Failable m, MonadIO m) => Identity -> SharedSecret -> Context -> m Identity+addSecret identity secret context = do+  let ?context = context+  result      <- runMaybeT $ findIdentityBySelf' identity+  identity'   <- maybe newIdentity return result+  removeSecret identity' (_ssType secret) context+  Result {..} <- writeSharedSecret' secret+  void $ writeSSIdentity' SharedSecretIdentity { _sharedSecretId = lastModifiedKey,+                                                 _identityId     = fromJust $ getIdentityId identity' }+  return identity'+    where newIdentity = do+            Result {..} <- writeIdentity identity context+            return $ setIdentityId identity lastModifiedKey++-- | Removes a secret of the given type (if present) from the specified identity+removeSecret :: (Failable m, MonadIO m) => Identity -> SharedSecretType -> Context -> m ()+removeSecret identity sType context =+  void . runMaybeT $ do+    let ?context = context+    identId      <- MaybeT . return $ getIdentityId identity+    ssIdentities <- findSSIdentity' identId+    secrets      <- mapM (findSharedSecret' . _sharedSecretId) ssIdentities+    let toDelete      = catMaybes $ _ssId <$> filter ((sType ==) . _ssType) secrets+        ssIdentities' = filter (\ss2Id -> elem (_sharedSecretId ss2Id) toDelete) ssIdentities+    mapM_ deleteSharedSecret' toDelete+    mapM_ deleteSSIdentity' ssIdentities'++-- | Removes an identity and its secrets and related entries altogether+removeIdentity :: (Failable m, MonadIO m) => Identity -> Context -> m ()+removeIdentity identity context =+  void . runMaybeT $ do+    let ?context = context+    identId      <- MaybeT . return $ getIdentityId identity+    ssIdentities <- findSSIdentity' identId+    mapM_ (deleteSharedSecret' . _sharedSecretId) ssIdentities+    mapM_ deleteSSIdentity' ssIdentities+    deleteIdentity' identId++-- manual API+ writeChildSAConfig :: (Failable m, MonadIO m) => ChildSAConfig -> Context -> m (Result Int) writeChildSAConfig cfg = withContext writeChildSAConfig''     where writeChildSAConfig'' context@Context_ { prepared_ = PreparedStatements {..}} =@@ -460,3 +521,94 @@     where deleteChild2TSConfig' Context_ { prepared_ = PreparedStatements {..}, ..} = do             ok@SQL.OK {..} <- SQL.executeStmt conn_ deleteC2TSStmt [toSQL $ toInt iD]             return Result { lastModifiedKey = okLastInsertID, response = ok }++writeIdentity :: (Failable m, MonadIO m) => Identity -> Context -> m (Result Int)+writeIdentity identity = withContext writeIdentity''+    where writeIdentity'' context@Context_ { prepared_ = PreparedStatements {..}, ..} =+            writeRow context updateIdentityStmt createIdentityStmt getIdentityId identity++findIdentity :: (Failable m, MonadIO m) => Int -> Context -> m Identity+findIdentity iD context =+  justOne ("findIdentity" <> Text.pack (show iD)) =<<+    retrieveRows findIdentityStmt [toSQL $ toInt iD] context++findIdentityBySelf :: (Failable m, MonadIO m) => Identity -> Context -> m Identity+findIdentityBySelf identity context =+  justOne ("findIdentityBySelf" <> Text.pack (show identity)) =<<+    retrieveRows findIdentityBySelfStmt (toValues identity) context++findIdentityBySelf' :: (Failable m, MonadIO m, ?context::Context ) => Identity -> m Identity+findIdentityBySelf' = flip findIdentityBySelf ?context++deleteIdentity :: (Failable m, MonadIO m) => Int -> Context -> m (Result Int)+deleteIdentity iD = withContext deleteIdentity''+    where deleteIdentity'' Context_ { prepared_ = PreparedStatements {..}, ..} = do+            ok@SQL.OK {..} <- SQL.executeStmt conn_ deleteIdentityStmt [toSQL $ toInt iD]+            return Result { lastModifiedKey = okLastInsertID, response = ok }++deleteIdentity' :: (Failable m, MonadIO m, ?context::Context) => Int -> m (Result Int)+deleteIdentity' = flip deleteIdentity ?context++writeSharedSecret :: (Failable m, MonadIO m) => SharedSecret -> Context -> m (Result Int)+writeSharedSecret ss = withContext writeSS+    where writeSS context@Context_ { prepared_ = PreparedStatements{..}, ..} =+            writeRow context updateSharedSecretStmt createSharedSecretStmt _ssId ss++writeSharedSecret' :: (Failable m, MonadIO m, ?context::Context) => SharedSecret -> m (Result Int)+writeSharedSecret' = flip writeSharedSecret ?context++findSharedSecret :: (Failable m, MonadIO m) => Int -> Context -> m SharedSecret+findSharedSecret iD context =+  justOne ("SharedSecret" <> Text.pack (show iD)) =<<+    retrieveRows findSharedSecretStmt [toSQL . toInt $ iD] context++findSharedSecret' :: (Failable m, MonadIO m, ?context::Context) => Int -> m SharedSecret+findSharedSecret' = flip findSharedSecret ?context++deleteSharedSecret :: (Failable m, MonadIO m) => Int -> Context -> m (Result Int)+deleteSharedSecret iD = withContext deleteSS+    where deleteSS Context_ { prepared_ = PreparedStatements {..}, ..} = do+            ok@SQL.OK {..} <- SQL.executeStmt conn_ deleteSharedSecretStmt [toSQL $ toInt iD]+            return Result { lastModifiedKey = okLastInsertID, response = ok }++deleteSharedSecret' :: (Failable m, MonadIO m, ?context::Context) => Int -> m (Result Int)+deleteSharedSecret' = flip deleteSharedSecret ?context++writeSSIdentity :: (Failable m, MonadIO m) => SharedSecretIdentity -> Context -> m (Result (Int, Int))+writeSSIdentity ssIdent@SharedSecretIdentity {..} = withContext writeSSIdentity''+    where writeSSIdentity'' Context_{ prepared_ = PreparedStatements {..}, ..} = do+            result@SQL.OK {..} <- SQL.executeStmt conn_ updateSSIdentityStmt $ sqlValues ++ selector+            result' <- if okAffectedRows == 0+                         then SQL.executeStmt conn_ createSSIdentityStmt sqlValues+                         else return result+            return Result { lastModifiedKey = (_sharedSecretId, _identityId),+                            response = result' }+          sqlValues = toValues ssIdent+          selector  = toSQL . toInt <$> [_sharedSecretId, _identityId]++writeSSIdentity' :: (Failable m, MonadIO m, ?context::Context) => SharedSecretIdentity -> m (Result (Int, Int))+writeSSIdentity' = flip writeSSIdentity ?context++findSSIdentity :: (Failable m, MonadIO m) => Int -> Context -> m [SharedSecretIdentity]+findSSIdentity iD = retrieveRows findSSIdentityStmt [toSQL . toInt $ iD]++findSSIdentity' :: (Failable m, MonadIO m, ?context::Context) => Int -> m [SharedSecretIdentity]+findSSIdentity' = flip findSSIdentity ?context++deleteSSIdentity :: (Failable m, MonadIO m) => SharedSecretIdentity -> Context -> m (Result (Int, Int))+deleteSSIdentity SharedSecretIdentity {..} = withContext deleteSSIdentity''+    where deleteSSIdentity'' Context_ { prepared_ = PreparedStatements {..}, ..} = do+            ok@SQL.OK {..} <- SQL.executeStmt conn_ deleteSSIdentityStmt values+            return Result { lastModifiedKey = (_sharedSecretId, _identityId), response = ok }+          values = toSQL . toInt <$> [_sharedSecretId, _identityId]++deleteSSIdentity' :: (Failable m, MonadIO m, ?context::Context) => SharedSecretIdentity -> m (Result (Int, Int))+deleteSSIdentity' = flip deleteSSIdentity ?context++++++++
src/StrongSwan/SQL/Encoding.hs view
@@ -54,22 +54,25 @@     fromSQL SQL.MySQLNull         = NullChar     fromSQL v                     = throw $ InvalidValueForType "VarChar" (show v) +fromId :: SQL.MySQLValue -> Maybe Int+fromId = return . fromInt . fromSQL+ instance SQLRow Identity where-    toValues AnyID                  = [toSQL $ toTinyInt (0::Word8),  toSQL $ toVarBinary "%any"]-    toValues (IPv4AddrID v4)        = [toSQL $ toTinyInt (1::Word8),  toSQL $ toVarBinary v4]-    toValues (NameID str)           = [toSQL $ toTinyInt (2::Word8),  toSQL $ toVarBinary str]-    toValues (EmailID local domain) = [toSQL $ toTinyInt (3::Word8),  toSQL $ toVarBinary (local ++ '@':domain)]-    toValues (IPv6AddrID v6)        = [toSQL $ toTinyInt (5::Word8),  toSQL $ toVarBinary v6]-    toValues (ASN1ID elements)      = [toSQL $ toTinyInt (9::Word8),  toSQL $ toVarBinary (encodeASN1' DER elements)]-    toValues (OpaqueID bytes)       = [toSQL $ toTinyInt (11::Word8), toSQL $ toVarBinary bytes]+    toValues (AnyID _)                = [toSQL $ toTinyInt (0::Word8),  toSQL $ toVarBinary "%any"]+    toValues (IPv4AddrID _ v4)        = [toSQL $ toTinyInt (1::Word8),  toSQL $ toVarBinary v4]+    toValues (NameID _ str)           = [toSQL $ toTinyInt (2::Word8),  toSQL $ toVarBinary str]+    toValues (EmailID _ local domain) = [toSQL $ toTinyInt (3::Word8),  toSQL $ toVarBinary (local ++ '@':domain)]+    toValues (IPv6AddrID _ v6)        = [toSQL $ toTinyInt (5::Word8),  toSQL $ toVarBinary v6]+    toValues (ASN1ID _ elements)      = [toSQL $ toTinyInt (9::Word8),  toSQL $ toVarBinary (encodeASN1' DER elements)]+    toValues (OpaqueID _ bytes)       = [toSQL $ toTinyInt (11::Word8), toSQL $ toVarBinary bytes] -    fromValues [SQL.MySQLInt8U 0, _] = AnyID-    fromValues [SQL.MySQLInt8U 1, v] = IPv4AddrID . fromVarBinary $ fromSQL v-    fromValues [SQL.MySQLInt8U 2, v] = NameID . fromVarBinary $ fromSQL v-    fromValues [SQL.MySQLInt8U 3, v] = uncurry EmailID . parseEmail . fromVarBinary $ fromSQL v-    fromValues [SQL.MySQLInt8U 5, v] = IPv6AddrID . fromVarBinary $ fromSQL v-    fromValues [SQL.MySQLInt8U 9, v] = ASN1ID . either throw id . decodeASN1' DER . fromVarBinary $ fromSQL v-    fromValues v                     = throw $ SQLValuesMismatch "Identity" (show v)+    fromValues [iD, SQL.MySQLInt8U 0, _] = AnyID      (fromId iD)+    fromValues [iD, SQL.MySQLInt8U 1, v] = IPv4AddrID (fromId iD) . fromVarBinary $ fromSQL v+    fromValues [iD, SQL.MySQLInt8U 2, v] = NameID     (fromId iD) . fromVarBinary $ fromSQL v+    fromValues [iD, SQL.MySQLInt8U 3, v] = uncurry (EmailID $ fromId iD)  . parseEmail . fromVarBinary $ fromSQL v+    fromValues [iD, SQL.MySQLInt8U 5, v] = IPv6AddrID (fromId iD) . fromVarBinary $ fromSQL v+    fromValues [iD, SQL.MySQLInt8U 9, v] = ASN1ID     (fromId iD) . either throw id . decodeASN1' DER . fromVarBinary $ fromSQL v+    fromValues v                         = throw $ SQLValuesMismatch "Identity" (show v)  parseEmail :: ByteString -> (String, String) parseEmail = second (drop 1) . span (/= '@') . unpack@@ -266,6 +269,27 @@                             c2tsTrafficSelectorKind  = fromTinyInt $ fromSQL trafficSelectorKind                       }     fromValues xs = throw $ SQLValuesMismatch "Child2TSConfig" (show xs)++instance SQLRow SharedSecret where+    toValues SharedSecret {..} = [+        toSQL $ toTinyInt _ssType,+        toSQL $ toVarBinary _ssData ]+    fromValues (iD : sharedSecretType : sharedSecretData : []) =+        SharedSecret {+              _ssId   = return . fromInt $ fromSQL iD,+              _ssType = fromTinyInt $ fromSQL sharedSecretType,+              _ssData = fromVarBinary $ fromSQL sharedSecretData+        }+    fromValues xs = throw $ SQLValuesMismatch "SharedSecret" (show xs)++instance SQLRow SharedSecretIdentity where+    toValues SharedSecretIdentity {..} = toSQL . toInt <$> [_sharedSecretId, _identityId]+    fromValues [ssId, identityId] = SharedSecretIdentity {+                                          _sharedSecretId = fromInt $ fromSQL ssId,+                                          _identityId     = fromInt $ fromSQL identityId+                                    }+    fromValues xs = throw $ SQLValuesMismatch "SharedSecretIdentity" (show xs)+  encodeHex :: ByteString -> String encodeHex = B.foldr showHex ""
src/StrongSwan/SQL/Lenses.hs view
@@ -9,4 +9,6 @@ makeLenses ''ChildSAConfig makeLenses ''PeerConfig makeLenses ''TrafficSelector+makeLenses ''SharedSecret+makeLenses ''SharedSecretIdentity makeLenses ''IPSecSettings
src/StrongSwan/SQL/Statements.hs view
@@ -61,6 +61,28 @@                         findC2TSStatement,                         deleteC2TSStatement] +    [createIdentity, updateIdentity, findIdentity, findIdentityBySelf, deleteIdentity] <-+        initializeWith createIdentityTable+                        [createIdentityStatement,+                         updateIdentityStatement,+                         findIdentityStatement,+                         findIdentityBySelfStatement,+                         deleteIdentityStatement]++    [createSharedSecret, updateSharedSecret, findSharedSecret, deleteSharedSecret] <-+        initializeWith createSharedSecretTable+                        [createSharedSecretStatement,+                         updateSharedSecretStatement,+                         findSharedSecretStatement,+                         deleteSharedSecretStatement]++    [createSSIdentity, updateSSIdentity, findSSIdentity, deleteSSIdentity] <-+        initializeWith createSSIdentityTable+                        [createSSIdentityStatement,+                         updateSSIdentityStatement,+                         findSSIdentityStatement,+                         deleteSSIdentityStatement]+     [createIPSec, findIPSec, deleteIPSec] <-         initializeWith createIPSecTableStatement                        [createIPSecStatement,@@ -68,35 +90,48 @@                         deleteIPSecStatement]      return PreparedStatements  {-        updateChildSAStmt     = updateChildSA,-        createChildSAStmt     = createChildSA,-        findChildSAByNameStmt = findChildSAByName,-        findChildSAStmt       = findChildSA,-        deleteChildSAStmt     = deleteChildSA,-        updateIKEStmt         = updateIKE,-        createIKEStmt         = createIKE,-        findIKEStmt           = findIKE,-        deleteIKEStmt         = deleteIKE,-        updatePeerStmt        = updatePeer,-        createPeerStmt        = createPeer,-        findPeerStmt          = findPeer,-        findPeerByNameStmt    = findPeerByName,-        deletePeerStmt        = deletePeer,-        updateP2CStmt         = updateP2C,-        createP2CStmt         = createP2C,-        findP2CStmt           = findP2C,-        deleteP2CStmt         = deleteP2C,-        findTSStmt            = findTS,-        createTSStmt          = createTS,-        updateTSStmt          = updateTS,-        deleteTSStmt          = deleteTS,-        updateC2TSStmt        = updateC2TS,-        createC2TSStmt        = createC2TS,-        findC2TSStmt          = findC2TS,-        deleteC2TSStmt        = deleteC2TS,-        createIPSecStmt       = createIPSec,-        findIPSecStmt         = findIPSec,-        deleteIPSecStmt       = deleteIPSec+        updateChildSAStmt      = updateChildSA,+        createChildSAStmt      = createChildSA,+        findChildSAByNameStmt  = findChildSAByName,+        findChildSAStmt        = findChildSA,+        deleteChildSAStmt      = deleteChildSA,+        updateIKEStmt          = updateIKE,+        createIKEStmt          = createIKE,+        findIKEStmt            = findIKE,+        deleteIKEStmt          = deleteIKE,+        updatePeerStmt         = updatePeer,+        createPeerStmt         = createPeer,+        findPeerStmt           = findPeer,+        findPeerByNameStmt     = findPeerByName,+        deletePeerStmt         = deletePeer,+        updateP2CStmt          = updateP2C,+        createP2CStmt          = createP2C,+        findP2CStmt            = findP2C,+        deleteP2CStmt          = deleteP2C,+        findTSStmt             = findTS,+        createTSStmt           = createTS,+        updateTSStmt           = updateTS,+        deleteTSStmt           = deleteTS,+        updateC2TSStmt         = updateC2TS,+        createC2TSStmt         = createC2TS,+        findC2TSStmt           = findC2TS,+        deleteC2TSStmt         = deleteC2TS,+        updateIdentityStmt     = updateIdentity,+        createIdentityStmt     = createIdentity,+        findIdentityStmt       = findIdentity,+        findIdentityBySelfStmt = findIdentityBySelf,+        deleteIdentityStmt     = deleteIdentity,+        updateSharedSecretStmt = updateSharedSecret,+        createSharedSecretStmt = createSharedSecret,+        findSharedSecretStmt   = findSharedSecret,+        deleteSharedSecretStmt = deleteSharedSecret,+        updateSSIdentityStmt   = updateSSIdentity,+        createSSIdentityStmt   = createSSIdentity,+        findSSIdentityStmt     = findSSIdentity,+        deleteSSIdentityStmt   = deleteSSIdentity,+        createIPSecStmt        = createIPSec,+        findIPSecStmt          = findIPSec,+        deleteIPSecStmt        = deleteIPSec     }  prepare :: (?conn :: MySQLConn, Failable m, MonadIO m) => SQL.Query -> m SQL.StmtID@@ -197,6 +232,54 @@  deleteC2TSStatement :: SQL.Query deleteC2TSStatement = "DELETE FROM child_config_traffic_selector WHERE child_cfg = ?;"++createSharedSecretTable :: SQL.Query+createSharedSecretTable = "CREATE TABLE shared_secrets (`id` int(10) unsigned NOT NULL auto_increment, `type` tinyint(3) unsigned NOT NULL, `data` varbinary(256) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"++createSharedSecretStatement :: SQL.Query+createSharedSecretStatement = "INSERT INTO shared_secrets (type, data) VALUES (?, ?);"++updateSharedSecretStatement :: SQL.Query+updateSharedSecretStatement = "UPDATE shared_secrets SET type = ?, data = ? WHERE id = ?;"++findSharedSecretStatement :: SQL.Query+findSharedSecretStatement = "SELECT * FROM shared_secrets WHERE id = ?;"++deleteSharedSecretStatement :: SQL.Query+deleteSharedSecretStatement = "DELETE FROM shared_secrets WHERE id = ?;"++createIdentityTable :: SQL.Query+createIdentityTable = "CREATE TABLE `identities` (`id` int(10) unsigned NOT NULL auto_increment, `type` tinyint(4) unsigned NOT NULL, `data` varbinary(64) NOT NULL, PRIMARY KEY (`id`), UNIQUE (`type`, `data`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"++createIdentityStatement  :: SQL.Query+createIdentityStatement = "INSERT INTO identities (type, data) VALUES (?, ?);"++updateIdentityStatement :: SQL.Query+updateIdentityStatement = "UPDATE identities SET type = ?, data = ? WHERE id = ?;"++findIdentityStatement :: SQL.Query+findIdentityStatement = "SELECT * FROM identities WHERE id = ?;"++findIdentityBySelfStatement :: SQL.Query+findIdentityBySelfStatement = "SELECT * FROM identities WHERE type = ? AND data = ?;"++deleteIdentityStatement :: SQL.Query+deleteIdentityStatement = "DELETE FROM identities WHERE id = ?;"++createSSIdentityTable  :: SQL.Query+createSSIdentityTable = "CREATE TABLE shared_secret_identity (`shared_secret` int(10) unsigned NOT NULL, `identity` int(10) unsigned NOT NULL, PRIMARY KEY (`shared_secret`, `identity`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"++createSSIdentityStatement :: SQL.Query+createSSIdentityStatement = "INSERT INTO shared_secret_identity (shared_secret, identity) VALUES (?, ?);"++updateSSIdentityStatement :: SQL.Query+updateSSIdentityStatement = "UPDATE shared_secret_identity SET shared_secret = ?, identity = ? WHERE shared_secret = ? AND identity = ?;"++findSSIdentityStatement :: SQL.Query+findSSIdentityStatement = "SELECT * from shared_secret_identity WHERE identity = ?;"++deleteSSIdentityStatement :: SQL.Query+deleteSSIdentityStatement = "DELETE FROM shared_secret_identity WHERE shared_secret = ? AND identity = ?;"  createIPSecTableStatement :: SQL.Query createIPSecTableStatement = "CREATE TABLE `ipsec_configs` (`name` varchar(64) NOT NULL, `child_cfg` int(10) unsigned NOT NULL, `peer_cfg` int(10) unsigned NOT NULL, `ike_cfg` int(10) unsigned NOT NULL, `local_ts` int(10) unsigned NOT NULL, `remote_ts` int(10) unsigned NOT NULL, PRIMARY KEY (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"
src/StrongSwan/SQL/Types.hs view
@@ -29,6 +29,7 @@            | UnknownEAPType Int            | UnknownTrafficSelectorType Int            | UnknownTrafficSelectorKind Int+           | UnknownSharedSecretType Int            | InvalidValueForType String String            | SQLValuesMismatch String String            | NotFound Text@@ -66,14 +67,36 @@   toEnum 60  = UTF32   toEnum x   = throw $ UnknownCharacterEncoding x -data Identity = AnyID                 -- Matches any ID (/%any/)-              | IPv4AddrID IPv4       -- IPv4 Address-              | NameID String         -- Fully qualified Domain Name-              | EmailID String String -- ^ RFC 822 Email Address /mailbox/@/domain/-              | IPv6AddrID IPv6       -- IPv6 Address-              | ASN1ID [ASN1]-              | OpaqueID ByteString   -- Opaque octet string as ID+data Identity = AnyID (Maybe Int)                 -- Matches any ID (/%any/)+              | IPv4AddrID (Maybe Int) IPv4       -- IPv4 Address+              | NameID (Maybe Int) String         -- Fully qualified Domain Name+              | EmailID (Maybe Int) String String -- ^ RFC 822 Email Address /mailbox/@/domain/+              | IPv6AddrID (Maybe Int) IPv6       -- IPv6 Address+              | ASN1ID (Maybe Int) [ASN1]         -- DER encoded ASN.1 distinguished name+              | OpaqueID (Maybe Int) ByteString   -- Opaque octet string as ID+              deriving Show +getIdentityId :: Identity -> Maybe Int+getIdentityId (AnyID iD)        = iD+getIdentityId (IPv4AddrID iD _) = iD+getIdentityId (NameID iD _)     = iD+getIdentityId (EmailID iD _ _)  = iD+getIdentityId (IPv6AddrID iD _) = iD+getIdentityId (ASN1ID iD _)     = iD+getIdentityId (OpaqueID iD _)   = iD++setIdentityId :: Identity -> Int -> Identity+setIdentityId (AnyID _)        iD = AnyID (Just iD)+setIdentityId (IPv4AddrID _ x) iD = IPv4AddrID (Just iD) x+setIdentityId (NameID _ x)     iD = NameID (Just iD) x+setIdentityId (EmailID _ x y)  iD = EmailID (Just iD) x y+setIdentityId (IPv6AddrID _ x) iD = IPv6AddrID (Just iD) x+setIdentityId (ASN1ID _ x)     iD = ASN1ID (Just iD) x+setIdentityId (OpaqueID _ x)   iD = OpaqueID (Just iD) x++instance Default Identity where+    def = AnyID Nothing+ data Value (a :: k -> SQL.MySQLValue) where     TinyInt   :: Word8      -> Value 'SQL.MySQLInt8U     SmallInt  :: Word16     -> Value 'SQL.MySQLInt16U@@ -131,6 +154,10 @@   toTinyInt = toSQLEnum   fromTinyInt = fromSQLEnum +instance TinyInt SharedSecretType where+  toTinyInt = toSQLEnum+  fromTinyInt = fromSQLEnum+ class SmallInt a where     toSmallInt   :: a -> Value 'SQL.MySQLInt16U     fromSmallInt :: Value 'SQL.MySQLInt16U -> a@@ -236,7 +263,7 @@     toEnum 2 = NeverSend     toEnum x = throw $ UnknownCertPolicy x -data AuthMethod = Any+data AuthMethod = AnyAuth                 | PubKey                 | PSK                 | EAP@@ -244,13 +271,13 @@                 deriving (Eq, Show)  instance Enum AuthMethod where-    fromEnum Any    = 0-    fromEnum PubKey = 1-    fromEnum PSK    = 2-    fromEnum EAP    = 3-    fromEnum XAUTH  = 4+    fromEnum AnyAuth = 0+    fromEnum PubKey  = 1+    fromEnum PSK     = 2+    fromEnum EAP     = 3+    fromEnum XAUTH   = 4 -    toEnum 0 = Any+    toEnum 0 = AnyAuth     toEnum 1 = PubKey     toEnum 2 = PSK     toEnum 3 = EAP@@ -318,6 +345,23 @@       toEnum 3 = RemoteDynamicTS       toEnum x = throw $ UnknownTrafficSelectorKind x +data SharedSecretType = SharedIKE+                      | SharedEAP+                      | SharedRSA+                      | SharedPIN+                      deriving (Eq, Show)++instance Enum SharedSecretType where+      fromEnum SharedIKE = 1+      fromEnum SharedEAP = 2+      fromEnum SharedRSA = 3+      fromEnum SharedPIN = 4+      toEnum 1 = SharedIKE+      toEnum 2 = SharedEAP+      toEnum 3 = SharedRSA+      toEnum 4 = SharedPIN+      toEnum x = throw $ UnknownSharedSecretType x+ data IKEConfig = IKEConfig {                     _ikeId            :: Maybe Int,                     _ikeReqCert       :: Bool,@@ -453,36 +497,63 @@                             c2tsTrafficSelectorKind  :: TrafficSelectorKind                       } deriving Show +data SharedSecret = SharedSecret {+                        _ssId   :: Maybe Int,+                        _ssType :: SharedSecretType,+                        _ssData :: ByteString+                      } deriving Show++instance Default SharedSecret where+    def = SharedSecret Nothing SharedIKE ""++data SharedSecretIdentity = SharedSecretIdentity {+                                  _sharedSecretId :: Int,+                                  _identityId     :: Int+                            }+ data PreparedStatements = PreparedStatements {-                              updateChildSAStmt     :: SQL.StmtID,-                              createChildSAStmt     :: SQL.StmtID,-                              findChildSAStmt       :: SQL.StmtID,-                              findChildSAByNameStmt :: SQL.StmtID,-                              deleteChildSAStmt     :: SQL.StmtID,-                              updateIKEStmt         :: SQL.StmtID,-                              createIKEStmt         :: SQL.StmtID,-                              findIKEStmt           :: SQL.StmtID,-                              deleteIKEStmt         :: SQL.StmtID,-                              updatePeerStmt        :: SQL.StmtID,-                              createPeerStmt        :: SQL.StmtID,-                              findPeerStmt          :: SQL.StmtID,-                              findPeerByNameStmt    :: SQL.StmtID,-                              deletePeerStmt        :: SQL.StmtID,-                              updateP2CStmt         :: SQL.StmtID,-                              createP2CStmt         :: SQL.StmtID,-                              findP2CStmt           :: SQL.StmtID,-                              deleteP2CStmt         :: SQL.StmtID,-                              updateTSStmt          :: SQL.StmtID,-                              createTSStmt          :: SQL.StmtID,-                              findTSStmt            :: SQL.StmtID,-                              deleteTSStmt          :: SQL.StmtID,-                              updateC2TSStmt        :: SQL.StmtID,-                              createC2TSStmt        :: SQL.StmtID,-                              findC2TSStmt          :: SQL.StmtID,-                              deleteC2TSStmt        :: SQL.StmtID,-                              createIPSecStmt       :: SQL.StmtID,-                              findIPSecStmt         :: SQL.StmtID,-                              deleteIPSecStmt       :: SQL.StmtID+                              updateChildSAStmt      :: SQL.StmtID,+                              createChildSAStmt      :: SQL.StmtID,+                              findChildSAStmt        :: SQL.StmtID,+                              findChildSAByNameStmt  :: SQL.StmtID,+                              deleteChildSAStmt      :: SQL.StmtID,+                              updateIKEStmt          :: SQL.StmtID,+                              createIKEStmt          :: SQL.StmtID,+                              findIKEStmt            :: SQL.StmtID,+                              deleteIKEStmt          :: SQL.StmtID,+                              updatePeerStmt         :: SQL.StmtID,+                              createPeerStmt         :: SQL.StmtID,+                              findPeerStmt           :: SQL.StmtID,+                              findPeerByNameStmt     :: SQL.StmtID,+                              deletePeerStmt         :: SQL.StmtID,+                              updateP2CStmt          :: SQL.StmtID,+                              createP2CStmt          :: SQL.StmtID,+                              findP2CStmt            :: SQL.StmtID,+                              deleteP2CStmt          :: SQL.StmtID,+                              updateTSStmt           :: SQL.StmtID,+                              createTSStmt           :: SQL.StmtID,+                              findTSStmt             :: SQL.StmtID,+                              deleteTSStmt           :: SQL.StmtID,+                              updateC2TSStmt         :: SQL.StmtID,+                              createC2TSStmt         :: SQL.StmtID,+                              findC2TSStmt           :: SQL.StmtID,+                              deleteC2TSStmt         :: SQL.StmtID,+                              updateIdentityStmt     :: SQL.StmtID,+                              createIdentityStmt     :: SQL.StmtID,+                              findIdentityStmt       :: SQL.StmtID,+                              findIdentityBySelfStmt :: SQL.StmtID,+                              deleteIdentityStmt     :: SQL.StmtID,+                              updateSharedSecretStmt :: SQL.StmtID,+                              createSharedSecretStmt :: SQL.StmtID,+                              findSharedSecretStmt   :: SQL.StmtID,+                              deleteSharedSecretStmt :: SQL.StmtID,+                              updateSSIdentityStmt   :: SQL.StmtID,+                              createSSIdentityStmt   :: SQL.StmtID,+                              findSSIdentityStmt     :: SQL.StmtID,+                              deleteSSIdentityStmt   :: SQL.StmtID,+                              createIPSecStmt        :: SQL.StmtID,+                              findIPSecStmt          :: SQL.StmtID,+                              deleteIPSecStmt        :: SQL.StmtID                           } deriving Show  -- | The managed IPsec configuration type encompasses a complete set of elements which are pushed and interlinked
strongswan-sql.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: df70c57c8e5221e054346a59c78abfe9477cb3ae1e175f69d1def6b29fe3f9da+-- hash: 60f2148a71514af362ac55216959613c573fd36159eb6446d93d1a2bf439a397  name:           strongswan-sql-version:        1.0.0.0+version:        1.0.1.0 synopsis:       Interface library for strongSwan SQL backend description:    Interface library and companion CLI tool to configure strongSwan IPsec over MySQL backend category:       Console, Library, Network APIs, SQL@@ -65,6 +65,7 @@       CLI.Commands       CLI.Commands.ChildSA       CLI.Commands.Common+      CLI.Commands.Identity       CLI.Commands.PeerCfg       CLI.Commands.TrafficSelector   hs-source-dirs: