Formatting and some completion to install script

This commit is contained in:
2024-12-29 20:34:10 +01:00
parent 77fbcb9b31
commit cf79b945dc
5 changed files with 158 additions and 110 deletions

View File

@@ -22,7 +22,21 @@ 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.
### The 4 branches ## Bundled programs
To keep the installation extremely small in size and footprint, the bundled programs are also
extremely small. Currently we bundle 2 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.
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?
@@ -42,7 +56,7 @@ If you want the bleeding-edge and don't care about stability, then `edge` is for
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/)

View File

@@ -2,10 +2,12 @@
Install script for the Python jailer. Install script for the Python jailer.
Version: 0.3.0-main1 Version: 0.3.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()
with open("./verinfo.txt", "r") as f: with open("./verinfo.txt", "r") as f:
ver = f.read() ver = f.read()
@@ -28,77 +30,43 @@ 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"
setup_posix = input("Do you wish to setup a mostly-POSIX compliant environment? [y/N] ") print("Creating directories...")
if setup_posix.lower() == "y": with open("./bin", "a+") as f:
print("Creating directories...") f.write("symlnk /usr/bin/")
with open("./bin", "a+") as f: f.close()
f.write("symlnk /usr/bin/") with open("./sbin", "a+") as f:
f.close() f.write("symlnk /usr/sbin/")
with open("./sbin", "a+") as f: f.close()
f.write("symlnk /usr/sbin/") with open("./lib", "a+") as f:
f.close() f.write("symlnk /usr/lib/")
with open("./lib", "a+") as f: f.close()
f.write("symlnk /usr/lib/") with open("./lib64", "a+") as f:
f.close() f.write("symlnk /usr/lib64/")
with open("./lib64", "a+") as f: f.close()
f.write("symlnk /usr/lib64/") with open("./usr/bin/sh", "a+") as f:
f.close() f.write("symlnk /usr/bin/shell.py")
with open("./usr/bin/sh", "a+") as f: f.close()
f.write("symlnk /usr/bin/shell.py") os.mkdir("./sys")
f.close() os.mkdir("./usr")
os.mkdir("./sys") os.mkdir("./proc")
os.mkdir("./usr") os.mkdir(f"./home/{usrname}")
os.mkdir("./proc") os.mkdir("./usr/bin/")
os.mkdir(f"./home/{usrname}") os.mkdir("./usr/sbin/")
os.mkdir("./usr/bin/") os.mkdir("./usr/lib/")
os.mkdir("./usr/sbin/") os.mkdir("./usr/lib64/")
os.mkdir("./usr/lib/") print("Copying files...")
os.mkdir("./usr/lib64/") shutil.move("./main.py", "./sys/jail_mgr.py")
print("Copying files...") shutil.move("./sh.py", "./bin/shell.py")
shutil.move("./main.py", "./sys/jail_mgr.py") shutil.move("./ledit.py", "./bin/ledit.py")
shutil.move("./sh.py", "./bin/shell.py") print("Creating system configuration files...")
shutil.move("./ledit.py", "./bin/ledit.py") with open("./sys/usr.conf", "a+") as f:
print("Creating system configuration files...") f.write(usrname)
with open("./sys/usr.conf", "a+") as f: f.close()
f.write(usrname) with open("./sys/procinfo", "a+") as f:
f.close() f.write("proc: vfs(/proc/)\nkernel: vfs(/proc/kcore)")
with open("./sys/procinfo", "a+") as f: f.close()
f.write("proc: vfs(/proc/)\nkernel: vfs(/proc/kcore)") with open("./proc/kcore", "a+") as f:
f.close() f.write("/sys/jail_mgr.py")
with open("./proc/kcore", "a+") as f: f.close()
f.write("/sys/jail_mgr.py")
f.close()
else: # POSIX and NO-POSIX have a firm split now.
print("Creating directories...")
os.mkdir("./bin")
os.mkdir("./sys")
os.mkdir("./usr")
os.mkdir("./proc")
os.mkdir(f"./home/{usrname}")
os.mkdir("./sys/krnl/")
print("Copying files...")
try:
shutil.move("./nps/main.py", "./sys/jail_mgr.py")
shutil.move("./nps/sh.py", "./bin/shell.py")
shutil.move("./nps/ledit.py", "./bin/ledit.py")
except Exception as e:
print("Failure to install! Non-POSIX files are most likely not present! Aborting install...")
shutil.move("../main.py", "../runner.py")
shutil.move("./main.py", "../main.py")
shutil.move("./sh.py", "../sh.py")
shutil.move("./ledit.py", "../ledit.py")
os.rmdir("./bin")
os.rmdir("./sys/krnl/")
os.rmdir("./sys")
os.rmdir("./usr")
os.rmdir("./proc")
os.rmdir(f"./home/{usrname}")
os.chdir("../")
shutil.rmtree("./vfs/")
exit(-1)
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!") print("Install completed! Run ./main.py to start the kernel!")
input("Press <Enter> to exit! ") input("Press <Enter> to exit! ")

View File

@@ -3,9 +3,12 @@ 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)
@@ -14,4 +17,7 @@ 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")

90
main.py
View File

@@ -2,6 +2,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: edge0005-base0.2.1 Version: edge0005-base0.2.1
""" """
import os import os
import time import time
import runpy import runpy
@@ -11,6 +12,7 @@ class PyJail:
""" """
The jail manager, handles all system calls and such. The jail manager, handles all system calls and such.
""" """
def __init__(self, debug=False): def __init__(self, debug=False):
self.rootpath = "" self.rootpath = ""
self.rootpath = self.fs() self.rootpath = self.fs()
@@ -31,15 +33,21 @@ class PyJail:
""" """
path_to_bin = self.fs(path_to_bin) path_to_bin = self.fs(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("jailmgr.run_program()", "An error has occurred launching the program.", True, self.msg(
"WARNING") "jailmgr.run_program()",
"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(self, caller: str, message: str, emit: bool = False, log_level: str = "INFO"): 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. The custom message parser, can parse messages and alert apps of said messages.
Replaces print statements. Replaces print statements.
@@ -53,7 +61,9 @@ class PyJail:
emit = 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(f"jailmgr.msg()",f"Not accepted loglevel!! {log_level}", False, "ERROR") self.msg(
"jailmgr.msg()", f"Not accepted loglevel!! {log_level}", False, "ERROR"
)
return 1 return 1
msg = f"[{time.time}] [{caller}] [{log_level}] {message}" 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:
@@ -83,7 +93,11 @@ 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 = f"{prepend_path}/{path}" if not path.endswith("/") else f"{prepend_path}/{path}/" prepend_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):
@@ -93,7 +107,9 @@ 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 != (len(check_path_split) - 1): 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. # 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:
@@ -109,12 +125,21 @@ class PyJail:
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("jailmgr.fs()", "reached non-symlink file not at end of list", self.msg(
False, "ERROR") "jailmgr.fs()",
self.msg("jailmgr.fs()", "What was assumed to be a directory isn't a" "reached non-symlink file not at end of list",
" directory nor a symlink! This might be because of a " False,
"typo or misconfigured symlink. The directory in question: " "ERROR",
f"{path}", True, "WARNING") )
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 2
return self.rootpath + check_path return self.rootpath + check_path
@@ -122,11 +147,19 @@ 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(f"jailmgr.fs()", "Cannot parse rootpath, expected vfspath", log_level="ERROR") self.msg(
"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(f"jailmgr.fs()", "File/directory doesn't exist in vfspath", log_level="ERROR") self.msg(
"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"
@@ -137,7 +170,7 @@ class PyJail:
""" """
Returns the kernel version Returns the kernel version
""" """
return "edge0005-base0.2.1" return "edge0006-base0.2.1"
def netsock(self, ip, port, mode, msg): def netsock(self, ip, port, mode, msg):
""" """
@@ -160,21 +193,30 @@ class PyJail:
if mode == "TCP": if mode == "TCP":
try: try:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except Exception as e: except Exception:
self.msg("jailmgr.netsock()", "Socket import failed!", False, "CRITICAL") self.msg(
self.msg("jailmgr.netsock()", "An unexpected error occurred!", True, "ERROR") "jailmgr.netsock()", "Socket import failed!", False, "CRITICAL"
)
self.msg(
"jailmgr.netsock()", "An unexpected error occurred!", True, "ERROR"
)
return None return None
# Connect to the server # Connect to the server
client_socket.connect((ip, port)) client_socket.connect((ip, port))
self.msg("jailmgr.netsock()", f"Connected to server at {server_ip}:{server_port}", False, "INFO") self.msg(
"jailmgr.netsock()",
f"Connected to server at {ip}:{port}",
False,
"INFO",
)
# Send the message to the server # Send the message to the server
client_socket.send(message.encode()) client_socket.send(msg.encode())
# Receive the response from the server # Receive the response from the server
response = client_socket.recv(1024).decode() response = client_socket.recv(1024).decode()
client_socket.close() # Close the connection client_socket.close() # Close the connection
self.msg("jailmgr.netsock", f"Received from server: {response}", False "INFO") self.msg("jailmgr.netsock", f"Received from server: {response}")
return response return response
@@ -182,15 +224,15 @@ class PyJail:
# raise NotImplementedError("TODO: PKG will be implemented later!") # raise NotImplementedError("TODO: PKG will be implemented later!")
file_io = requests.get(ip) file_io = requests.get(ip)
if file_io.startswith("PYPAK PMD"): if file_io.startswith("PYPAK PMD"):
with open(self.fs(f"/usr/netsock/cache/{pkg}.pmd"), "a+") as f: with open(self.fs(f"/usr/netsock/cache/{msg}.pmd"), "a+") as f:
f.write(file_io) f.write(file_io)
f.close() f.close()
else: else:
with open(self.fs(f"/usr/netsock/cache/{pkg}.py")) with open(self.fs(f"/usr/netsock/cache/{msg}.py"), "a+") as f:
f.write(file_io) f.write(file_io)
f.close() f.close()
else: else:
raise NotImplementedError("TODO: UDP will be implemented later!") raise NotImplementedError("TODO: UDP will be implemented later!")
# raise NotImplementedError("TODO: Netsock will be implemented once 0.3.0 comes around!") # raise NotImplementedError("TODO: Netsock will be implemented once 0.3.0 comes around!")

40
sh.py
View File

@@ -1,14 +1,14 @@
""" """
The shell for PyNVOS The shell for PyNVOS
Version: 0.2.0.0401 Version: 0.2.0.0402
""" """
import importlib import importlib
import os import os
import cmd import cmd
import shutil 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") jail_mgr = importlib.import_module(".jail_mgr", "vfs.sys")
jailmgr = jail_mgr.PyJail() jailmgr = jail_mgr.PyJail()
@@ -42,9 +42,17 @@ class shell(cmd.Cmd):
def do_pkg(self, pkg): def do_pkg(self, pkg):
"""Downloads packages over the internet.""" """Downloads packages over the internet."""
self.jailmgr.netsock(f"https://pkg.novacow.ch/repo/{kver}/meta/{pkg}.pmd", None, "PKG", f"{pkg}") self.jailmgr.netsock(
shutil.copy(self.jailmgr.fs(f"/usr/netsock/cache/{pkg}.pmd"), self.jailmgr.fs(f"/usr/pkg/metacache/")) f"https://pkg.novacow.ch/repo/{self.kver}/meta/{pkg}.pmd",
with open(self.jailmgr.fs(f"/usr/pkgs/metacache/{pkg}.pmd"), "r") as f: 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() package_meta = f.read()
f.close() f.close()
self.jailmgr.msg("shell.do_pkg", package_meta, True, "INFO") self.jailmgr.msg("shell.do_pkg", package_meta, True, "INFO")
@@ -52,16 +60,26 @@ class shell(cmd.Cmd):
if y_n_confirmation.lower() != "y": if y_n_confirmation.lower() != "y":
print("Aborted.") print("Aborted.")
return return
self.jailmgr.netsock(f"https://pkg.novacow.ch/repo/{kver}/main/static/binary/{pkg}.py", None, "PKG", f"{pkg}") self.jailmgr.netsock(
shutil.copy(self.jailmgr.fs(f"/usr/netsock/cache/{pkg}.py"), self.jailmgr.fs(f"/usr/bin/")) 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("The shell can't be ran as a standalone program and must be ran in conjunction with the jail manager.") print(
"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)