aboutsummaryrefslogtreecommitdiffstats
path: root/src/Network/WireGuard/Internal/RpcParsers.hs
blob: b28b00036354f25b26f32095307cf863046e97a9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{-# LANGUAGE OverloadedStrings #-}

module Network.WireGuard.Internal.RpcParsers(
  RpcRequest(..),
  OpType(..),
  RpcSetPayload(..),
  RpcDevicePayload(..),
  RpcPeerPayload(..),
  requestParser,
  deviceParser
) where

import           Control.Applicative                       ((*>), (<|>))
import           Control.Monad                             (liftM, join)
import           Crypto.Noise.DH                           (dhSecToBytes, dhBytesToPair)
import           Data.Attoparsec.ByteString.Char8          (Parser, string,
                                                            takeTill, option)
import           Data.Attoparsec.Combinator                ((<?>))                                                            
import qualified Data.ByteArray                      as BA (convert)
import qualified Data.ByteString                     as BS (head)
import           Data.ByteString.Conversion
import qualified Data.ByteString.Char8               as BC (pack)
import           Data.Maybe                                (fromMaybe)
import           Data.IP                                   (IPRange(..))
import           Data.Hex                                  (unhex)
import           Data.Word                                 (Word, Word64)
import           Data.ByteString                           (ByteString)
import           Network.Socket.Internal                   (SockAddr)


import Network.WireGuard.Internal.Data.RpcTypes (OpType(..),
                                                 RpcRequest(..),
                                                 RpcDevicePayload(..),
                                                 RpcPeerPayload(..),
                                                 RpcSetPayload(..))


-- | Attoparsec parser used to parse a RPC request, both Set or Get.
requestParser :: Parser RpcRequest 
requestParser = do
  op <- requestTypeParser
  let p = case op of
                  Set -> undefined
                  Get -> Nothing
  _ <- string $ BC.pack "\n\n"
  return $ RpcRequest op p

requestTypeParser :: Parser OpType
requestTypeParser = "get=1" *> return Get
                <|> "set=1" *> return Set

setPayloadParser :: Parser RpcSetPayload
setPayloadParser = undefined

deviceParser :: Parser RpcDevicePayload 
deviceParser = do
  pkHex  <- option Nothing (unhex <$> keyParser "private_key") <?> "Primary key parser"
  "\n"
  let pk = join $ (dhBytesToPair . BA.convert) <$> pkHex 
  p      <- (fromMaybe 0 . fromByteString) <$> keyParser "listen_port" <?> "Port parser"
  "\n"
  fwmark <- option Nothing (fromByteString <$> keyParser "fwmark") <?> "Fwmark parser"
  return $ RpcDevicePayload pk p fwmark False

keyParser :: ByteString -> Parser ByteString
keyParser str = (string str *> "=")  *> takeTill (=='\n')