HANDIN COMMIT
This commit is contained in:
36
code/iottb-project/.gitignore
vendored
36
code/iottb-project/.gitignore
vendored
@@ -1,36 +0,0 @@
|
||||
__pycache__
|
||||
.venv
|
||||
iottb.egg-info
|
||||
.idea
|
||||
*.log
|
||||
logs/
|
||||
*.pyc
|
||||
.obsidian
|
||||
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
.private/
|
||||
*.pcap
|
||||
110
code/iottb-project/docs/command_reference.txt
Normal file
110
code/iottb-project/docs/command_reference.txt
Normal file
@@ -0,0 +1,110 @@
|
||||
Usage: iottb [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
Options:
|
||||
-v, --verbosity Set verbosity [default: 0; 0<=x<=3]
|
||||
-d, --debug Enable debug mode
|
||||
--dry-run [default: True]
|
||||
--cfg-file PATH Path to iottb config file [default:
|
||||
/home/seb/.config/iottb/iottb.cfg]
|
||||
--help Show this message and exit.
|
||||
|
||||
Commands:
|
||||
add-device Add a device to a database
|
||||
init-db
|
||||
rm-cfg Removes the cfg file from the filesystem.
|
||||
rm-dbs Removes ALL(!) databases from the filesystem if...
|
||||
set-key-in-table-to Edit config or metadata files.
|
||||
show-all Show everything: configuration, databases, and...
|
||||
show-cfg Show the current configuration context
|
||||
sniff Sniff packets with tcpdump
|
||||
Usage: iottb init-db [OPTIONS]
|
||||
|
||||
Options:
|
||||
-d, --dest PATH Location to put (new) iottb database
|
||||
-n, --name TEXT Name of new database. [default: iottb.db]
|
||||
--update-default / --no-update-default
|
||||
If new db should be set as the new default
|
||||
[default: update-default]
|
||||
--help Show this message and exit.
|
||||
Usage: iottb add-device [OPTIONS]
|
||||
|
||||
Add a device to a database
|
||||
|
||||
Options:
|
||||
--dev, --device-name TEXT The name of the device to be added. If this
|
||||
string contains spaces or other special
|
||||
characters normalization is
|
||||
performed to derive a canonical name [required]
|
||||
--db, --database DIRECTORY Database in which to add this device. If not
|
||||
specified use default from config. [env var:
|
||||
IOTTB_DB]
|
||||
--guided Add device interactively [env var:
|
||||
IOTTB_GUIDED_ADD]
|
||||
--help Show this message and exit.
|
||||
Usage: iottb sniff [OPTIONS] [TCPDUMP-ARGS] [DEVICE]
|
||||
|
||||
Sniff packets with tcpdump
|
||||
|
||||
Options:
|
||||
Testbed sources:
|
||||
--db, --database TEXT Database of device. Only needed if not current
|
||||
default. [env var: IOTTB_DB]
|
||||
--app TEXT Companion app being used during capture
|
||||
Runtime behaviour:
|
||||
--unsafe Disable checks for otherwise required options.
|
||||
[env var: IOTTB_UNSAFE]
|
||||
--guided [env var: IOTTB_GUIDED]
|
||||
--pre TEXT Script to be executed before main command is
|
||||
started.
|
||||
--post TEXT Script to be executed upon completion of main
|
||||
command.
|
||||
Tcpdump options:
|
||||
-i, --interface TEXT Network interface to capture on.If not specified
|
||||
tcpdump tries to find and appropriate one. [env
|
||||
var: IOTTB_CAPTURE_INTERFACE]
|
||||
-a, --address TEXT IP or MAC address to filter packets by. [env var:
|
||||
IOTTB_CAPTURE_ADDRESS]
|
||||
-I, --monitor-mode Put interface into monitor mode.
|
||||
--ff TEXT tcpdump filter as string or file path. [env var:
|
||||
IOTTB_CAPTURE_FILTER]
|
||||
-#, --print-pacno Print packet number at beginning of line. True by
|
||||
default. [default: True]
|
||||
-e, --print-ll Print link layer headers. True by default.
|
||||
-c, --count INTEGER Number of packets to capture. [default: 1000]
|
||||
--help Show this message and exit.
|
||||
Utility Commands mostly for development
|
||||
Usage: iottb rm-cfg [OPTIONS]
|
||||
|
||||
Removes the cfg file from the filesystem.
|
||||
|
||||
This is mostly a utility during development. Once non-standard database
|
||||
locations are implemented, deleting this would lead to iottb not being able
|
||||
to find them anymore.
|
||||
|
||||
Options:
|
||||
--yes Confirm the action without prompting.
|
||||
--help Show this message and exit.
|
||||
Usage: iottb rm-dbs [OPTIONS]
|
||||
|
||||
Removes ALL(!) databases from the filesystem if they're empty.
|
||||
|
||||
Development utility currently unfit for use.
|
||||
|
||||
Options:
|
||||
--yes Confirm the action without prompting.
|
||||
--help Show this message and exit.
|
||||
Usage: iottb show-cfg [OPTIONS]
|
||||
|
||||
Show the current configuration context
|
||||
|
||||
Options:
|
||||
--cfg-file PATH Path to the config file [default:
|
||||
/home/seb/.config/iottb/iottb.cfg]
|
||||
-pp Pretty Print
|
||||
--help Show this message and exit.
|
||||
Usage: iottb show-all [OPTIONS]
|
||||
|
||||
Show everything: configuration, databases, and device metadata
|
||||
|
||||
Options:
|
||||
--help Show this message and exit.
|
||||
38
code/iottb-project/docs/help.txt
Normal file
38
code/iottb-project/docs/help.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
Usage: iottb [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
Options:
|
||||
-v, --verbosity Set verbosity [default: 0; 0<=x<=3]
|
||||
-d, --debug Enable debug mode
|
||||
--dry-run [default: True]
|
||||
--cfg-file PATH Path to iottb config file [default:
|
||||
/home/seb/.config/iottb/iottb.cfg]
|
||||
--help Show this message and exit.
|
||||
|
||||
Commands:
|
||||
add-device Add a device to a database
|
||||
init-db
|
||||
rm-cfg Removes the cfg file from the filesystem.
|
||||
rm-dbs Removes ALL(!) databases from the filesystem if...
|
||||
set-key-in-table-to Edit config or metadata files.
|
||||
show-all Show everything: configuration, databases, and...
|
||||
show-cfg Show the current configuration context
|
||||
sniff Sniff packets with tcpdump
|
||||
Usage: iottb [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
Options:
|
||||
-v, --verbosity Set verbosity [default: 0; 0<=x<=3]
|
||||
-d, --debug Enable debug mode
|
||||
--dry-run [default: True]
|
||||
--cfg-file PATH Path to iottb config file [default:
|
||||
/home/seb/.config/iottb/iottb.cfg]
|
||||
--help Show this message and exit.
|
||||
|
||||
Commands:
|
||||
add-device Add a device to a database
|
||||
init-db
|
||||
rm-cfg Removes the cfg file from the filesystem.
|
||||
rm-dbs Removes ALL(!) databases from the filesystem if...
|
||||
set-key-in-table-to Edit config or metadata files.
|
||||
show-all Show everything: configuration, databases, and...
|
||||
show-cfg Show the current configuration context
|
||||
sniff Sniff packets with tcpdump
|
||||
@@ -1,9 +1,9 @@
|
||||
Main Command: iottb
|
||||
Testbed [I]
|
||||
Usage: [OPTIONS] COMMAND [ARGS]...
|
||||
# Main Command: `iottb`
|
||||
|
||||
Usage: `iottb [OPTIONS] COMMAND [ARGS]...`
|
||||
|
||||
Options:
|
||||
-v, --verbosity Set verbosity [0<=x<=3]
|
||||
-v, --verbosity Set verbosity [0<=x<=3] \n
|
||||
-d, --debug Enable debug mode
|
||||
--dry-run
|
||||
--cfg-file PATH Path to iottb config file
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
import click
|
||||
from pathlib import Path
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
import sys
|
||||
from iottb.models.iottb_config import IottbConfig
|
||||
from iottb.definitions import DB_NAME
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('-d', '--dest', type=click.Path(), help='Location to put (new) iottb database')
|
||||
@click.option('-n', '--name', default=DB_NAME, type=str, help='Name of new database.')
|
||||
@click.option('--update-default/--no-update-default', default=True, help='If new db should be set as the new default')
|
||||
@click.pass_context
|
||||
def init_db(ctx, dest, name, update_default):
|
||||
logger.info('init-db invoked')
|
||||
config = ctx.obj['CONFIG']
|
||||
logger.debug(f'str(config)')
|
||||
# Use the default path from config if dest is not provided
|
||||
known_dbs = config.get_known_databases()
|
||||
logger.debug(f'Known databases: {known_dbs}')
|
||||
if name in known_dbs:
|
||||
dest = config.get_database_location(name)
|
||||
if Path(dest).joinpath(name).is_dir():
|
||||
click.echo(f'A database {name} already exists.')
|
||||
logger.debug(f'DB {name} exists in {dest}')
|
||||
click.echo(f'Exiting...')
|
||||
exit()
|
||||
logger.debug(f'DB name {name} registered but does not exist.')
|
||||
if not dest:
|
||||
logger.info('No dest set, choosing default destination.')
|
||||
dest = Path(config.default_db_location).parent
|
||||
|
||||
db_path = Path(dest).joinpath(name)
|
||||
logger.debug(f'Full path for db {str(db_path)}')
|
||||
# Create the directory if it doesn't exist
|
||||
db_path.mkdir(parents=True, exist_ok=True)
|
||||
logger.info(f"mkdir {db_path} successful")
|
||||
click.echo(f'Created {db_path}')
|
||||
|
||||
# Update configuration
|
||||
config.set_database_location(name, str(dest))
|
||||
if update_default:
|
||||
config.set_default_database(name, str(dest))
|
||||
config.save_config()
|
||||
logger.info(f"Updated configuration with database {name} at {db_path}")
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('-d', '--dest', type=click.Path(), help='Location to put (new) iottb database')
|
||||
@click.option('-n', '--name', default=DB_NAME, type=str, help='Name of new database.')
|
||||
@click.option('--update-default/--no-update-default', default=True, help='If new db should be set as the new default')
|
||||
@click.pass_context
|
||||
def init_db_inactive(ctx, dest, name, update_default):
|
||||
logger.info('init-db invoked')
|
||||
config = ctx.obj['CONFIG']
|
||||
logger.debug(f'str(config)')
|
||||
|
||||
# Retrieve known databases
|
||||
known_dbs = config.get_known_databases()
|
||||
|
||||
# Determine destination path
|
||||
if name in known_dbs:
|
||||
dest = Path(config.get_database_location(name))
|
||||
if dest.joinpath(name).is_dir():
|
||||
click.echo(f'A database {name} already exists.')
|
||||
logger.debug(f'DB {name} exists in {dest}')
|
||||
click.echo(f'Exiting...')
|
||||
exit()
|
||||
logger.debug(f'DB name {name} registered but does not exist.')
|
||||
elif not dest:
|
||||
logger.info('No destination set, using default path from config.')
|
||||
dest = Path(config.default_db_location).parent
|
||||
|
||||
# Ensure destination path is absolute
|
||||
dest = dest.resolve()
|
||||
|
||||
# Combine destination path with database name
|
||||
db_path = dest / name
|
||||
logger.debug(f'Full path for database: {str(db_path)}')
|
||||
|
||||
# Create the directory if it doesn't exist
|
||||
try:
|
||||
db_path.mkdir(parents=True, exist_ok=True)
|
||||
logger.info(f'Directory {db_path} created successfully.')
|
||||
click.echo(f'Created {db_path}')
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to create directory {db_path}: {e}')
|
||||
click.echo(f'Failed to create directory {db_path}: {e}', err=True)
|
||||
exit(1)
|
||||
|
||||
# Update configuration
|
||||
config.set_database_location(name, str(db_path))
|
||||
if update_default:
|
||||
config.set_default_database(name, str(db_path))
|
||||
config.save_config()
|
||||
logger.info(f'Updated configuration with database {name} at {db_path}')
|
||||
click.echo(f'Updated configuration with database {name} at {db_path}')
|
||||
0
code/iottb-project/iottb/commands/raw.py
Normal file
0
code/iottb-project/iottb/commands/raw.py
Normal file
@@ -1,18 +1,16 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
import subprocess
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from time import time
|
||||
|
||||
import click
|
||||
import subprocess
|
||||
import json
|
||||
from pathlib import Path
|
||||
import logging
|
||||
import re
|
||||
from datetime import datetime
|
||||
from click_option_group import optgroup
|
||||
from iottb.definitions import APP_NAME, CFG_FILE_PATH
|
||||
from iottb.models.iottb_config import IottbConfig
|
||||
|
||||
from iottb.utils.string_processing import make_canonical_name
|
||||
|
||||
# Setup logger
|
||||
@@ -47,11 +45,13 @@ def validate_sniff(ctx, param, value):
|
||||
|
||||
|
||||
def run_pre(pre):
|
||||
pass
|
||||
subprocess.run(pre, shell=True)
|
||||
logger.debug(f'finnished {pre}')
|
||||
|
||||
|
||||
def run_post(post):
|
||||
pass
|
||||
subprocess.run(post, shell=True)
|
||||
logger.debug(f'finnished {post}')
|
||||
|
||||
|
||||
@click.command('sniff', help='Sniff packets with tcpdump')
|
||||
@@ -63,9 +63,8 @@ def run_post(post):
|
||||
@optgroup.option('--unsafe', is_flag=True, default=False, envvar='IOTTB_UNSAFE', is_eager=True,
|
||||
help='Disable checks for otherwise required options.\n', show_envvar=True)
|
||||
@optgroup.option('--guided', is_flag=True, default=False, envvar='IOTTB_GUIDED', show_envvar=True)
|
||||
@optgroup.option('--pre', type=click.Path(exists=True, executable=True), help='Script to be executed before main '
|
||||
'command'
|
||||
'is started.')
|
||||
@optgroup.option('--pre', help='Script to be executed before main command is started.')
|
||||
@optgroup.option('--post', help='Script to be executed upon completion of main command.')
|
||||
@optgroup.group('Tcpdump options')
|
||||
@optgroup.option('-i', '--interface',
|
||||
help='Network interface to capture on.' +
|
||||
@@ -74,11 +73,11 @@ def run_post(post):
|
||||
@optgroup.option('-a', '--address', callback=validate_sniff,
|
||||
help='IP or MAC address to filter packets by.\n', show_envvar=True,
|
||||
envvar='IOTTB_CAPTURE_ADDRESS')
|
||||
@optgroup.option('-I', '--monitor-mode', help='Put interface into monitor mode.', is_flag=True)
|
||||
@optgroup.option('-I', '--monitor-mode', help='Put interface into monitor mode.\n', is_flag=True)
|
||||
@optgroup.option('--ff', type=str, envvar='IOTTB_CAPTURE_FILTER', show_envvar=True,
|
||||
help='tcpdump filter as string or file path.')
|
||||
@optgroup.option('-#', '--print-pacno', is_flag=True, default=True,
|
||||
help='Print packet number at beginning of line. True by default.')
|
||||
help='Print packet number at beginning of line. True by default.\n')
|
||||
@optgroup.option('-e', '--print-ll', is_flag=True, default=False,
|
||||
help='Print link layer headers. True by default.')
|
||||
@optgroup.option('-c', '--count', type=int, help='Number of packets to capture.', default=1000)
|
||||
@@ -263,7 +262,7 @@ def sniff(ctx, device, interface, print_pacno, ff, count, monitor_mode, print_ll
|
||||
out.write(tcp_complete.stdout)
|
||||
err.write(tcp_complete.stderr)
|
||||
|
||||
#click.echo(f'Mock sniff execution')
|
||||
# click.echo(f'Mock sniff execution')
|
||||
click.echo(f"Capture complete. Saved to {pcap_file}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(f'Failed to capture packets: {e}')
|
||||
@@ -285,6 +284,8 @@ def sniff(ctx, device, interface, print_pacno, ff, count, monitor_mode, print_ll
|
||||
end_time = datetime.now().strftime("%H:%M:%S")
|
||||
end = time()
|
||||
delta = end - start
|
||||
|
||||
|
||||
click.echo(f'tcpdump took {delta:.2f} seconds.')
|
||||
# Step 9: Register metadata
|
||||
metadata = {
|
||||
@@ -310,7 +311,9 @@ def sniff(ctx, device, interface, print_pacno, ff, count, monitor_mode, print_ll
|
||||
'resources': {
|
||||
'pcap_file': str(pcap_file),
|
||||
'stdout_log': str(stdout_log_file),
|
||||
'stderr_log': str(stderr_log_file)
|
||||
'stderr_log': str(stderr_log_file),
|
||||
'pre': str(pre),
|
||||
'post': str(post)
|
||||
},
|
||||
'environment': {
|
||||
'capture_dir': capture_dir,
|
||||
@@ -337,5 +340,7 @@ def sniff(ctx, device, interface, print_pacno, ff, count, monitor_mode, print_ll
|
||||
|
||||
click.echo(f'END SNIFF SUBCOMMAND')
|
||||
if post:
|
||||
click.echo(f'Running post command {post}')
|
||||
click.echo(f'Running post script {post}')
|
||||
run_post(post)
|
||||
|
||||
|
||||
|
||||
@@ -65,56 +65,3 @@ def init_db(ctx, dest, name, update_default):
|
||||
# config.save_config()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('-d', '--dest', type=click.Path(), help='Location to put (new) iottb database')
|
||||
@click.option('-n', '--name', default=DB_NAME, type=str, help='Name of new database.')
|
||||
@click.option('--update-default/--no-update-default', default=True, help='If new db should be set as the new default')
|
||||
@click.pass_context
|
||||
def init_db_inactive(ctx, dest, name, update_default):
|
||||
logger.info('init-db invoked')
|
||||
config = ctx.obj['CONFIG']
|
||||
logger.debug(f'str(config)')
|
||||
|
||||
# Retrieve known databases
|
||||
known_dbs = config.get_known_databases()
|
||||
|
||||
# Determine destination path
|
||||
if name in known_dbs:
|
||||
dest = Path(config.get_database_location(name))
|
||||
if dest.joinpath(name).is_dir():
|
||||
click.echo(f'A database {name} already exists.')
|
||||
logger.debug(f'DB {name} exists in {dest}')
|
||||
click.echo(f'Exiting...')
|
||||
exit()
|
||||
logger.debug(f'DB name {name} registered but does not exist.')
|
||||
elif not dest:
|
||||
logger.info('No destination set, using default path from config.')
|
||||
dest = Path(config.default_db_location).parent
|
||||
|
||||
# Ensure destination path is absolute
|
||||
dest = dest.resolve()
|
||||
|
||||
# Combine destination path with database name
|
||||
db_path = dest / name
|
||||
logger.debug(f'Full path for database: {str(db_path)}')
|
||||
|
||||
# Create the directory if it doesn't exist
|
||||
try:
|
||||
db_path.mkdir(parents=True, exist_ok=True)
|
||||
logger.info(f'Directory {db_path} created successfully.')
|
||||
click.echo(f'Created {db_path}')
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to create directory {db_path}: {e}')
|
||||
click.echo(f'Failed to create directory {db_path}: {e}', err=True)
|
||||
exit(1)
|
||||
|
||||
# Update configuration
|
||||
config.set_database_location(name, str(db_path))
|
||||
if update_default:
|
||||
config.set_default_database(name, str(db_path))
|
||||
config.save_config()
|
||||
logger.info(f'Updated configuration with database {name} at {db_path}')
|
||||
click.echo(f'Updated configuration with database {name} at {db_path}')
|
||||
|
||||
@@ -50,8 +50,23 @@ def write_help_to_file(cli, filename):
|
||||
f.write("\n\n")
|
||||
|
||||
|
||||
def manual():
|
||||
comands = [
|
||||
'init-db',
|
||||
'add-device',
|
||||
'sniff'
|
||||
]
|
||||
dev_commands = [
|
||||
'show-all',
|
||||
'rm-dbs',
|
||||
'show-cfg',
|
||||
'show-all'
|
||||
]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from iottb import DOCS_FOLDER
|
||||
|
||||
print('Must be in project root for this to work properly!')
|
||||
print(f'CWD is {str(Path.cwd())}')
|
||||
DOCS_FOLDER.mkdir(exist_ok=True)
|
||||
|
||||
@@ -8,7 +8,7 @@ readme = "README.md"
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
click = "^8.1"
|
||||
scapy = "^2.5"
|
||||
# scapy = "^2.5"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
iottb = "iottb.main:cli"
|
||||
|
||||
Reference in New Issue
Block a user