control-port-filter add_onion parsing

Information

ID: 562
PHID: PHID-TASK-gyjrztlhzaqer7o4v6lb
Author: Patrick
Status at Migration Time: invalid
Priority at Migration Time: Normal

Description

Limit IPs to:

  • Qubes-Whonix: 10.137.0.0-10.138.255.255
  • Non-Qubes-Whonix: 10.152.152.0-10.152.152.24

Limit ports to:

  • real ports

WIP:

#!/usr/bin/python

import logging
import os
import sys

client_ip = "555.555.555.555"
ADD_ONION_INJECT_IP = True

#"ADD_ONION RSA1024:[Blob Redacted] Port=80,192.168.1.1:8080",

add_onion_test = [
 "ADD_ONION NEW:BEST Flags=DiscardPK Port=80",
 "ADD_ONION NEW:BEST Flags=DiscardPK Port=80",
 "ADD_ONION NEW:BEST Port=22 Port=80,8080",
 "ADD_ONION NEW:BEST Flags=DiscardPK,BasicAuth Port=22",
 "ADD_ONION NEW:BEST Flags=DiscardPK Port=22",
 "ADD_ONION NEW:BEST Flags=DiscardPK,NonAnonymous Port=22",
 "ADD_ONION NEW:BEST Flags=DiscardPK Port=22",
 "ADD_ONION NEW:BEST Flags=DiscardPK,NonAnonymous Port=22",
 "add_onion new:best port=80,17600",
 "add_onion new:best port=80,127.0.0.1:17600",
 "add_onion new:best port=8 0,17600"
 "add_onion new:best port=80 : 17600",
 "add_onion new:best port=80 : 17600 Flags=DiscardPK",
 "add_onion new:best port= 80:17600 Flags=DiscardPK",
];

## TODO: KeyBlob support
## TODO: do not lower KeyBlob
## TODO: do not lower ClientBlob
## TODO: do not lower ClientName
## TODO: (when implementing) KeyBlob maximum string length
## TODO: (when implementing) ClientBlob maximum string length
def add_onion_parse(request, client_ip, inject):
    ## ADD_ONION KeyType:KeyBlob
    ## Flags=Flag,Flag
    ## Port=VirtPort,TargetIP:TargetPort
    ## ClientAuth=ClientName
    ## ClientAuth=ClientName:ClientBlob

    request_processed = ""

    block_counter = 0
    for block in request.split(" "):
        block_counter = block_counter + 1
        #logger.info('block %s: %s' % (str(block_counter), block))
        if block_counter == 1 and block == "add_onion":
           request_processed = "add_onion"
           continue
        if block_counter == 2:
           KeyTyp = block.split(":")[0]
           KeyBlob = block.split(":")[1]
           if KeyTyp == "new":
               request_processed = request_processed + " " + "new"
           elif KeyTyp == "rsa1024":
               request_processed = request_processed + " " + "rsa1024"
           else:
               logger.error('KeyType not whitelisted! KeyTyp: %s' % (KeyType))
               return False
           request_processed = request_processed + ":" + KeyBlob
           continue

        first = block.split("=")[0]
        second = block.split("=")[1]
        if first == "flags":
            request_processed = request_processed + " " + "flags="
            for single_flag in second.split(","):
                #logger.info('single_flag: %s' % (single_flag))
                if single_flag == "discardpk":
                   request_processed = request_processed + "discardpk,"
                elif single_flag == "detach":
                   request_processed = request_processed + "detach,"
                elif single_flag == "basicauth":
                   request_processed = request_processed + "detach,"
                else:
                   logger.error('Flag not whitelisted! flag: %s' % (single_flag))
                   return False

            ## Remove extraneous ',' at the end.
            request_processed = request_processed[:-1]
        elif first == "port":
           request_processed = request_processed + " " + "port="
           port = second

           ##    port=22
           ## vs port=80,17600

           ## Format such as 'Port=80,192.168.1.1:8080' not yet supported.

           if len(port.split(",")) == 1:
               if not port.isdigit():
                   logger.error('port is no digit! port: %s' % (str(port)))
                   return False
               request_processed = request_processed + port + ","
           elif len(port.split(",")) == 2:
               port_counter = 0
               for port_single in port.split(","):
                  if not port_single.isdigit():
                     logger.error('port_single is no digit! port_single: %s' % (str(port_single)))
                     return False

                  #logger.info('port_single %s: %s' % (str(port_counter), port_single))
                  port_counter = port_counter + 1
                  if port_counter == 1:
                      request_processed = request_processed + port_single + ","
                  elif port_counter == 2:
                      if inject == True:
                          request_processed = request_processed + client_ip + ":" + port_single + ","
                      else:
                          request_processed = request_processed + ":" + port_single + ","
                  else:
                     logger.error('len(port.split(",")) too long!')
                     return False

           ## Remove extraneous ',' at the end.
           request_processed = request_processed[:-1]

    return request_processed


mypid = os.getpid()
log_prefix = "CPFP " + str(mypid) + " log"
logger = logging.getLogger(log_prefix)
logger.setLevel(logging.DEBUG)

formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
logger.addHandler(handler)

for request in add_onion_test:
    logger.info('request_requested: %s' % (request))
    request = request.lower().strip()
    request_startswith = request.split(' ', 1)[0]
    if request_startswith == "add_onion":
        try:
            request_processed = add_onion_parse(request, client_ip, ADD_ONION_INJECT_IP)
        except:
            exception_msg = str(sys.exc_info()[0])
            logger.error('exception_msg: %s' % (exception_msg))
            request_processed = False
        logger.info('request_processed: %s' % (request_processed))
        print ""

2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_requested: ADD_ONION NEW:BEST Flags=DiscardPK Port=80
2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_processed: add_onion new:best flags=discardpk port=80

2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_requested: ADD_ONION NEW:BEST Port=22 Port=80,8080
2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_processed: add_onion new:best port=22 port=80,555.555.555.555:8080

2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_requested: ADD_ONION NEW:BEST Flags=DiscardPK,BasicAuth Port=22
2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_processed: add_onion new:best flags=discardpk,detach port=22

2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_requested: ADD_ONION NEW:BEST Flags=DiscardPK Port=22
2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_processed: add_onion new:best flags=discardpk port=22

2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_requested: ADD_ONION NEW:BEST Flags=DiscardPK,NonAnonymous Port=22
2016-09-27 16:26:19,283 - CPFP 9680 log - ERROR - Flag not whitelisted! flag: nonanonymous
2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_processed: False

2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_requested: ADD_ONION NEW:BEST Flags=DiscardPK Port=22
2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_processed: add_onion new:best flags=discardpk port=22

2016-09-27 16:26:19,283 - CPFP 9680 log - INFO - request_requested: ADD_ONION NEW:BEST Flags=DiscardPK,NonAnonymous Port=22
2016-09-27 16:26:19,283 - CPFP 9680 log - ERROR - Flag not whitelisted! flag: nonanonymous
2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_processed: False

2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_requested: add_onion new:best port=80,17600
2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_processed: add_onion new:best port=80,555.555.555.555:17600

2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_requested: add_onion new:best port=80,127.0.0.1:17600
2016-09-27 16:26:19,284 - CPFP 9680 log - ERROR - port_single is no digit! port_single: 127.0.0.1:17600
2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_processed: False

2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_requested: add_onion new:best port=8 0,17600add_onion new:best port=80 : 17600
2016-09-27 16:26:19,284 - CPFP 9680 log - ERROR - exception_msg: <type 'exceptions.IndexError'>
2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_processed: False

2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_requested: add_onion new:best port=80 : 17600 Flags=DiscardPK
2016-09-27 16:26:19,284 - CPFP 9680 log - ERROR - exception_msg: <type 'exceptions.IndexError'>
2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_processed: False

2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_requested: add_onion new:best port= 80:17600 Flags=DiscardPK
2016-09-27 16:26:19,284 - CPFP 9680 log - ERROR - port is no digit! port: 
2016-09-27 16:26:19,284 - CPFP 9680 log - INFO - request_processed: False

Comments


Patrick

2016-12-07 18:10:37 UTC