Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
7c1ee43b0a |
38
README.md
38
README.md
@@ -5,8 +5,8 @@ It allows you to jail Python programs in a closed off filesystem
|
|||||||
|
|
||||||
## How to install
|
## How to install
|
||||||
|
|
||||||
Installing PyJail is really simple! Just run `python3 ./install.py`
|
Installing PyJail is really simple! Just run `python3 ./install.py` in the directory
|
||||||
(for Windows `py .\install.py`) in the directory where the files are stored!
|
where the files are stored!
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@ As of now we're still working on a custom Python interpreter to make all program
|
|||||||
fully jailing compatible, sadly enough it's quite hard work.
|
fully jailing compatible, sadly enough it's quite hard work.
|
||||||
So as of now it is compatible with all Python programs, **but** only some will be
|
So as of now it is compatible with all Python programs, **but** only some will be
|
||||||
properly confined.
|
properly confined.
|
||||||
There is a converter to automatically convert tools, but some still aren't compatible yet.
|
|
||||||
|
|
||||||
## POSIX compatibility
|
## POSIX compatibility
|
||||||
|
|
||||||
@@ -23,46 +22,17 @@ made for Linux to also run natively on Windows. This is more meant for Windows
|
|||||||
versions that don't feature WSL (Windows 7/8/8.1) but still need to run some
|
versions that don't feature WSL (Windows 7/8/8.1) but still need to run some
|
||||||
Linux only scripts.
|
Linux only scripts.
|
||||||
|
|
||||||
## Bundled programs
|
### The 4 branches
|
||||||
|
|
||||||
To keep the installation extremely small in size and footprint, the bundled programs are also
|
|
||||||
extremely small. Currently we bundle 3 programs:
|
|
||||||
|
|
||||||
### `sh.py` (While installed: `/bin/sh` or `/usr/bin/sh` or `/usr/bin/shell.py`)
|
|
||||||
A very simple shell, just does directory navigation and installs packages.
|
|
||||||
|
|
||||||
### `ledit.py` (While installed: `/usr/bin/ledit.py`)
|
|
||||||
A simple line text editor. Meant for extreme simplicity.
|
|
||||||
|
|
||||||
### `autoconvert.py` (While installed: `/usr/bin/autoconvert.py`)
|
|
||||||
A converter to convert Python programs to be compatible with the jailed filesystem.
|
|
||||||
|
|
||||||
|
|
||||||
We recommend getting essential packages like a proper shell and the UwUGet package manager.
|
|
||||||
|
|
||||||
## The 4 branches
|
|
||||||
|
|
||||||
Which branch works best for you?
|
Which branch works best for you?
|
||||||
|
|
||||||
|
|
||||||
Well, that's pretty simple. We have 4 branches (`main`, `next`, `edge` and `no-posix`).
|
Well, that's pretty simple. We have 4 branches (`main`, `next`, `edge` and `no-posix`).
|
||||||
|
|
||||||
|
|
||||||
If you want the most stable experience, then the `main` branch is for you.
|
If you want the most stable experience, then the `main` branch is for you.
|
||||||
|
|
||||||
|
|
||||||
If you want the lastest features, but also a more stable experience (compared to `edge`),
|
If you want the lastest features, but also a more stable experience (compared to `edge`),
|
||||||
then the `next` branch is for you
|
then the `next` branch is for you
|
||||||
|
|
||||||
|
|
||||||
If you want the bleeding-edge and don't care about stability, then `edge` is for you.
|
If you want the bleeding-edge and don't care about stability, then `edge` is for you.
|
||||||
|
|
||||||
|
|
||||||
If you only need simple jailing and no POSIX compatibility, then `no-posix` is for you.
|
If you only need simple jailing and no POSIX compatibility, then `no-posix` is for you.
|
||||||
|
|
||||||
## Issues
|
### Issues
|
||||||
|
|
||||||
Please report issues [over here](https://git.novacow.ch/Nova/PyJail/issues/)
|
Please report issues [over here](https://git.novacow.ch/Nova/PyJail/issues/)
|
||||||
|
|
||||||
|
|
||||||
And please check if your issue isn't a duplicate before reporting.
|
And please check if your issue isn't a duplicate before reporting.
|
||||||
|
@@ -1,82 +0,0 @@
|
|||||||
"""
|
|
||||||
Converts files to be jail-compatible
|
|
||||||
"""
|
|
||||||
|
|
||||||
import importlib
|
|
||||||
|
|
||||||
|
|
||||||
class FileConverter:
|
|
||||||
def __init__(self):
|
|
||||||
self.jail_mgr = importlib.import_module(".jail_mgr", "vfs.sys")
|
|
||||||
self.jailmgr = self.jail_mgr.PyJail()
|
|
||||||
self._file_openers = ["os.path", "open", "shutil.copy", "shutil.rm"]
|
|
||||||
self._unsupported_file_openers = ["QFile"]
|
|
||||||
|
|
||||||
def convert_file(self, fn):
|
|
||||||
unsupported_openers_found = 0
|
|
||||||
lines = []
|
|
||||||
with open(self.jailmgr.fs(fn), "a") as f:
|
|
||||||
for line in f:
|
|
||||||
line = line.strip()
|
|
||||||
lines.append(line)
|
|
||||||
blank_line_found = False
|
|
||||||
init_found = False
|
|
||||||
i_total = 0
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
if line == "" and blank_line_found is False:
|
|
||||||
line = "import importlib\n"
|
|
||||||
lines[i] = line
|
|
||||||
blank_line_found = True
|
|
||||||
if "def __init__" in line and init_found is False:
|
|
||||||
line_to_export = (
|
|
||||||
"\nself.jail_mgr = importlib.import_module('.jail_mgr', 'vfs.sys')\n"
|
|
||||||
"self.jailmgr = self.jail_mgr.PyJail()"
|
|
||||||
)
|
|
||||||
lines[i + 1] = line_to_export
|
|
||||||
init_found = True
|
|
||||||
if self._file_openers in line:
|
|
||||||
idx = line.index("(")
|
|
||||||
idx2 = line.index(")")
|
|
||||||
# if idx2 - idx != 1:
|
|
||||||
# self.jailmgr.msg(f"{self}", "Unsupported type!", False, "WARN")
|
|
||||||
# unsupported_openers_found += 1
|
|
||||||
# else:
|
|
||||||
expression = line[idx : idx2 + 1]
|
|
||||||
line_to_edit = f"self.jailmgr.fs({expression})"
|
|
||||||
idx -= 1
|
|
||||||
idx2 += 2
|
|
||||||
full_line = f"{line[:idx]}{line_to_edit}{line[idx2:]}"
|
|
||||||
lines[i] = full_line
|
|
||||||
elif self._unsupported_file_openers in line:
|
|
||||||
self.jailmgr.msg(f"{self}", "Unsupported opener!", False, "WARN")
|
|
||||||
unsupported_openers_found += 1
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
i_total = i
|
|
||||||
if unsupported_openers_found > 0:
|
|
||||||
self.jailmgr.msg(
|
|
||||||
f"{self}",
|
|
||||||
f"Some/all of the openers in this file aren't compatible with the converter, amount: {unsupported_openers_found} of the {i_total}",
|
|
||||||
True,
|
|
||||||
"WARN",
|
|
||||||
)
|
|
||||||
return lines
|
|
||||||
|
|
||||||
def file_writer(self, fn, content):
|
|
||||||
for i, line in enumerate(content):
|
|
||||||
line.rstrip("\n")
|
|
||||||
with open(self.jailmgr.fs(fn), "a+") as f:
|
|
||||||
f.write(f"{line}\n")
|
|
||||||
f.close()
|
|
||||||
self.jailmgr.msg(f"{self}", "Conversion OK! Please check results.", True)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
fc = FileConverter()
|
|
||||||
fn = input("Enter filepath to convert (fullpath): ")
|
|
||||||
try:
|
|
||||||
lines = fc.convert_file(fn)
|
|
||||||
fc.file_writer(lines)
|
|
||||||
except Exception:
|
|
||||||
print("Failure to convert!")
|
|
71
install.py
71
install.py
@@ -1,11 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
Install script for the Python jailer.
|
Install script for the Python jailer.
|
||||||
Version: 0.3.0-main1
|
Version: 1.0.0-main1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
with open("./kverinfo.txt", "r") as f:
|
with open("./kverinfo.txt", "r") as f:
|
||||||
kver = f.read()
|
kver = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
@@ -25,50 +23,65 @@ shutil.move("./main.py", "./vfs/main.py")
|
|||||||
shutil.move("./runner.py", "./main.py")
|
shutil.move("./runner.py", "./main.py")
|
||||||
shutil.move("./sh.py", "./vfs/sh.py")
|
shutil.move("./sh.py", "./vfs/sh.py")
|
||||||
shutil.move("./ledit.py", "./vfs/ledit.py")
|
shutil.move("./ledit.py", "./vfs/ledit.py")
|
||||||
shutil.move("./autoconvert.py" "./vfs/autoconvert.py")
|
|
||||||
os.chdir(os.getcwd() + "/vfs")
|
os.chdir(os.getcwd() + "/vfs")
|
||||||
print("Gathering info...")
|
print("Gathering info...")
|
||||||
usrname = input("Please enter your username: [usr1] ")
|
usrname = input("Please enter your username: [usr1] ")
|
||||||
if usrname == "":
|
if usrname == "":
|
||||||
usrname = "usr1"
|
usrname = "usr1"
|
||||||
print("Creating directories...")
|
setup_posix = input("Do you wish to setup a mostly-POSIX compliant environment? [y/N] ")
|
||||||
with open("./bin", "a+") as f:
|
if setup_posix.lower() == "y":
|
||||||
|
print("Creating directories...")
|
||||||
|
with open("./bin", "a+") as f:
|
||||||
f.write("symlnk /usr/bin/")
|
f.write("symlnk /usr/bin/")
|
||||||
f.close()
|
f.close()
|
||||||
with open("./sbin", "a+") as f:
|
with open("./sbin", "a+") as f:
|
||||||
f.write("symlnk /usr/sbin/")
|
f.write("symlnk /usr/sbin/")
|
||||||
f.close()
|
f.close()
|
||||||
with open("./lib", "a+") as f:
|
with open("./lib", "a+") as f:
|
||||||
f.write("symlnk /usr/lib/")
|
f.write("symlnk /usr/lib/")
|
||||||
f.close()
|
f.close()
|
||||||
with open("./lib64", "a+") as f:
|
with open("./lib64", "a+") as f:
|
||||||
f.write("symlnk /usr/lib64/")
|
f.write("symlnk /usr/lib64/")
|
||||||
f.close()
|
f.close()
|
||||||
with open("./usr/bin/sh", "a+") as f:
|
with open("./usr/bin/sh", "a+") as f:
|
||||||
f.write("symlnk /usr/bin/shell.py")
|
f.write("symlnk /usr/bin/shell.py")
|
||||||
f.close()
|
f.close()
|
||||||
os.mkdir("./sys")
|
os.mkdir("./sys")
|
||||||
os.mkdir("./usr")
|
os.mkdir("./usr")
|
||||||
os.mkdir("./proc")
|
os.mkdir("./proc")
|
||||||
os.mkdir(f"./home/{usrname}")
|
os.mkdir(f"./home/{usrname}")
|
||||||
os.mkdir("./usr/bin/")
|
os.mkdir("./usr/bin/")
|
||||||
os.mkdir("./usr/sbin/")
|
os.mkdir("./usr/sbin/")
|
||||||
os.mkdir("./usr/lib/")
|
os.mkdir("./usr/lib/")
|
||||||
os.mkdir("./usr/lib64/")
|
os.mkdir("./usr/lib64/")
|
||||||
print("Copying files...")
|
print("Copying files...")
|
||||||
shutil.move("./main.py", "./sys/jail_mgr.py")
|
shutil.move("./main.py", "./sys/jail_mgr.py")
|
||||||
shutil.move("./sh.py", "./usr/bin/shell.py")
|
shutil.move("./sh.py", "./bin/shell.py")
|
||||||
shutil.move("./ledit.py", "./usr/bin/ledit.py")
|
shutil.move("./ledit.py", "./bin/ledit.py")
|
||||||
shutil.move("./autoconvert.py", "./usr/bin/autoconvert.py")
|
print("Creating system configuration files...")
|
||||||
print("Creating system configuration files...")
|
with open("./sys/usr.conf", "a+") as f:
|
||||||
with open("./sys/usr.conf", "a+") as f:
|
|
||||||
f.write(usrname)
|
f.write(usrname)
|
||||||
f.close()
|
f.close()
|
||||||
with open("./sys/procinfo", "a+") as f:
|
with open("./sys/procinfo", "a+") as f:
|
||||||
f.write("proc: vfs(/proc/)\nkernel: vfs(/proc/kcore)")
|
f.write("proc: vfs(/proc/)\nmgr: vfs(/proc/kcore)")
|
||||||
f.close()
|
f.close()
|
||||||
with open("./proc/kcore", "a+") as f:
|
with open("./proc/kcore", "a+") as f:
|
||||||
f.write("/sys/jail_mgr.py")
|
f.write("/sys/jail_mgr.py")
|
||||||
f.close()
|
f.close()
|
||||||
print("Install completed! Run ./main.py to start the process!")
|
else:
|
||||||
|
print("Creating directories...")
|
||||||
|
os.mkdir("./bin")
|
||||||
|
os.mkdir("./sys")
|
||||||
|
os.mkdir("./usr")
|
||||||
|
os.mkdir("./proc")
|
||||||
|
os.mkdir(f"./home/{usrname}")
|
||||||
|
print("Copying files...")
|
||||||
|
shutil.move("./main.py", "./sys/jail_mgr.py")
|
||||||
|
shutil.move("./sh.py", "./bin/shell.py")
|
||||||
|
shutil.move("./ledit.py", "./bin/ledit.py")
|
||||||
|
print("Creating system configuration files...")
|
||||||
|
with open("./sys/usr.conf", "a+") as f:
|
||||||
|
f.write(usrname)
|
||||||
|
f.close()
|
||||||
|
print("Install completed! Run ./main.py to start the kernel!")
|
||||||
input("Press <Enter> to exit! ")
|
input("Press <Enter> to exit! ")
|
||||||
|
@@ -1 +1 @@
|
|||||||
edge0005-base0.2.1
|
0.2.0-main1
|
||||||
|
6
ledit.py
6
ledit.py
@@ -3,12 +3,9 @@ LEdit, a single line text editor made in Python
|
|||||||
Version: 0.0.2-alpha1
|
Version: 0.0.2-alpha1
|
||||||
Made as an example program for PyNVOS
|
Made as an example program for PyNVOS
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ledit:
|
class ledit:
|
||||||
def __init__(self, instance):
|
def __init__(self, instance):
|
||||||
self._kernel = instance
|
self._kernel = instance
|
||||||
|
|
||||||
def prgm(self):
|
def prgm(self):
|
||||||
path_to_file = input("Enter location of file to edit/create: ")
|
path_to_file = input("Enter location of file to edit/create: ")
|
||||||
path_to_file = self._kernel.fs(path_to_file)
|
path_to_file = self._kernel.fs(path_to_file)
|
||||||
@@ -17,7 +14,4 @@ class ledit:
|
|||||||
f.write(text_to_write + "\n")
|
f.write(text_to_write + "\n")
|
||||||
f.close()
|
f.close()
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "<run_path>":
|
if __name__ == "<run_path>":
|
||||||
raise NotImplementedError("no")
|
|
||||||
|
163
main.py
163
main.py
@@ -1,8 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
This is the PyJail, a jailing tool for running Python apps in a sandboxed environment.
|
This is the PyJail, a jailing tool for running Python apps in a sandboxed environment.
|
||||||
Version: edge0007-base0.2.1
|
Version: 0.2.0-main1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import runpy
|
import runpy
|
||||||
@@ -10,9 +9,8 @@ import runpy
|
|||||||
|
|
||||||
class PyJail:
|
class PyJail:
|
||||||
"""
|
"""
|
||||||
The jail manager, handles all system calls and such.
|
The
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, debug=False):
|
def __init__(self, debug=False):
|
||||||
self.rootpath = ""
|
self.rootpath = ""
|
||||||
self.rootpath = self.fs()
|
self.rootpath = self.fs()
|
||||||
@@ -32,22 +30,18 @@ class PyJail:
|
|||||||
Runs a specified program.
|
Runs a specified program.
|
||||||
"""
|
"""
|
||||||
path_to_bin = self.fs(path_to_bin)
|
path_to_bin = self.fs(path_to_bin)
|
||||||
|
# print(path_to_bin)
|
||||||
|
# print(str(self.rootpath) + str(path_to_bin))
|
||||||
if path_to_bin == 3 or path_to_bin == 2:
|
if path_to_bin == 3 or path_to_bin == 2:
|
||||||
self.msg(
|
self.msg("jailmgr.run_program()", "An error has occurred launching the program.", True,
|
||||||
"jailmgr.run_program()",
|
"WARNING")
|
||||||
"An error has occurred launching the program.",
|
|
||||||
True,
|
|
||||||
"WARNING",
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
with open(self.fs("/proc/kproc"), "a+") as f:
|
with open(self.fs("/proc/kproc"), "a+") as f:
|
||||||
f.write(f"proc: {path_to_bin}({self._program_counter})")
|
f.write(f"proc: {path_to_bin}({self._program_counter})")
|
||||||
self._program_counter += 1
|
self._program_counter += 1
|
||||||
runpy.run_path(path_to_bin)
|
runpy.run_path(path_to_bin)
|
||||||
|
|
||||||
def msg(
|
def msg(self, caller: str, message:str, emit: bool = False, log_level: str = "INFO"):
|
||||||
self, caller: str, message: str, emit: bool = False, log_level: str = "INFO"
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
The custom message parser, can parse messages and alert apps of said messages.
|
The custom message parser, can parse messages and alert apps of said messages.
|
||||||
Replaces print statements.
|
Replaces print statements.
|
||||||
@@ -57,27 +51,15 @@ class PyJail:
|
|||||||
emit: If the message needs to be passed to apps.
|
emit: If the message needs to be passed to apps.
|
||||||
log_level: The loglevel, either DEBUG, INFO, WARNING, ERROR, CRITICAL
|
log_level: The loglevel, either DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||||
"""
|
"""
|
||||||
emit_full = False
|
|
||||||
if self._debug is True:
|
if self._debug is True:
|
||||||
emit_full = True
|
emit = True
|
||||||
accepted_log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
accepted_log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
||||||
if log_level.upper() not in accepted_log_levels:
|
if log_level.upper() not in accepted_log_levels:
|
||||||
self.msg(
|
self.msg(f"jailmgr.msg()",f"Not accepted loglevel!! {log_level}", False, "ERROR")
|
||||||
"jailmgr.msg()", f"Not accepted loglevel!! {log_level}", False, "ERROR"
|
|
||||||
)
|
|
||||||
return 1
|
|
||||||
if log_level == "DEBUG" and self._debug is False:
|
|
||||||
emit = False
|
|
||||||
emit_full = False
|
|
||||||
msg = f"[{time.time}] [{caller}] [{log_level}] {message}"
|
|
||||||
with open(self.fs("/proc/klog"), "a+") as f:
|
with open(self.fs("/proc/klog"), "a+") as f:
|
||||||
f.write(msg)
|
f.write(f"[{time.time}] [{caller}] [{log_level}] {message}")
|
||||||
if emit is True and log_level.upper() == "CRITICAL":
|
if emit is True:
|
||||||
print(msg)
|
|
||||||
elif emit is True:
|
|
||||||
print(message)
|
print(message)
|
||||||
elif emit_full is True:
|
|
||||||
print(msg)
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def fs(self, check_path=None, resolve_symlinks=True):
|
def fs(self, check_path=None, resolve_symlinks=True):
|
||||||
@@ -99,11 +81,7 @@ class PyJail:
|
|||||||
check_path_split = check_path.split("/", -1)
|
check_path_split = check_path.split("/", -1)
|
||||||
prepend_path = ""
|
prepend_path = ""
|
||||||
for i, path in enumerate(check_path_split):
|
for i, path in enumerate(check_path_split):
|
||||||
prepend_path = (
|
prepend_path = f"{prepend_path}/{path}" if not path.endswith("/") else f"{prepend_path}/{path}/"
|
||||||
f"{prepend_path}/{path}"
|
|
||||||
if not path.endswith("/")
|
|
||||||
else f"{prepend_path}/{path}/"
|
|
||||||
)
|
|
||||||
check_path_split[i] = f"{prepend_path}"
|
check_path_split[i] = f"{prepend_path}"
|
||||||
check_path = ""
|
check_path = ""
|
||||||
for i, path in enumerate(check_path_split):
|
for i, path in enumerate(check_path_split):
|
||||||
@@ -113,9 +91,7 @@ class PyJail:
|
|||||||
elif os.path.isdir(path) and i == (len(check_path_split) - 1):
|
elif os.path.isdir(path) and i == (len(check_path_split) - 1):
|
||||||
# The last thing to access was a directory. We can safely return the full path now.
|
# The last thing to access was a directory. We can safely return the full path now.
|
||||||
return path
|
return path
|
||||||
elif not os.path.isdir(path) and i != (
|
elif not os.path.isdir(path) and i != (len(check_path_split) - 1):
|
||||||
len(check_path_split) - 1
|
|
||||||
):
|
|
||||||
# This was not the last thing we needed to access, so we assume it's a symlink.
|
# This was not the last thing we needed to access, so we assume it's a symlink.
|
||||||
# One problem is that we can't be sure, so we make sure it is a symlink.
|
# One problem is that we can't be sure, so we make sure it is a symlink.
|
||||||
with open(self.fs(path, False)) as f:
|
with open(self.fs(path, False)) as f:
|
||||||
@@ -125,27 +101,19 @@ class PyJail:
|
|||||||
# This is a symlink!
|
# This is a symlink!
|
||||||
# Symlinks always contain the full literal path that they need to access, so we can
|
# Symlinks always contain the full literal path that they need to access, so we can
|
||||||
# take that and do the same trick to split it and add the next things to it.
|
# take that and do the same trick to split it and add the next things to it.
|
||||||
|
# raise NotImplementedError()
|
||||||
is_symlink_split = is_symlink.split(" ", 1)
|
is_symlink_split = is_symlink.split(" ", 1)
|
||||||
symlink_dest = is_symlink_split[1]
|
symlink_dest = is_symlink_split[1]
|
||||||
symlink_dest = f"{symlink_dest}/{path}"
|
symlink_dest = f"{symlink_dest}/{path}"
|
||||||
return symlink_dest
|
return symlink_dest
|
||||||
else:
|
else:
|
||||||
# This is either not a symlink or an improperly configured one.
|
# This is either not a symlink or an improperly configured one.
|
||||||
self.msg(
|
self.msg("jailmgr.fs()", "reached non-symlink file not at end of list",
|
||||||
"jailmgr.fs()",
|
False, "ERROR")
|
||||||
"reached non-symlink file not at end of list",
|
self.msg("jailmgr.fs()", "What was assumed to be a directory isn't a"
|
||||||
False,
|
|
||||||
"ERROR",
|
|
||||||
)
|
|
||||||
self.msg(
|
|
||||||
"jailmgr.fs()",
|
|
||||||
"What was assumed to be a directory isn't a"
|
|
||||||
" directory nor a symlink! This might be because of a "
|
" directory nor a symlink! This might be because of a "
|
||||||
"typo or misconfigured symlink. The directory in question: "
|
"typo or misconfigured symlink. The directory in question: "
|
||||||
f"{path}",
|
f"{path}", True, "WARNING")
|
||||||
True,
|
|
||||||
"WARNING",
|
|
||||||
)
|
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
return self.rootpath + check_path
|
return self.rootpath + check_path
|
||||||
@@ -153,103 +121,20 @@ class PyJail:
|
|||||||
check_path = check_path.lstrip(".")
|
check_path = check_path.lstrip(".")
|
||||||
return os.getcwd() + check_path if "vfs" in os.getcwd() else 2
|
return os.getcwd() + check_path if "vfs" in os.getcwd() else 2
|
||||||
elif self.rootpath in check_path:
|
elif self.rootpath in check_path:
|
||||||
self.msg(
|
self.msg(f"jailmgr.fs()", "Cannot parse rootpath, expected vfspath", log_level="ERROR")
|
||||||
"jailmgr.fs()",
|
|
||||||
"Cannot parse rootpath, expected vfspath",
|
|
||||||
log_level="ERROR",
|
|
||||||
)
|
|
||||||
return 3
|
return 3
|
||||||
else:
|
else:
|
||||||
# Path is not in the jailed fs, so we say it doesn't exist.
|
# Path is not in the jailed fs, so we say it doesn't exist.
|
||||||
self.msg(
|
self.msg(f"jailmgr.fs()", "File/directory doesn't exist in vfspath", log_level="ERROR")
|
||||||
"jailmgr.fs()",
|
|
||||||
"File/directory doesn't exist in vfspath",
|
|
||||||
log_level="ERROR",
|
|
||||||
)
|
|
||||||
return 2
|
return 2
|
||||||
else:
|
else:
|
||||||
rootpath = os.getcwd() + "/vfs"
|
rootpath = os.getcwd() + "/vfs"
|
||||||
self.msg("jailmgr.fs()", message=rootpath, log_level="INFO")
|
self.msg("jailmgr.fs()", message=rootpath, log_level="INFO")
|
||||||
return rootpath
|
return rootpath
|
||||||
|
|
||||||
def kver(self):
|
@staticmethod
|
||||||
|
def kver():
|
||||||
"""
|
"""
|
||||||
Returns the kernel version
|
Returns the jail manager version
|
||||||
"""
|
"""
|
||||||
return "edge0007-base0.2.1"
|
return "0.2.0-main1"
|
||||||
|
|
||||||
def netsock(self, ip, port, mode, msg):
|
|
||||||
"""
|
|
||||||
An easy interface to network sockets, built right into the jailmanager
|
|
||||||
|
|
||||||
Args:
|
|
||||||
ip: The IP of the server to access.
|
|
||||||
port: The port to access the server on
|
|
||||||
mode: Either UDP, TCP or PKG (HTTP)
|
|
||||||
msg: The message to send the server
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Whatever the server returns.
|
|
||||||
"""
|
|
||||||
if mode == "PKG":
|
|
||||||
import requests
|
|
||||||
else:
|
|
||||||
import socket
|
|
||||||
|
|
||||||
if mode == "TCP":
|
|
||||||
try:
|
|
||||||
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
except Exception:
|
|
||||||
self.msg(
|
|
||||||
"jailmgr.netsock()", "Socket import failed!", False, "CRITICAL"
|
|
||||||
)
|
|
||||||
self.msg(
|
|
||||||
"jailmgr.netsock()", "An unexpected error occurred!", True, "ERROR"
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
# Connect to the server
|
|
||||||
client_socket.connect((ip, port))
|
|
||||||
self.msg(
|
|
||||||
"jailmgr.netsock()",
|
|
||||||
f"Connected to server at {ip}:{port}",
|
|
||||||
False,
|
|
||||||
"INFO",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Send the message to the server
|
|
||||||
client_socket.send(msg.encode())
|
|
||||||
|
|
||||||
# Receive the response from the server
|
|
||||||
response = client_socket.recv(1024).decode()
|
|
||||||
client_socket.close() # Close the connection
|
|
||||||
self.msg("jailmgr.netsock", f"Received from server: {response}")
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
elif mode == "PKG":
|
|
||||||
# raise NotImplementedError("TODO: PKG will be implemented later!")
|
|
||||||
file_io = requests.get(ip)
|
|
||||||
if file_io.startswith("PYPAK PMD"):
|
|
||||||
with open(self.fs(f"/usr/netsock/cache/{msg}.pmd"), "a+") as f:
|
|
||||||
f.write(file_io)
|
|
||||||
f.close()
|
|
||||||
else:
|
|
||||||
with open(self.fs(f"/usr/netsock/cache/{msg}.py"), "a+") as f:
|
|
||||||
f.write(file_io)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
else:
|
|
||||||
# Create a UDP socket
|
|
||||||
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
|
|
||||||
# Send the message to the server
|
|
||||||
client_socket.sendto(msg.encode(), (ip, port))
|
|
||||||
|
|
||||||
# Receive the response from the server
|
|
||||||
response, _ = client_socket.recvfrom(1024)
|
|
||||||
self.msg(f"{self}", f"Received from server: {response.decode()}")
|
|
||||||
|
|
||||||
# Close the socket
|
|
||||||
client_socket.close()
|
|
||||||
|
|
||||||
# raise NotImplementedError("TODO: Netsock will be implemented once 0.3.0 comes around!")
|
|
||||||
|
64
sh.py
64
sh.py
@@ -1,85 +1,51 @@
|
|||||||
"""
|
"""
|
||||||
The shell for PyNVOS
|
The shell for PyNVOS
|
||||||
Version: 0.2.0.0402
|
Version: 0.1.0-main1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
import cmd
|
import cmd
|
||||||
import shutil
|
|
||||||
|
|
||||||
|
|
||||||
|
# from ..sys.krnl import Kernel
|
||||||
|
print(__name__)
|
||||||
class shell(cmd.Cmd):
|
class shell(cmd.Cmd):
|
||||||
jail_mgr = importlib.import_module(".jail_mgr", "vfs.sys")
|
intro = "Shell started, PyNVOS 0.1.1-main1"
|
||||||
jailmgr = jail_mgr.PyJail()
|
prompt = "shell-0.1.0$ "
|
||||||
kver = jailmgr.kver()
|
|
||||||
intro = f"Shell started, PyJail {kver}"
|
|
||||||
prompt = "shell-0.2$ "
|
|
||||||
file = None
|
file = None
|
||||||
|
krnl = importlib.import_module(".jail_mgr", "vfs.sys")
|
||||||
|
kernel = krnl.Kernel()
|
||||||
|
print(str(kernel) + " " + str(type(kernel)))
|
||||||
|
|
||||||
def do_cd(self, args):
|
def do_cd(self, args):
|
||||||
"""Changes directory"""
|
"""Changes directory"""
|
||||||
args = shell.jailmgr.fs(args)
|
args = shell.kernel.fs(args)
|
||||||
os.chdir(args)
|
os.chdir(args)
|
||||||
|
|
||||||
def do_exec(self, args):
|
def do_exec(self, args):
|
||||||
"""Allows you to execute a file"""
|
"""Allows you to execute a file"""
|
||||||
# Apps in /bin should be allowed to launch without first adding /bin/ or ./, just the name of the executable
|
# Apps in /bin should be allowed to launch without first adding /bin/ or ./, just the name of the executable
|
||||||
# So for ledit it should be just 'ledit' and not /bin/ledit.py or ./ledit.py
|
# So for ledit it should be just 'ledit' and not /bin/ledit.py or ./ledit.py
|
||||||
bins_in_bin = os.listdir(self.jailmgr.fs("/bin"))
|
bins_in_bin = os.listdir(shell.kernel.fs("/bin"))
|
||||||
apps_strip = []
|
apps_strip = []
|
||||||
for apps in bins_in_bin:
|
for apps in bins_in_bin:
|
||||||
if apps.endswith(".py"):
|
if apps.endswith(".py"):
|
||||||
apps_strip.append(apps.strip(".py"))
|
apps_strip.append(apps.strip(".py"))
|
||||||
if args in apps_strip:
|
if args in apps_strip:
|
||||||
shell.jailmgr.run_program(f"/bin/{args}.py")
|
shell.kernel.run_program(f"/bin/{args}.py")
|
||||||
else:
|
else:
|
||||||
shell.jailmgr.run_program(args)
|
shell.kernel.run_program(args)
|
||||||
|
|
||||||
def do_ls(self, none):
|
def do_ls(self, none):
|
||||||
"""Lists the content of a directory"""
|
"""Lists the content of a directory"""
|
||||||
os.listdir(os.getcwd())
|
os.listdir(os.getcwd())
|
||||||
|
|
||||||
def do_pkg(self, pkg):
|
|
||||||
"""Downloads packages over the internet."""
|
|
||||||
self.jailmgr.netsock(
|
|
||||||
f"https://pkg.novacow.ch/repo/{self.kver}/meta/{pkg}.pmd",
|
|
||||||
None,
|
|
||||||
"PKG",
|
|
||||||
f"{pkg}",
|
|
||||||
)
|
|
||||||
shutil.copy(
|
|
||||||
self.jailmgr.fs(f"/usr/netsock/cache/{pkg}.pmd"),
|
|
||||||
self.jailmgr.fs("/usr/pkg/metacache/"),
|
|
||||||
)
|
|
||||||
with open(self.jailmgr.fs(f"/usr/pkg/metacache/{pkg}.pmd"), "r") as f:
|
|
||||||
package_meta = f.read()
|
|
||||||
f.close()
|
|
||||||
self.jailmgr.msg("shell.do_pkg", package_meta, True, "INFO")
|
|
||||||
y_n_confirmation = input("Do you want to install this package? [y/N] ")
|
|
||||||
if y_n_confirmation.lower() != "y":
|
|
||||||
print("Aborted.")
|
|
||||||
return
|
|
||||||
self.jailmgr.netsock(
|
|
||||||
f"https://pkg.novacow.ch/repo/{self.kver}/main/static/binary/{pkg}.py",
|
|
||||||
None,
|
|
||||||
"PKG",
|
|
||||||
f"{pkg}",
|
|
||||||
)
|
|
||||||
shutil.copy(
|
|
||||||
self.jailmgr.fs(f"/usr/netsock/cache/{pkg}.py"),
|
|
||||||
self.jailmgr.fs("/usr/bin/"),
|
|
||||||
)
|
|
||||||
|
|
||||||
def postloop(self):
|
def postloop(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "<run_path>":
|
if __name__ == '<run_path>':
|
||||||
shell().cmdloop()
|
shell().cmdloop()
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
print(
|
print("The shell can't be ran as a standalone program and must be ran in conjunction with the kernel.")
|
||||||
"The shell can't be ran as a standalone program and must be ran in conjunction with the jail manager."
|
|
||||||
)
|
|
||||||
input("Press Enter to continue...")
|
input("Press Enter to continue...")
|
||||||
exit(-1)
|
exit(-1)
|
@@ -1 +1 @@
|
|||||||
edge
|
0.2 build 0036
|
||||||
|
Reference in New Issue
Block a user