Add Master files.
This commit is contained in:
87
install.py
Normal file
87
install.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
"""
|
||||||
|
Install script for the Python jailer.
|
||||||
|
Version: 1.0.0-main1
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
with open("./kverinfo.txt", "r") as f:
|
||||||
|
kver = f.read()
|
||||||
|
f.close()
|
||||||
|
with open("./verinfo.txt", "r") as f:
|
||||||
|
ver = f.read()
|
||||||
|
f.close()
|
||||||
|
print("Welcome to the PyJail install wizard.")
|
||||||
|
print(f"You are about to install version {ver} with manager {kver}")
|
||||||
|
y_n_question = input("Do you want to install PyJail? [Y/n] ")
|
||||||
|
if y_n_question.lower() == "n":
|
||||||
|
print("Installation cancelled!")
|
||||||
|
input("Press <Enter> to exit ")
|
||||||
|
exit(-1)
|
||||||
|
print("Preparing installation...")
|
||||||
|
os.mkdir(os.getcwd() + "/vfs")
|
||||||
|
shutil.move("./main.py", "./vfs/main.py")
|
||||||
|
shutil.move("./runner.py", "./main.py")
|
||||||
|
shutil.move("./sh.py", "./vfs/sh.py")
|
||||||
|
shutil.move("./ledit.py", "./vfs/ledit.py")
|
||||||
|
os.chdir(os.getcwd() + "/vfs")
|
||||||
|
print("Gathering info...")
|
||||||
|
usrname = input("Please enter your username: [usr1] ")
|
||||||
|
if usrname == "":
|
||||||
|
usrname = "usr1"
|
||||||
|
setup_posix = input("Do you wish to setup a mostly-POSIX compliant environment? [y/N] ")
|
||||||
|
if setup_posix.lower() == "y":
|
||||||
|
print("Creating directories...")
|
||||||
|
with open("./bin", "a+") as f:
|
||||||
|
f.write("symlnk /usr/bin/")
|
||||||
|
f.close()
|
||||||
|
with open("./sbin", "a+") as f:
|
||||||
|
f.write("symlnk /usr/sbin/")
|
||||||
|
f.close()
|
||||||
|
with open("./lib", "a+") as f:
|
||||||
|
f.write("symlnk /usr/lib/")
|
||||||
|
f.close()
|
||||||
|
with open("./lib64", "a+") as f:
|
||||||
|
f.write("symlnk /usr/lib64/")
|
||||||
|
f.close()
|
||||||
|
with open("./usr/bin/sh", "a+") as f:
|
||||||
|
f.write("symlnk /usr/bin/shell.py")
|
||||||
|
f.close()
|
||||||
|
os.mkdir("./sys")
|
||||||
|
os.mkdir("./usr")
|
||||||
|
os.mkdir("./proc")
|
||||||
|
os.mkdir(f"./home/{usrname}")
|
||||||
|
os.mkdir("./usr/bin/")
|
||||||
|
os.mkdir("./usr/sbin/")
|
||||||
|
os.mkdir("./usr/lib/")
|
||||||
|
os.mkdir("./usr/lib64/")
|
||||||
|
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()
|
||||||
|
with open("./sys/procinfo", "a+") as f:
|
||||||
|
f.write("proc: vfs(/proc/)\nmgr: vfs(/proc/kcore)")
|
||||||
|
f.close()
|
||||||
|
with open("./proc/kcore", "a+") as f:
|
||||||
|
f.write("/sys/jail_mgr.py")
|
||||||
|
f.close()
|
||||||
|
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! ")
|
1
kverinfo.txt
Normal file
1
kverinfo.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0.2.0-main1
|
17
ledit.py
Normal file
17
ledit.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
"""
|
||||||
|
LEdit, a single line text editor made in Python
|
||||||
|
Version: 0.0.2-alpha1
|
||||||
|
Made as an example program for PyNVOS
|
||||||
|
"""
|
||||||
|
class ledit:
|
||||||
|
def __init__(self, instance):
|
||||||
|
self._kernel = instance
|
||||||
|
def prgm(self):
|
||||||
|
path_to_file = input("Enter location of file to edit/create: ")
|
||||||
|
path_to_file = self._kernel.fs(path_to_file)
|
||||||
|
with open(path_to_file, "a+") as f:
|
||||||
|
text_to_write = input("Line: ")
|
||||||
|
f.write(text_to_write + "\n")
|
||||||
|
f.close()
|
||||||
|
exit()
|
||||||
|
if __name__ == "<run_path>":
|
140
main.py
Normal file
140
main.py
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
"""
|
||||||
|
This is the PyJail, a jailing tool for running Python apps in a sandboxed environment.
|
||||||
|
Version: 0.2.0-main1
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import runpy
|
||||||
|
|
||||||
|
|
||||||
|
class PyJail:
|
||||||
|
"""
|
||||||
|
The
|
||||||
|
"""
|
||||||
|
def __init__(self, debug=False):
|
||||||
|
self.rootpath = ""
|
||||||
|
self.rootpath = self.fs()
|
||||||
|
self._debug = debug
|
||||||
|
with open(self.fs("/proc/klog"), "w") as f:
|
||||||
|
# Always use jailmgr.msg() from this point onwards.
|
||||||
|
f.write(f"[{time.time}] [jailmgr.__init__()] [INFO] START LOG")
|
||||||
|
f.close()
|
||||||
|
with open(self.fs("/proc/kproc"), "w") as f:
|
||||||
|
f.write("proc: jailmgr(1)")
|
||||||
|
self._program_counter = 2
|
||||||
|
f.close()
|
||||||
|
self._resolve_symlinks = False if os.path.isdir(self.fs("/bin")) else True
|
||||||
|
|
||||||
|
def run_program(self, path_to_bin):
|
||||||
|
"""
|
||||||
|
Runs a specified program.
|
||||||
|
"""
|
||||||
|
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:
|
||||||
|
self.msg("jailmgr.run_program()", "An error has occurred launching the program.", True,
|
||||||
|
"WARNING")
|
||||||
|
else:
|
||||||
|
with open(self.fs("/proc/kproc"), "a+") as f:
|
||||||
|
f.write(f"proc: {path_to_bin}({self._program_counter})")
|
||||||
|
self._program_counter += 1
|
||||||
|
runpy.run_path(path_to_bin)
|
||||||
|
|
||||||
|
def msg(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.
|
||||||
|
Replaces print statements.
|
||||||
|
Args:
|
||||||
|
caller: The program that called the logger
|
||||||
|
message: Is the message to parse.
|
||||||
|
emit: If the message needs to be passed to apps.
|
||||||
|
log_level: The loglevel, either DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||||
|
"""
|
||||||
|
if self._debug is True:
|
||||||
|
emit = True
|
||||||
|
accepted_log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
||||||
|
if log_level.upper() not in accepted_log_levels:
|
||||||
|
self.msg(f"jailmgr.msg()",f"Not accepted loglevel!! {log_level}", False, "ERROR")
|
||||||
|
with open(self.fs("/proc/klog"), "a+") as f:
|
||||||
|
f.write(f"[{time.time}] [{caller}] [{log_level}] {message}")
|
||||||
|
if emit is True:
|
||||||
|
print(message)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def fs(self, check_path=None, resolve_symlinks=True):
|
||||||
|
"""
|
||||||
|
Keeps track of the jailed filesystem and makes sure any calls to any
|
||||||
|
file get done in the jailed filesystem
|
||||||
|
"""
|
||||||
|
if check_path is not None:
|
||||||
|
if os.path.exists(f"{self.rootpath}{check_path}"):
|
||||||
|
if self._resolve_symlinks is True or resolve_symlinks is True:
|
||||||
|
# This exists to ease /bin and other symlinks that are always present.
|
||||||
|
# It allows the system to drastically speed up resolving symlinks.
|
||||||
|
symlinkable_dirs = ["/bin", "/sbin", "/lib", "/lib64"]
|
||||||
|
for directory in symlinkable_dirs:
|
||||||
|
if check_path.startswith(directory):
|
||||||
|
check_path_usr_merge = f"/usr{check_path}"
|
||||||
|
return self.rootpath + check_path_usr_merge
|
||||||
|
# Well, if it doesn't start with any of them, we need to check each and every directory.
|
||||||
|
check_path_split = check_path.split("/", -1)
|
||||||
|
prepend_path = ""
|
||||||
|
for i, path in enumerate(check_path_split):
|
||||||
|
prepend_path = f"{prepend_path}/{path}" if not path.endswith("/") else f"{prepend_path}/{path}/"
|
||||||
|
check_path_split[i] = f"{prepend_path}"
|
||||||
|
check_path = ""
|
||||||
|
for i, path in enumerate(check_path_split):
|
||||||
|
if os.path.isdir(path) and i != (len(check_path_split) - 1):
|
||||||
|
# Directory is not a symlink, we can just ignore and move on.
|
||||||
|
pass
|
||||||
|
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.
|
||||||
|
return path
|
||||||
|
elif not os.path.isdir(path) and i != (len(check_path_split) - 1):
|
||||||
|
# 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.
|
||||||
|
with open(self.fs(path, False)) as f:
|
||||||
|
is_symlink = f.read()
|
||||||
|
f.close()
|
||||||
|
if is_symlink.startswith("symlnk"):
|
||||||
|
# This is a symlink!
|
||||||
|
# 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.
|
||||||
|
# raise NotImplementedError()
|
||||||
|
is_symlink_split = is_symlink.split(" ", 1)
|
||||||
|
symlink_dest = is_symlink_split[1]
|
||||||
|
symlink_dest = f"{symlink_dest}/{path}"
|
||||||
|
return symlink_dest
|
||||||
|
else:
|
||||||
|
# This is either not a symlink or an improperly configured one.
|
||||||
|
self.msg("jailmgr.fs()", "reached non-symlink file not at end of list",
|
||||||
|
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 "
|
||||||
|
"typo or misconfigured symlink. The directory in question: "
|
||||||
|
f"{path}", True, "WARNING")
|
||||||
|
return 2
|
||||||
|
|
||||||
|
return self.rootpath + check_path
|
||||||
|
if check_path.startswith("."):
|
||||||
|
check_path = check_path.lstrip(".")
|
||||||
|
return os.getcwd() + check_path if "vfs" in os.getcwd() else 2
|
||||||
|
elif self.rootpath in check_path:
|
||||||
|
self.msg(f"jailmgr.fs()", "Cannot parse rootpath, expected vfspath", log_level="ERROR")
|
||||||
|
return 3
|
||||||
|
else:
|
||||||
|
# Path is not in the jailed fs, so we say it doesn't exist.
|
||||||
|
self.msg(f"jailmgr.fs()", "File/directory doesn't exist in vfspath", log_level="ERROR")
|
||||||
|
return 2
|
||||||
|
else:
|
||||||
|
rootpath = os.getcwd() + "/vfs"
|
||||||
|
self.msg("jailmgr.fs()", message=rootpath, log_level="INFO")
|
||||||
|
return rootpath
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def kver():
|
||||||
|
"""
|
||||||
|
Returns the jail manager version
|
||||||
|
"""
|
||||||
|
return "0.2.0-main1"
|
7
runner.py
Normal file
7
runner.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
"""
|
||||||
|
Allows the PyNVOS "kernel" to "boot"
|
||||||
|
Version: 1.0.0
|
||||||
|
"""
|
||||||
|
from vfs.sys.jail_mgr import PyJail
|
||||||
|
krnl = PyJail()
|
||||||
|
krnl.run_program("/bin/shell.py")
|
51
sh.py
Normal file
51
sh.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
"""
|
||||||
|
The shell for PyNVOS
|
||||||
|
Version: 0.1.0-main1
|
||||||
|
"""
|
||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
import cmd
|
||||||
|
|
||||||
|
# from ..sys.krnl import Kernel
|
||||||
|
print(__name__)
|
||||||
|
class shell(cmd.Cmd):
|
||||||
|
intro = "Shell started, PyNVOS 0.1.1-main1"
|
||||||
|
prompt = "shell-0.1.0$ "
|
||||||
|
file = None
|
||||||
|
krnl = importlib.import_module(".jail_mgr", "vfs.sys")
|
||||||
|
kernel = krnl.Kernel()
|
||||||
|
print(str(kernel) + " " + str(type(kernel)))
|
||||||
|
|
||||||
|
def do_cd(self, args):
|
||||||
|
"""Changes directory"""
|
||||||
|
args = shell.kernel.fs(args)
|
||||||
|
os.chdir(args)
|
||||||
|
|
||||||
|
def do_exec(self, args):
|
||||||
|
"""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
|
||||||
|
# So for ledit it should be just 'ledit' and not /bin/ledit.py or ./ledit.py
|
||||||
|
bins_in_bin = os.listdir(shell.kernel.fs("/bin"))
|
||||||
|
apps_strip = []
|
||||||
|
for apps in bins_in_bin:
|
||||||
|
if apps.endswith(".py"):
|
||||||
|
apps_strip.append(apps.strip(".py"))
|
||||||
|
if args in apps_strip:
|
||||||
|
shell.kernel.run_program(f"/bin/{args}.py")
|
||||||
|
else:
|
||||||
|
shell.kernel.run_program(args)
|
||||||
|
|
||||||
|
def do_ls(self, none):
|
||||||
|
"""Lists the content of a directory"""
|
||||||
|
os.listdir(os.getcwd())
|
||||||
|
|
||||||
|
def postloop(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '<run_path>':
|
||||||
|
shell().cmdloop()
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print("The shell can't be ran as a standalone program and must be ran in conjunction with the kernel.")
|
||||||
|
input("Press Enter to continue...")
|
||||||
|
exit(-1)
|
1
verinfo.txt
Normal file
1
verinfo.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0.2 build 0036
|
Reference in New Issue
Block a user