packages feed

scan-metadata (empty) → 0.2.1.0

raw patch · 5 files changed

+199/−0 lines, 5 filesdep +aesondep +antiope-coredep +antiope-s3setup-changed

Dependencies added: aeson, antiope-core, antiope-s3, base, bytestring, containers, generic-lens, hw-aeson, hw-ip, lens, mtl, text, thyme, unliftio-core

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2019 alexeyraga++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.
+ README.md view
@@ -0,0 +1,1 @@+# scan-metadata
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ scan-metadata.cabal view
@@ -0,0 +1,41 @@+cabal-version:       2.2++name:                scan-metadata+version:             0.2.1.0+synopsis:            Metadata types for Albedo Scanners+description:         Metadata types for Albedo Scanners.+-- bug-reports:+license:             MIT+license-file:        LICENSE+author:              alexeyraga+maintainer:          alexey.raga@gmail.com+-- copyright:+category:            Data+extra-source-files:  README.md++source-repository head+  type: git+  location: https://github.com/packetloop/scan-metadata++library+  exposed-modules:+    Arbor.Albedo.Scan.Metadata+  -- other-modules:+  -- other-extensions:+  build-depends:+      base >=4.7 && <=5+    , aeson+    , antiope-core >=7.0.1+    , antiope-s3 >=7.0.1+    , bytestring+    , containers+    , generic-lens >= 1.1.0.0+    , hw-aeson >=0.1.0.1+    , hw-ip >=2.3.1.0+    , lens >= 4.17.1+    , mtl+    , text+    , thyme >=0.3.5.5+    , unliftio-core+  hs-source-dirs:      src+  default-language:    Haskell2010
+ src/Arbor/Albedo/Scan/Metadata.hs view
@@ -0,0 +1,135 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleContexts #-}+module Arbor.Albedo.Scan.Metadata+where++import Antiope.Core                          (toText, runAwsTyped)+import Antiope.Env                           (Env)+import Antiope.S3                            (S3Uri)+import Antiope.S3.Strict                     (downloadFromS3Uri)+import Control.Applicative                   ((<|>))+import Control.Lens                          (from, (&), (<&>), (^.))+import Control.Monad.Reader                  (MonadReader)+import Control.Monad.IO.Unlift               (MonadUnliftIO)+import Data.Aeson+import Data.Aeson.Types+import Data.ByteString.Lazy                  (fromStrict)+import Data.Generics.Product.Any             (the)+import Data.Generics.Product.Typed           (HasType)+import Data.Int                              (Int64)+import Data.Maybe+import Data.Thyme.Time.Core                  (UTCTime, microseconds, posixSecondsToUTCTime, toSeconds, utcTimeToPOSIXSeconds)+import GHC.Generics                          hiding (from)+import HaskellWorks.Data.Aeson+import HaskellWorks.Data.Network.Ip.Ipv4     (IpBlock)+import HaskellWorks.Data.Network.Ip.Validity (Canonical)++import qualified Data.Text as Text+++newtype Proto = Proto { unProto :: Int } deriving (Generic, Show, Eq, FromJSON, ToJSON)++data Command = Command+  { name        :: Maybe String+  , scanner     :: Maybe String+  , probe       :: Maybe String+  , probeBanner :: Maybe String -- use if zmap and zgrab use different probes(ie udp and cldap), banner-commander would prioritize probeBanner+  , probeArgs   :: Maybe String+  , port        :: Int+  , proto       :: Proto+  , destination :: Either FilePath S3Uri+  , cidr        :: IpBlock Canonical+  , deadline    :: UTCTime+  , banners     :: Bool+  } deriving (Generic, Show, Eq)++data ScanMetaData = ScanMetaData+  { startAt    :: UTCTime+  , stopAt     :: UTCTime+  , provenance :: Maybe String+  , scanCmd    :: Command+  , digest     :: String+  , port       :: Int+  , proto      :: Proto+  , cidr       :: IpBlock Canonical+  , source     :: Maybe String+  , data'      :: String+  } deriving (Generic, Show, Eq)++instance FromJSON Command where+  parseJSON = withObject "object" $ \o ->+    Command <$> o .:? "name"+            <*> o .: "scanner"+            <*> o .: "probe"+            <*> o .:? "probeBanner"+            <*> o .:? "probeArgs"+            <*> o .: "port"+            <*> (o .: "proto")+            <*> (o .:  "destination" >>= readDestination)+            <*> (o .:  "cidr"        >>= readJson "cidr")+            <*> (o .:  "deadline"    & fmap int64ToUTCTime)+            <*> (o .:? "banners" .!= False)++instance ToJSON Command where+  toJSON r = objectWithoutNulls+    [ "name"        .= (r ^. the @"name")+    , "scanner"     .= (r ^. the @"scanner")+    , "probe"       .= (r ^. the @"probe")+    , "probeBanner" .= (r ^. the @"probeBanner")+    , "probeArgs"   .= (r ^. the @"probeArgs")+    , "port"        .= (r ^. the @"port")+    , "proto"       .= (r ^. the @"proto")+    , "destination" .= either Text.pack toText (r ^. the @"destination")+    , "cidr"        .= show (r ^. the @"cidr")+    , "deadline"    .= utcTimeToInt64 (r ^. the @"deadline")+    , "banners"     .= (r ^. the @"banners")+    ]++instance FromJSON ScanMetaData where+  parseJSON = withObject "object" $ \o ->+    ScanMetaData <$> (o .: "startAt" & fmap int64ToUTCTime)+                 <*> (o .: "stopAt"  & fmap int64ToUTCTime)+                 <*> (o .:? "provenance")+                 <*> o .: "scanCmd"+                 <*> o .: "digest"+                 <*> o .: "port"+                 <*> (o .: "proto")+                 <*> (o .: "cidr"   >>= readJson "cidr")+                 <*> (o .:? "source")+                 <*> (o .: "data")++instance ToJSON ScanMetaData where+  toJSON r = objectWithoutNulls+    [ "startAt"    .= utcTimeToInt64 (r ^. the @"startAt")+    , "stopAt"     .= utcTimeToInt64 (r ^. the @"stopAt")+    , "provenance" .= (r ^. the @"provenance")+    , "scanCmd"    .= (r ^. the @"scanCmd")+    , "digest"     .= (r ^. the @"digest")+    , "port"       .= (r ^. the @"port")+    , "proto"      .= (r ^. the @"proto")+    , "cidr"       .= show (r ^. the @"cidr")+    , "source"     .= (r ^. the @"source")+    , "data"       .= (r ^. the @"data'")+    ]++readDestination :: String -> Parser (Either FilePath S3Uri)+readDestination s = (Right <$> readJson "destination (s3uri)"    s)+                <|> (Left  <$> readJson "destination (filepath)" s)++int64ToUTCTime :: Int64 -> UTCTime+int64ToUTCTime a = posixSecondsToUTCTime $ (a * 1000 * 1000) ^. from microseconds++utcTimeToInt64 :: UTCTime -> Int64+utcTimeToInt64 ut = round (toSeconds (utcTimeToPOSIXSeconds ut) :: Double)++loadScanMetadata :: (MonadUnliftIO m, MonadReader r m, HasType Env r)+    => S3Uri+    -> m (Maybe ScanMetaData)+loadScanMetadata uri = runAwsTyped $ do+    mb <- downloadFromS3Uri uri+    pure $ mb >>= (decode . fromStrict)