Something went wrong. Try again.
A wrapper of `/bin/sh` that limits the available commands.
shell sh zig security
Something went wrong. Try again.
2.4 kB · 65 lines
Zig
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566const std = @import("std");const lib = @import("lib");
pub fn main(init: std.process.Init) !void { const user = init.environ_map.get("USER") orelse @panic("cannot get user"); const alloc = init.arena.allocator();
const cli_args = try lib.parseArgs(init.minimal.args); if (cli_args.command) |cmd| { try lib.runCmd(alloc, init.io, cmd); return; }
var buffer: [1024]u8 = undefined; var stdin = std.Io.File.stdin().reader(init.io, &buffer);
var stderr_buffer: [64]u8 = undefined; var stderr = std.Io.File.stderr().writer(init.io, &stderr_buffer); _ = try stderr.interface.write("$ "); try stderr.flush();
out: while (stdin.interface.takeDelimiterExclusive('\n')) |c| { stdin.interface.toss(1); const cmd = std.mem.trimEnd(u8, c, "\r"); if (std.mem.eql(u8, cmd, "exit")) return; defer { _ = stderr.interface.write("$ ") catch unreachable; stderr.flush() catch unreachable; } var dir = try std.Io.Dir.cwd().openDir(init.io, cli_args.path, .{}); var file = dir.openFile(init.io, user, .{}) catch |err| switch (err) { error.FileNotFound => { try cantExecute(init.io); continue; }, else => return err, }; var buf: [1024]u8 = undefined; var reader = file.reader(init.io, &buf); const cfg = try lib.Config.parseConfig(alloc, &reader.interface); var iter_parts = std.mem.splitScalar(u8, cmd, '|'); while (iter_parts.next()) |part| { var iter = std.mem.splitScalar(u8, part, ' '); var rargs = std.ArrayList([]const u8).empty; while (iter.next()) |it| try rargs.append(alloc, it); const args = try rargs.toOwnedSlice(alloc); defer alloc.free(args); if (!cfg.canExecute(args)) { try cantExecute(init.io); continue :out; } } try lib.runCmd(alloc, init.io, cmd); } else |err| switch (err) { error.EndOfStream => {}, else => return err, }}
fn cantExecute(io: std.Io) !void { var buffer: [256]u8 = undefined; var writer = std.Io.File.stderr().writer(io, &buffer); _ = try writer.interface.write("You can't execute this command, sorry.\n"); try writer.interface.flush();}