-
Notifications
You must be signed in to change notification settings - Fork 381
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #366 from termanix/NFS-Protocol
New Protocol NFS
- Loading branch information
Showing
9 changed files
with
528 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
from pathlib import Path | ||
from sqlalchemy.orm import sessionmaker, scoped_session | ||
from sqlalchemy import MetaData, Table | ||
from sqlalchemy.exc import ( | ||
IllegalStateChangeError, | ||
NoInspectionAvailable, | ||
NoSuchTableError, | ||
) | ||
from nxc.logger import nxc_logger | ||
import sys | ||
|
||
|
||
class database: | ||
def __init__(self, db_engine): | ||
self.CredentialsTable = None | ||
self.HostsTable = None | ||
self.LoggedinRelationsTable = None | ||
self.SharesTable = None | ||
|
||
self.db_engine = db_engine | ||
self.db_path = self.db_engine.url.database | ||
self.protocol = Path(self.db_path).stem.upper() | ||
self.metadata = MetaData() | ||
self.reflect_tables() | ||
|
||
session_factory = sessionmaker(bind=self.db_engine, expire_on_commit=True) | ||
Session = scoped_session(session_factory) | ||
self.sess = Session() | ||
|
||
@staticmethod | ||
def db_schema(db_conn): | ||
db_conn.execute( | ||
"""CREATE TABLE "credentials" ( | ||
"id" integer PRIMARY KEY, | ||
"username" text, | ||
"password" text | ||
)""" | ||
) | ||
|
||
db_conn.execute( | ||
"""CREATE TABLE "hosts" ( | ||
"id" integer PRIMARY KEY, | ||
"ip" text, | ||
"hostname" text, | ||
"port" integer | ||
)""" | ||
) | ||
db_conn.execute( | ||
"""CREATE TABLE "loggedin_relations" ( | ||
"id" integer PRIMARY KEY, | ||
"cred_id" integer, | ||
"host_id" integer, | ||
FOREIGN KEY(cred_id) REFERENCES credentials(id), | ||
FOREIGN KEY(host_id) REFERENCES hosts(id) | ||
)""" | ||
) | ||
db_conn.execute( | ||
"""CREATE TABLE "shares" ( | ||
"id" integer PRIMARY KEY, | ||
"lir_id" integer, | ||
"data" text, | ||
FOREIGN KEY(lir_id) REFERENCES loggedin_relations(id) | ||
)""" | ||
) | ||
|
||
def reflect_tables(self): | ||
with self.db_engine.connect(): | ||
try: | ||
self.CredentialsTable = Table("credentials", self.metadata, autoload_with=self.db_engine) | ||
self.HostsTable = Table("hosts", self.metadata, autoload_with=self.db_engine) | ||
self.LoggedinRelationsTable = Table("loggedin_relations", self.metadata, autoload_with=self.db_engine) | ||
self.SharesTable = Table("shares", self.metadata, autoload_with=self.db_engine) | ||
except (NoInspectionAvailable, NoSuchTableError): | ||
print( | ||
f""" | ||
[-] Error reflecting tables for the {self.protocol} protocol - this means there is a DB schema mismatch | ||
[-] This is probably because a newer version of nxc is being run on an old DB schema | ||
[-] Optionally save the old DB data (`cp {self.db_path} ~/nxc_{self.protocol.lower()}.bak`) | ||
[-] Then remove the {self.protocol} DB (`rm -f {self.db_path}`) and run nxc to initialize the new DB""" | ||
) | ||
sys.exit() | ||
|
||
def shutdown_db(self): | ||
try: | ||
self.sess.close() | ||
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw: | ||
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and | ||
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5> | ||
except IllegalStateChangeError as e: | ||
nxc_logger.debug(f"Error while closing session db object: {e}") | ||
|
||
def clear_database(self): | ||
for table in self.metadata.sorted_tables: | ||
self.sess.execute(table.delete()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from nxc.nxcdb import DatabaseNavigator, print_help | ||
|
||
|
||
class navigator(DatabaseNavigator): | ||
def do_clear_database(self, line): | ||
if input("This will destroy all data in the current database, are you SURE you want to run this? (y/n): ") == "y": | ||
self.db.clear_database() | ||
|
||
def help_clear_database(self): | ||
help_string = """ | ||
clear_database | ||
THIS COMPLETELY DESTROYS ALL DATA IN THE CURRENTLY CONNECTED DATABASE | ||
YOU CANNOT UNDO THIS COMMAND | ||
""" | ||
print_help(help_string) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
def proto_args(parser, parents): | ||
nfs_parser = parser.add_parser("nfs", help="NFS", parents=parents) | ||
nfs_parser.add_argument("--port", type=int, default=111, help="NFS portmapper port (default: %(default)s)") | ||
nfs_parser.add_argument("--nfs-timeout", type=int, default=30, help="NFS connection timeout (default: %(default)ss)") | ||
|
||
dgroup = nfs_parser.add_argument_group("NFS Mapping/Enumeration", "Options for Mapping/Enumerating NFS") | ||
dgroup.add_argument("--shares", action="store_true", help="List NFS shares") | ||
dgroup.add_argument("--enum-shares", nargs="?", type=int, const=3, help="Authenticate and enumerate exposed shares recursively (default depth: %(const)s)") | ||
dgroup.add_argument("--get-file", nargs=2, metavar="FILE", help="Download remote NFS file. Example: --get-file remote_file local_file") | ||
dgroup.add_argument("--put-file", nargs=2, metavar="FILE", help="Upload remote NFS file with chmod 777 permissions to the specified folder. Example: --put-file local_file remote_file") | ||
|
||
return parser |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters