1
1
import cmd
2
- import configparser
3
2
import csv
3
+ import sys
4
4
import os
5
+ import argparse
5
6
from os import listdir
6
7
from os .path import exists
7
8
from os .path import join as path_join
8
- import shutil
9
- from sqlite3 import connect
10
- import sys
11
9
from textwrap import dedent
12
-
13
10
from requests import get , post , ConnectionError
14
- from sqlalchemy import create_engine
15
11
from terminaltables import AsciiTable
12
+ from termcolor import colored
16
13
17
14
from nxc .loaders .protocolloader import ProtocolLoader
18
- from nxc .paths import CONFIG_PATH , WS_PATH , WORKSPACE_DIR
15
+ from nxc .paths import CONFIG_PATH , WORKSPACE_DIR
16
+ from nxc .database import create_db_engine , open_config , get_workspace , get_db , write_configfile , create_workspace , set_workspace
19
17
20
18
21
19
class UserExitedProto (Exception ):
22
20
pass
23
21
24
22
25
- def create_db_engine (db_path ):
26
- return create_engine (f"sqlite:///{ db_path } " , isolation_level = "AUTOCOMMIT" , future = True )
27
-
28
-
29
23
def print_table (data , title = None ):
30
24
print ()
31
25
table = AsciiTable (data )
@@ -446,29 +440,15 @@ class NXCDBMenu(cmd.Cmd):
446
440
def __init__ (self , config_path ):
447
441
cmd .Cmd .__init__ (self )
448
442
self .config_path = config_path
449
-
450
- try :
451
- self .config = configparser .ConfigParser ()
452
- self .config .read (self .config_path )
453
- except Exception as e :
454
- print (f"[-] Error reading nxc.conf: { e } " )
455
- sys .exit (1 )
456
-
457
443
self .conn = None
458
444
self .p_loader = ProtocolLoader ()
459
445
self .protocols = self .p_loader .get_protocols ()
460
446
461
- self .workspace = self .config .get ("nxc" , "workspace" )
447
+ self .config = open_config (self .config_path )
448
+ self .workspace = get_workspace (self .config )
449
+ self .db = get_db (self .config )
462
450
self .do_workspace (self .workspace )
463
451
464
- self .db = self .config .get ("nxc" , "last_used_db" )
465
- if self .db :
466
- self .do_proto (self .db )
467
-
468
- def write_configfile (self ):
469
- with open (self .config_path , "w" ) as configfile :
470
- self .config .write (configfile )
471
-
472
452
def do_proto (self , proto ):
473
453
if not proto :
474
454
return
@@ -479,7 +459,7 @@ def do_proto(self, proto):
479
459
db_nav_object = self .p_loader .load_protocol (self .protocols [proto ]["nvpath" ])
480
460
db_object = self .p_loader .load_protocol (self .protocols [proto ]["dbpath" ])
481
461
self .config .set ("nxc" , "last_used_db" , proto )
482
- self . write_configfile ()
462
+ write_configfile (self . config , self . config_path )
483
463
try :
484
464
proto_menu = db_nav_object .navigator (self , db_object .database (self .conn ), proto )
485
465
proto_menu .cmdloop ()
@@ -506,18 +486,18 @@ def do_workspace(self, line):
506
486
if subcommand == "create" :
507
487
new_workspace = line .split ()[1 ].strip ()
508
488
print (f"[*] Creating workspace '{ new_workspace } '" )
509
- self . create_workspace (new_workspace , self .p_loader , self . protocols )
489
+ create_workspace (new_workspace , self .p_loader )
510
490
self .do_workspace (new_workspace )
511
491
elif subcommand == "list" :
512
492
print ("[*] Enumerating Workspaces" )
513
493
for workspace in listdir (path_join (WORKSPACE_DIR )):
514
494
if workspace == self .workspace :
515
- print ("==> " + workspace )
495
+ print (f" * { colored ( workspace , 'green' ) } " )
516
496
else :
517
- print (workspace )
497
+ print (f" { workspace } " )
518
498
elif exists (path_join (WORKSPACE_DIR , line )):
519
499
self .config .set ("nxc" , "workspace" , line )
520
- self . write_configfile ()
500
+ write_configfile (self . config , self . config_path )
521
501
self .workspace = line
522
502
self .prompt = f"nxcdb ({ line } ) > "
523
503
@@ -538,65 +518,49 @@ def help_exit():
538
518
Exits
539
519
"""
540
520
print_help (help_string )
541
-
542
- @staticmethod
543
- def create_workspace (workspace_name , p_loader , protocols ):
544
- os .mkdir (path_join (WORKSPACE_DIR , workspace_name ))
545
-
546
- for protocol in protocols :
547
- protocol_object = p_loader .load_protocol (protocols [protocol ]["dbpath" ])
548
- proto_db_path = path_join (WORKSPACE_DIR , workspace_name , f"{ protocol } .db" )
549
-
550
- if not exists (proto_db_path ):
551
- print (f"[*] Initializing { protocol .upper ()} protocol database" )
552
- conn = connect (proto_db_path )
553
- c = conn .cursor ()
554
-
555
- # try to prevent some weird sqlite I/O errors
556
- c .execute ("PRAGMA journal_mode = OFF" )
557
- c .execute ("PRAGMA foreign_keys = 1" )
558
-
559
- protocol_object .database .db_schema (c )
560
-
561
- # commit the changes and close everything off
562
- conn .commit ()
563
- conn .close ()
564
-
565
-
566
- def delete_workspace (workspace_name ):
567
- shutil .rmtree (path_join (WORKSPACE_DIR , workspace_name ))
568
-
569
-
570
- def initialize_db (logger ):
571
- if not exists (path_join (WS_PATH , "default" )):
572
- logger .debug ("Creating default workspace" )
573
- os .mkdir (path_join (WS_PATH , "default" ))
574
-
575
- p_loader = ProtocolLoader ()
576
- protocols = p_loader .get_protocols ()
577
- for protocol in protocols :
578
- protocol_object = p_loader .load_protocol (protocols [protocol ]["dbpath" ])
579
- proto_db_path = path_join (WS_PATH , "default" , f"{ protocol } .db" )
580
-
581
- if not exists (proto_db_path ):
582
- logger .debug (f"Initializing { protocol .upper ()} protocol database" )
583
- conn = connect (proto_db_path )
584
- c = conn .cursor ()
585
- # try to prevent some weird sqlite I/O errors
586
- c .execute ("PRAGMA journal_mode = OFF" ) # could try setting to PERSIST if DB corruption starts occurring
587
- c .execute ("PRAGMA foreign_keys = 1" )
588
- # set a small timeout (5s) so if another thread is writing to the database, the entire program doesn't crash
589
- c .execute ("PRAGMA busy_timeout = 5000" )
590
- protocol_object .database .db_schema (c )
591
- # commit the changes and close everything off
592
- conn .commit ()
593
- conn .close ()
594
-
521
+
595
522
596
523
def main ():
597
524
if not exists (CONFIG_PATH ):
598
525
print ("[-] Unable to find config file" )
599
526
sys .exit (1 )
527
+
528
+ parser = argparse .ArgumentParser (
529
+ description = "NXCDB is a database navigator for NXC" ,
530
+ )
531
+ parser .add_argument (
532
+ "-gw" ,
533
+ "--get-workspace" ,
534
+ action = "store_true" ,
535
+ help = "get the current workspace" ,
536
+ )
537
+ parser .add_argument (
538
+ "-cw" ,
539
+ "--create-workspace" ,
540
+ help = "create a new workspace" ,
541
+ )
542
+ parser .add_argument (
543
+ "-sw" ,
544
+ "--set-workspace" ,
545
+ help = "set the current workspace" ,
546
+ )
547
+ args = parser .parse_args ()
548
+
549
+ if args .create_workspace :
550
+ create_workspace (args .create_workspace )
551
+ sys .exit ()
552
+ if args .set_workspace :
553
+ set_workspace (CONFIG_PATH , args .set_workspace )
554
+ sys .exit ()
555
+ if args .get_workspace :
556
+ current_workspace = get_workspace (open_config (CONFIG_PATH ))
557
+ for workspace in listdir (path_join (WORKSPACE_DIR )):
558
+ if workspace == current_workspace :
559
+ print (f" * { colored (workspace , 'green' )} " )
560
+ else :
561
+ print (f" { workspace } " )
562
+ sys .exit ()
563
+
600
564
try :
601
565
nxcdbnav = NXCDBMenu (CONFIG_PATH )
602
566
nxcdbnav .cmdloop ()
0 commit comments