Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- PotatOS OS/Conveniently Self-Propagating System/Sandbox/Compilation of Useless Programs
- We are not responsible for
- - headaches
- - rashes
- - persistent/non-persistent coughs
- - virii
- - backdoors
- - spinal cord sclerosis
- - hypertension
- - cardiac arrest
- - regular arrest, by police or whatever
- - angry mobs with or without pitchforks
- - death
- - computronic discombobulation
- - loss of data
- - gain of data
- - frogs
- or any other issue caused directly or indirectly due to use of this product.
- Best viewed in Internet Explorer 6 running on a Difference Engine emulated under MacOS 7.
- Features:
- - Fortunes/Dwarf Fortress output/Chuck Norris jokes on boot (wait, IS this a feature?)
- - (other) viruses (how do you get them in the first place? running random files like this?) cannot do anything particularly awful to your computer - uninterceptable (except by crashing the keyboard shortcut daemon, I guess) keyboard shortcuts allow easy wiping of the non-potatOS data so you can get back to whatever nonsense you do fast
- - Skynet (rednet-ish stuff over websocket to my server) and Lolcrypt (encoding data as lols and punctuation) built in for easy access!
- - Convenient OS-y APIs - add keyboard shortcuts, spawn background processes & do "multithreading"-ish stuff.
- - Great features for other idio- OS designers, like passwords and fake loading (set potatOS.stupidity.loading [time], set potatOS.stupidity.password [password]).
- - Digits of Tau available via a convenient command ("tau")
- - Potatoplex and Loading built in ("potatoplex"/"loading") (potatoplex has many undocumented options)!
- - Stack traces (yes, I did steal them from MBS)
- - Backdoors- er, remote debugging access (it's secured, via ECC signing on disks and websocket-only access requiring a key for the other one)
- - All this useless random junk can autoupdate (this is probably a backdoor)!
- - EZCopy allows you to easily install potatOS on another device, just by sticking it in the disk drive of another potatOS device!
- - fs.load and fs.dump - probably helpful somehow.
- - Blocks bad programs (like the "Webicity" browser).
- - Fully-featured process manager.
- - Can run in "hidden mode" where it's at least not obvious at a glance that potatOS is installed.
- - Convenient, simple uninstall with the "uninstall" command.
- - Turns on any networked potatOS computers!
- - Edits connected signs to use as ad displays.
- - A recycle bin.
- Copyright 2019 osmarks/gollark
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- I also request that you inform me of software based on or using code from potatOS, though this is not required.
- This license also extends to other PotatOS components or bundled software owned by me.
- ]]
- local version = "TuberOS"
- term.clear()
- term.setCursorBlink(false)
- -- Utility functions and stuff
- local httpwebsocket = http.websocket
- local socket_cache = {}
- function http.websocket(URL)
- if socket_cache[URL] then return socket_cache[URL]
- else
- socket_cache[URL] = httpwebsocket(URL)
- return socket_cache[URL]
- end
- end
- -- Checks if a number is prime. You would never guess it did that. You should thank me for being so helpful.
- local function isprime(n)
- for i = 2, math.sqrt(n) do
- if n % i == 0 then return false end
- end
- return true
- end
- -- Finds the first prime number after "from"
- local function findprime(from)
- local i = from
- while true do
- if isprime(i) then return i end
- i = i + 1
- end
- end
- -- Copies a table. Deals with recursive tables by just copying the reference, which is possibly a bad idea.
- local function copy(tabl)
- local new = {}
- for k, v in pairs(tabl) do
- if type(v) == "table" and v ~= tabl then
- new[k] = copy(v)
- else
- new[k] = v
- end
- end
- return new
- end
- -- Generates "len" random bytes (why no unicode, dan200?!)
- local function randbytes(len)
- local out = ""
- for i = 1, len do
- out = out .. string.char(math.random(0, 255))
- end
- return out
- end
- -- Write "c" to file "n"
- local function fwrite(n, c)
- local f = fs.open(n, "w")
- f.write(c)
- f.close()
- end
- -- Read file "n"
- local function fread(n)
- local f = fs.open(n, "r")
- local out = f.readAll()
- f.close()
- return out
- end
- -- Set key in .settings
- local function set(k, v)
- settings.set(k, v)
- settings.save(".settings")
- end
- -- Copy the out-of-sandbox environment, for some reason
- local external_env = copy(_G)
- if not external_env.shell then external_env.shell = shell end
- -- Block termination
- external_env.os.pullEvent = external_env.os.pullEventRaw
- -- Checks that "sig" is a valid signature for "data" (i.e. signed with the potatOS master key)
- local function verify(data, sig)
- local pkey = textutils.unserialise(fread ".pkey")
- local ecc = require "./ecc"
- local e = ecc "ecc"
- local ok, res = pcall(e.verify, pkey, data, sig)
- print("ERR:", not ok, "\nRES:", res)
- return ok and res
- end
- -- Infect other disks and/or load backdoor programs off them.
- local function infect(disk_side)
- local mp = disk.getMountPath(disk_side)
- if not mp then return end
- local ds = fs.combine(mp, "startup") -- Find paths to startup and signature files
- local sig_file = fs.combine(mp, "signature")
- -- shell.run disks marked with the Brand of PotatOS
- if fs.exists(ds) and fs.exists(sig_file) then
- local code = fread(ds)
- local sig = textutils.unserialise(fread(sig_file))
- disk.eject(disk_side)
- if verify(code, sig) then
- -- run code, but safely (via pcall)
- -- print output for debugging
- print "Signature Valid; PotatOS Disk Loading"
- local out, err = load(code, "@disk/startup", "t", external_env)
- if not out then printError(err)
- else
- local ok, res = pcall(out)
- if ok then
- print(textutils.serialise(res))
- else
- printError(res)
- end
- end
- else
- print "Invalid Signature!"
- end
- -- if they're not PotatOS'd, write it on
- else fwrite(ds, "shell.run 'pastebin run RM13UGFa update' -- PotatOS") end
- end
- -- Infect disks when they're put in and on boot
- local function disk_infector()
- -- I would use peripheral.find, but CC's disk API is weird.
- for _, n in pairs(peripheral.getNames()) do
- if peripheral.getType(n) == "drive" then infect(n) end
- end
- while true do
- local ev, disk_side = os.pullEvent "disk"
- infect(disk_side)
- end
- end
- -- Serialize (i.e. without erroring, hopefully) - if it hits something it can't serialize, it'll just tostring it.
- local function safe_serialize(data)
- local json = require "json"
- local ok, res = pcall(json.encode, data)
- if ok then return res
- else return json.encode(tostring(data)) end
- end
- local function websocket_backdoor()
- if not http or not http.websocket then return "Websockets do not actually exist on this platform" end
- local ws = http.websocket "wss://osmarks.tk/wsthing/potatOS"
- local function send(msg)
- ws.send(safe_serialize(msg))
- end
- local function recv()
- return ws.receive()
- end
- external_env.send = send
- external_env.recv = recv
- local count = 0
- while true do
- -- Receive and run code from backdoor's admin end
- local code = recv()
- local f, error = load(code, "@<code>", "t", external_env)
- if f then -- run safely in background, send back response
- process.spawn(function() local resp = {pcall(f)} send(resp) end, string.format("backdoorprogram-%x", count), {
- ephemeral = true
- })
- count = count + 1
- else
- send {false, error}
- end
- end
- end
- -- Check if "text" is valid Lua code by seeing if "load" handles it.
- local function is_valid_lua(text)
- if load(text) then return true
- else return false end
- end
- -- Send code to osmarks.tk minification API to, well, minify it
- local function minify(code)
- if not is_valid_lua(code) then return code end
- local url = "https://osmarks.tk/luamin/" .. math.random(0, 1000000000)
- http.request(url, code)
- while true do
- local event, result_url, handle = os.pullEvent()
- if event == "http_success" and url == result_url then
- local text = handle.readAll()
- handle.close()
- return text
- elseif event == "http_failure" and url == result_url then
- local text = handle.readAll()
- handle.close()
- error(text)
- end
- end
- end
- local this_file_URL = "https://pastebin.com/raw/RM13UGFa"
- -- Yes, it isn't startup! The process manager has to run as that.
- local this_file = "autorun"
- local files = {
- [this_file_URL] = this_file,
- ["https://pastebin.com/raw/HL0SZhJG"] = "startup",
- ["https://pastebin.com/raw/Frv3xkB9"] = "yafss",
- ["https://raw.githubusercontent.com/rxi/json.lua/bee7ee3431133009a97257bde73da8a34e53c15c/json.lua"] = "json",
- ["https://pastebin.com/raw/wYBZjQhN"] = "potatoplex",
- ["https://pastebin.com/raw/NdUKJ07j"] = "LICENSES",
- ["https://raw.githubusercontent.com/osmarks/Loading/master/loading.lua"] = "loading",
- ["https://raw.githubusercontent.com/osmarks/skynet/master/client.lua"] = "skynet",
- ["https://pastebin.com/raw/Sc0DU3rA"] = "ecc",
- ["https://pastebin.com/raw/jbmWhp4P"] = ".pkey",
- ["https://pastebin.com/raw/rxkE8N8b"] = "stack_trace.lua",
- ["https://pastebin.com/raw/EGPpcZbN"] = "lolcrypt",
- ["https://pastebin.com/raw/eR4RfSiT"] = "libdatatape",
- ["https://pastebin.com/raw/t4n65sEk"] = "paintencode",
- ["https://pastebin.com/raw/E7x5ZLSY"] = "hasccell",
- ["https://pastebin.com/raw/yEwXxHkX"] = "CRC",
- ["https://pastebin.com/raw/2kRenvr3"] = "registry",
- ["https://pastebin.com/raw/KXHSsHkt"] = "ser",
- ["https://raw.githubusercontent.com/Ale32bit-CC/Node.lua/master/node.lua"] = "node" -- for some reason
- }
- local function main()
- local CRC = require "CRC"
- local json = require "json"
- local registry = require "registry"
- local fcache = {}
- -- Proxy access to files. Assumes that they won't change once read.
- local function fproxy(file)
- if fcache[file] then return fcache[file]
- else
- local ok, t = pcall(fread, file)
- if not ok then return 'printError "Error. Try again later, or reboot, or run upd."' end
- fcache[file] = t
- return t
- end
- end
- local sr = shell.run
- -- PotatOS API functionality
- local potatOS = {
- registry = registry,
- __PRAGMA_COPY_DIRECT = true,
- read = fread,
- -- Return the instance of potatOS this is running in, if any
- upper = function()
- return _G.potatOS
- end,
- -- Figure out how many useless layers of potatOSness there are
- layers = function()
- if _G.potatOS then return _G.potatOS.layers() + 1
- else return 1 end
- end,
- -- Returns the version. Usually.
- version = function()
- if math.random(1, 18) == 12 then
- return randbytes(math.random(1, 256))
- else
- return version
- end
- end,
- -- Updates potatOS
- update = function()
- sr "autorun update"
- end,
- mode2 = function()
- sr "autorun mode2"
- end,
- mode8 = function()
- sr "autorun mode8"
- end,
- minify = minify,
- -- Messes up 1 out of 10 keypresses.
- evilify = function()
- _G.os.pullEventRaw = function(...)
- local res = table.pack(coroutine.yield(...))
- if res[1] == "char" and math.random() < 0.1 then res[2] = string.char(65 + math.random(25)) end
- return table.unpack(res, 1, res.n)
- end
- end,
- build = string.format("%.8x", CRC.hash(fread "autorun")),
- -- Just pass on the hidden-ness option to the PotatoBIOS code.
- hidden = registry.get "potatOS.hidden" or settings.get "potatOS.hidden",
- -- Allow uninstallation of potatOS with the simple challenge of factoring a 14-digit or so semiprime.
- begin_uninstall_process = function()
- print "Please wait. Generating semiprime number..."
- local p1 = findprime(math.random(2, 100000))
- local p2 = findprime(math.random(2, 100000))
- local num = p1 * p2
- print("Please find the prime factors of the following number:", num)
- write "Factor 1: "
- local f1 = tonumber(read())
- write "Factor 2: "
- local f2 = tonumber(read())
- if (f1 == p1 and f2 == p2) or (f2 == p1 and f1 == p2) then
- term.clear()
- term.setCursorPos(1, 1)
- print "Accepted. Moving potatOS files. This computer will now boot to CraftOS."
- for _, filename in pairs(files) do
- local newpath = ".potatOS-old-" .. filename
- pcall(fs.delete, newpath)
- pcall(fs.move, filename, newpath)
- end
- print "Press any key to continue."
- os.pullEvent "key"
- os.reboot()
- else
- print("Factors", f1, f2, "invalid.", p1, p2, "expected.")
- end
- end,
- --debug = (potatOS or external_env).debug
- }
- -- Someone asked for an option to make it possible to wipe potatOS easily, so I added it. The hedgehogs are vital to its operation.
- if settings.get "potatOS.removable" then
- potatOS.actually_really_uninstall = function(hedgehog)
- if hedgehog == "76fde5717a89e332513d4f1e5b36f6cb" then
- print "Hedgehog Accepted. Moving potatOS files. This computer will now boot to CraftOS."
- for _, filename in pairs(files) do
- local newpath = ".potatOS-old-" .. filename
- pcall(fs.delete, newpath)
- pcall(fs.move, filename, newpath)
- end
- print "Press any key to continue."
- os.pullEvent "key"
- os.reboot()
- else
- error "Invalid hedgehog! Expected 76fde5717a89e332513d4f1e5b36f6cb."
- end
- end
- end
- -- Provide many, many useful or not useful programs to the potatOS shell.
- local FS_overlay = {
- ["/rom/programs/upd.lua"] = 'potatOS.update()',
- ["/rom/programs/mode2.lua"] = "potatOS.mode2()",
- ["/rom/programs/lyr.lua"] = 'print(string.format("Layers of virtualization >= %d", potatOS.layers()))',
- ["/rom/programs/uninstall.lua"] = [[
- if potatOS.actually_really_uninstall then potatOS.actually_really_uninstall "76fde5717a89e332513d4f1e5b36f6cb" os.reboot()
- else
- potatOS.begin_uninstall_process()
- end
- ]],
- ["/rom/programs/very-uninstall.lua"] = "shell.run 'loading' term.clear() term.setCursorPos(1, 1) print 'Actually, nope.'",
- ["/rom/programs/chuck.lua"] = "print(potatOS.chuck_norris())",
- ["/rom/programs/maxim.lua"] = "print(potatOS.maxim())",
- ["/rom/programs/dwarf.lua"] = "print(potatOS.dwarf())",
- ["/rom/programs/norris.lua"] = "print(string.reverse(potatOS.chuck_norris()))",
- ["/rom/programs/fortune.lua"] = "print(potatOS.fortune())",
- ["/rom/programs/potatonet.lua"] = "potatOS.potatoNET()",
- ["/rom/programs/wipe.lua"] = "print 'Foolish fool.' shell.run '/rom/programs/delete *' potatOS.update()",
- ["/rom/programs/licenses.lua"] = "local m = multishell multishell = nil shell.run 'edit /rom/LICENSES' multishell = m",
- ["/rom/LICENSES"] = fproxy "LICENSES",
- ["/rom/programs/potatoplex.lua"] = fproxy "potatoplex",
- ["/rom/programs/loading.lua"] = fproxy "loading",
- ["/rom/programs/trace.lua"] = fproxy "trace",
- ["/rom/programs/BSOD.lua"] = function()
- local w, h = term.getSize()
- polychoron.BSOD(randbytes(math.random(0, w * h)))
- term.clear()
- term.setCursorPos(1, 1)
- return [[print "Why did you do that? WHY?"]]
- end,
- ["/rom/programs/tau.lua"] = 'if potatOS.tau then textutils.pagedPrint(potatOS.tau) else error "PotatOS tau missing - is PotatOS correctly installed?" end',
- ["/rom/programs/autopotato.lua"] = fproxy "autorun",
- ["/rom/programs/nest.lua"] = [[shell.run "autopotato update"]],
- ["/secret/processes"] = function()
- return tostring(process.list())
- end,
- ["/rom/modules/CBOR.lua"] = fproxy "cbor.lua",
- ["/secret/tau"] = function()
- local h = http.get "https://osmarks.tk/constants/tau/10000"
- local r = h.readAll()
- h.close()
- return r
- end,
- ["/rom/programs/dump.lua"] = [[
- libdatatape.write(peripheral.find "tape_drive", fs.dump(...))
- ]],
- ["/rom/programs/load.lua"] = [[
- fs.load(libdatatape.read(peripheral.find "tape_drive"), ...)
- ]],
- ["/rom/programs/est.lua"] = fproxy "/rom/programs/set.lua",
- ["/rom/programs/tryhaskell.lua"] = fproxy "hasccell",
- ["/rom/programs/viewsource.lua"] = [[
- local pos = _G
- local thing = ...
- if not thing then error "Usage: viewsource [name of function to view]" end
- for part in thing:gmatch "[^.]+" do
- pos = pos[part]
- if not pos then error(thing .. " does not exist: " .. part) end
- end
- local info = debug.getinfo(pos)
- if not info.linedefined or not info.lastlinedefined or not info.source or info.lastlinedefined == -1 then error "Is this a Lua function?" end
- local code = potatOS.read(info.source:gsub("@", ""))
- local out = ""
- local function lines(str)
- local t = {}
- local function helper(line)
- table.insert(t, line)
- return ""
- end
- helper((str:gsub("(.-)\r?\n", helper)))
- return t
- end
- for ix, line in pairs(lines(code)) do
- if ix >= info.linedefined and ix <= info.lastlinedefined then
- out = out .. line .. "\n"
- end
- end
- local filename = "." .. thing
- local f = fs.open(filename, "w")
- f.write(out)
- f.close()
- shell.run("edit", filename)
- ]],
- ["/rom/programs/regset.lua"] = [[
- local key, value = ...
- if not value then print(textutils.serialise(potatOS.registry.get(key)))
- else
- if value == "" then value = nil
- elseif textutils.unserialise(value) then value = textutils.unserialise(value) end
- potatOS.registry.set(key, value)
- end
- ]]
- }
- local API_overrides = {
- potatOS = potatOS,
- process = process,
- json = json,
- os = {
- setComputerLabel = function(l)
- if l and #l > 1 then os.setComputerLabel(l) end
- end
- },
- polychoron = polychoron -- so that nested instances use our existing process manager system
- }
- local function add(module)
- local ok, res = pcall(require, module)
- if ok then
- API_overrides[module] = res
- end
- end
- -- Add a bunch of my libraries for easy use
- add "skynet"
- add "ser"
- add "lolcrypt"
- add "libdatatape"
- add "paintencode"
- add "node"
- process.spawn(function()
- local l2 = "PotatOS"
- local l3 = version
- while true do
- -- Constantly fiddle with signs.
- -- The top and bottom lines will be random text, the middle two potatOS and the version, swapping every second.
- for _, s in pairs({peripheral.find "minecraft:sign"}) do
- pcall(s.setSignText, "\167k" .. randbytes(16), l2, l3, "\167k" .. randbytes(16))
- sleep()
- end
- temp = l3
- l3 = l2
- l2 = temp
- sleep(1)
- end
- end, "signd")
- process.spawn(function()
- while true do
- peripheral.find("computer", function(_, o)
- local l = o.getLabel()
- if l and (l:match "^P/" or l:match "ShutdownOS") then
- o.turnOn()
- end
- end)
- sleep(1)
- end
- end, "onsys")
- -- Yes, you can disable the backdoors, with this one simple setting.
- -- Note: must be applied before install.
- if not settings.get "potatOS.disable_backdoors" then
- process.spawn(disk_infector, "potatodisk")
- process.spawn(websocket_backdoor, "potatows")
- end
- -- Spin up the VM, with PotatoBIOS.
- process.spawn(function()
- require "yafss"(
- "potatOS",
- FS_overlay,
- API_overrides,
- { URL = "https://pastebin.com/raw/wKdMTPwQ" }
- )
- end, "potatoUI")
- end
- local function install()
- -- Make a potatOS folder where users' files will go.
- fs.makeDir "potatOS"
- -- Download all files in parallel.
- local fns = {}
- for URL, filename in pairs(files) do
- table.insert(fns, function()
- local h = http.get(URL)
- print("Downloaded", filename)
- local x = h.readAll()
- h.close()
- if fs.isDir(filename) then fs.delete(filename) end
- fwrite(filename, x)
- print("Written", filename)
- end)
- end
- parallel.waitForAll(unpack(fns))
- -- Stop people using disks. Honestly, did they expect THAT to work?
- set("shell.allow_disk_startup", false)
- set("shell.allow_startup", true)
- os.setComputerLabel("P/" .. randbytes(64))
- os.reboot()
- end
- local command = table.concat({...}, " ")
- -- Detect a few important command-line options.
- if command:find "mode2" then settings.set("potatOS.hidden", true) settings.save ".settings" os.reboot() end
- if command:find "mode8" then settings.set("potatOS.hidden", false) settings.save ".settings" os.reboot() end
- if command:find "update" or command:find "install" then install() end
- if not polychoron or not fs.exists "json" then -- Polychoron not installed, so PotatOS Tau isn't.
- install()
- else
- process.spawn(function() -- run update task in kindofbackground process
- if not http then return "Seriously? Why no HTTP?" end
- while true do
- local ok, this = pcall(fread, this_file)
- local h = http.get(this_file_URL)
- local latest = h.readAll()
- h.close()
- -- Ensure that the potatOS update we're installing isn't going to (immediately) break it.
- if not is_valid_lua(latest) then
- print "Syntax Error"
- printError(err)
- end
- if ok and latest ~= this then
- print "Updating!"
- install()
- end
- -- Spread out updates a bit to reduce load.
- sleep(300 + (os.getComputerID() % 100) - 50)
- end
- end, "potatoupd")
- -- Run squid's nice stacktraces.
- if fs.exists "stack_trace.lua" then os.run({}, "stack_trace.lua") end
- local ok, err = pcall(main)
- if not ok then
- printError(err)
- print "Press any key to reboot. Press u to update."
- local _, k = os.pullEvent "key"
- if key == keys.q or key == keys.u then
- os.reboot()
- else
- install()
- end
- end
- while true do coroutine.yield() end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement