diff --git a/permissions/sockets.json b/permissions/sockets.json deleted file mode 100644 index 7b1a795..0000000 --- a/permissions/sockets.json +++ /dev/null @@ -1,161 +0,0 @@ -{ - "alsa": [ - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/usr/share/alsa", - "dest": "/usr/share/alsa" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/etc/alsa", - "dest": "/etc/alsa" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/etc/group", - "dest": "/etc/group" - }, - { - "flag": "--dev-bind", - "resolve_symlink": true, - "src": "/dev/snd", - "dest": "/dev/snd" - } - ], - "cgroup": [], - "dbus": [ - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "$XDG_RUNTIME_DIR/bus", - "dest": "/run/user/$UID/bus" - } - ], - "ipc": [], - "network": [ - { - "flag": "--share-net" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/etc/ca-certificates", - "dest": "/etc/ca-certificates" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/etc/resolv.conf", - "dest": "/etc/resolv.conf" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/etc/ssl", - "dest": "/etc/ssl" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/etc/pki", - "dest": "/etc/pki" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/usr/share/ca-certificates", - "dest": "/usr/share/ca-certificates" - } - ], - "pid": [], - "pipewire": [ - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "$XDG_RUNTIME_DIR/pipewire-0", - "dest": "/run/user/$UID/pipewire-0" - } - ], - "pulseaudio": [ - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "$XDG_RUNTIME_DIR/pulse", - "dest": "/run/user/$UID/pulse" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/etc/pulse", - "dest": "/etc/pulse" - } - ], - "session": [], - "user": [], - "uts": [], - "wayland": [ - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY", - "dest": "/run/user/$UID/wayland-0" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/usr/share/X11", - "dest": "/usr/share/X11" - }, - { - "flag": "--setenv", - "src": "WAYLAND_DISPLAY", - "dest": "wayland-0" - }, - { - "flag": "--setenv", - "src": "_JAVA_AWT_WM_NONPARENTING", - "dest": "1" - }, - { - "flag": "--setenv", - "src": "MOZ_ENABLE_WAYLAND", - "dest": "1" - }, - { - "flag": "--setenv", - "src": "XDG_SESSION_TYPE", - "dest": "wayland" - } - ], - "x11": [ - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "$XAUTHORITY", - "dest": "$HOME/.Xauthority" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - - "_COMMENT_": "TODO: represent display correctly", - "src": "$TMPDIR/.X11-unix/X$DISPLAY", - - "dest": "/usr/share/X11" - }, - { - "flag": "--ro-bind-try", - "resolve_symlink": true, - "src": "/usr/share/X11", - "dest": "/usr/share/X11" - }, - { - "flag": "--setenv", - "src": "XAUTHORITY", - "dest": "$HOME/.Xauthority" - } - ] -} diff --git a/zig/build.zig.zon b/zig/build.zig.zon index b342ad1..fbc1d84 100644 --- a/zig/build.zig.zon +++ b/zig/build.zig.zon @@ -1,6 +1,6 @@ .{ .name = "aisap", - .version = "0.10.11-alpha", + .version = "0.10.1-alpha", .paths = [][]const u8 {""}, .dependencies = .{ .squashfuse = .{ @@ -12,8 +12,8 @@ .hash = "12205592f7dc4b4c7256abd657a50bd9784459a0e9b8bfe8b0d1bbcc153a6d0f650a", }, .known_folders = .{ - .url = "https://github.com/ziglibs/known-folders/archive/0ad514dcfb7525e32ae349b9acc0a53976f3a9fa.tar.gz", - .hash = "12209cde192558f8b3dc098ac2330fc2a14fdd211c5433afd33085af75caa9183147", + .url = "https://github.com/ziglibs/known-folders/archive/cdcc6137ed2e92096b27d394db917d1861f156b3.tar.gz", + .hash = "1220863f0fc3e97cfd47a8edb28c7a3d109c42143235042fb513207b5c5a032fb93f", }, }, } diff --git a/zig/examples/build.zig b/zig/examples/build.zig index 2b3cd81..9c88b19 100644 --- a/zig/examples/build.zig +++ b/zig/examples/build.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const aisap = @import("aisap/zig/build.zig"); +//const aisap = @import("aisap/zig/build.zig"); pub fn build(b: *std.Build) void { // Standard target options allows the person running `zig build` to choose diff --git a/zig/examples/src/main.zig b/zig/examples/src/main.zig index 60bdece..3cdad1b 100644 --- a/zig/examples/src/main.zig +++ b/zig/examples/src/main.zig @@ -62,7 +62,7 @@ pub fn main() !void { var md5_buf: [33]u8 = undefined; - const permissions = try ai.permissions( + var permissions = try ai.permissions( allocator, ) orelse { std.debug.print("no permissions found\n", .{}); @@ -85,6 +85,9 @@ pub fn main() !void { std.debug.print("[]\n", .{}); } + permissions.level = 3; + try AppImage.SocketPermissions.initDatabase(allocator); + std.debug.print("{s}\n", .{ai.name}); std.debug.print("desktop: {s}\n", .{ai.desktop_entry}); std.debug.print("type: {}\n", .{ai.kind}); @@ -93,12 +96,14 @@ pub fn main() !void { try ai.md5(&md5_buf), }); - try ai.mount(.{}); + try ai.mount(.{ + .foreground = false, + }); - const wrapArgs = try ai.wrapArgs(allocator); - printWrapArgs(wrapArgs); + //const wrapArgs = try ai.wrapArgs(allocator, permissions); + //printWrapArgs(wrapArgs); - try ai.sandbox(.{ + try ai.sandbox(permissions, .{ //.args = &[_][]const u8{"build"}, }); } diff --git a/zig/lib/appimage.zig b/zig/lib/appimage.zig index afa1b16..da4aae1 100644 --- a/zig/lib/appimage.zig +++ b/zig/lib/appimage.zig @@ -381,7 +381,6 @@ pub const AppImage = struct { pub const SocketPermissions = enum { alsa, - audio, cgroup, dbus, ipc, @@ -395,6 +394,30 @@ pub const AppImage = struct { wayland, x11, + const JsonSocket = struct { + name: []const u8, + flags: ?[]const []const u8 = null, + }; + + // Parses the built-in JSON database into a HashMap + // TODO: do this comptime + pub fn initDatabase(allocator: std.mem.Allocator) !void { + const sockets_json = @embedFile("../sockets.json"); + + const parsed = try std.json.parseFromSlice( + []JsonSocket, + allocator, + sockets_json, + .{}, + ); + defer parsed.deinit(); + + for (parsed.value) |val| { + std.debug.print("name: {s}\n", .{val.name}); + std.debug.print("flags: {?s}\n", .{val.flags}); + } + } + pub fn fromString(sock: []const u8) !SocketPermissions { return std.meta.stringToEnum( SocketPermissions, @@ -419,6 +442,14 @@ pub const AppImage = struct { ); } + // pub fn toBwrapArgs(allocator: std.mem.Allocator, opts: SocketOptions,) ![]const []const u8 { + // _ = opts; + // + // var list = std.ArrayList([]const u8).init(allocator); + // + // + // } + /// Generates bwrap args from socket. Memory is cleared on each call /// to the method pub fn toBwrapArgs( @@ -440,37 +471,6 @@ pub const AppImage = struct { "--ro-bind-try", "/etc/group", "/etc/group", "--dev-bind", "/dev/snd", "/dev/snd", }, - .audio => blk: { - const runtime_pulse_dir = try std.fmt.allocPrint( - allocator, - "{s}/pulse", - .{opts.runtime_dir}, - ); - defer allocator.free(runtime_pulse_dir); - - const dest_pulse_dir = try std.fmt.allocPrint( - allocator, - "/run/user/{d}/pulse", - .{opts.uid}, - ); - defer allocator.free(dest_pulse_dir); - - var list = std.ArrayList([]const u8).init(allocator); - - try list.appendSlice( - &[_][]const u8{ - "--ro-bind-try", runtime_pulse_dir, dest_pulse_dir, - "--ro-bind-try", "/usr/share/alsa", "/usr/share/alsa", - "--ro-bind-try", "/usr/share/pulseaudio", "/usr/share/pulseaudio", - "--ro-bind-try", "/etc/alsa", "/etc/alsa", - "--ro-bind-try", "/etc/group", "/etc/group", - "--ro-bind-try", "/etc/pulse", "/etc/pulse", - "--dev-bind", "/dev/snd", "/dev/snd", - }, - ); - - break :blk try list.toOwnedSlice(); - }, .cgroup => &[_][]const u8{}, .dbus => blk: { const runtime_bus_dir = try appendDir( @@ -689,17 +689,16 @@ pub const AppImage = struct { // TODO: finish implementing in Zig // TODO: free allocated memory. Currently, this should just be allocated using an arena - pub fn wrapArgs(ai: *AppImage, allocator: std.mem.Allocator) ![]const []const u8 { + pub fn wrapArgs( + ai: *AppImage, + allocator: std.mem.Allocator, + perms: Permissions, + ) ![]const []const u8 { if (ai.mount_dir == null) { return WrapArgsError.BundleNotMounted; } - var perms = try ai.permissions(allocator) orelse { - return WrapArgsError.NoPermissions; - }; - defer perms.deinit(); - - //if (perms.level == 0) return WrapArgsError.SandboxLevelTooLow; + if (perms.level == 0) return WrapArgsError.SandboxLevelTooLow; const home = try known_folders.getPath(allocator, .home) orelse { return WrapArgsError.HomeNotFound; @@ -708,361 +707,359 @@ pub const AppImage = struct { var list = std.ArrayList([]const u8).init(allocator); try list.append("bwrap"); - if (perms.level > 0) { - var md5_buf: [33]u8 = undefined; - const ai_md5 = try ai.md5(&md5_buf); + var md5_buf: [33]u8 = undefined; + const ai_md5 = try ai.md5(&md5_buf); + + // TODO: fallback if `LOGNAME` not present + const logname = std.posix.getenv("LOGNAME") orelse ""; + const user = try std.process.getUserInfo(logname); + + // Bwrap args for AppImages regardless of level + try list.appendSlice(&[_][]const u8{ + "--setenv", "TMPDIR", "/tmp", + "--setenv", "HOME", home, + "--setenv", "ARGV0", fs.path.basename(ai.path), + + // If these directories are symlinks, they will be resolved, + // otherwise + "--ro-bind-try", try resolve(allocator, "/opt"), "/opt", + "--ro-bind-try", try resolve(allocator, "/bin"), "/bin", + "--ro-bind-try", try resolve(allocator, "/sbin"), "/sbin", + "--ro-bind-try", try resolve(allocator, "/lib"), "/lib", + "--ro-bind-try", try resolve(allocator, "/lib32"), "/lib32", + "--ro-bind-try", try resolve(allocator, "/lib64"), "/lib64", + "--ro-bind-try", try resolve(allocator, "/usr/bin"), "/usr/bin", + "--ro-bind-try", try resolve(allocator, "/usr/sbin"), "/usr/sbin", + "--ro-bind-try", try resolve(allocator, "/usr/lib"), "/usr/lib", + "--ro-bind-try", try resolve(allocator, "/usr/lib32"), "/usr/lib32", + "--ro-bind-try", try resolve(allocator, "/usr/lib64"), "/usr/lib64", + + "--setenv", "APPDIR", + try std.fmt.allocPrint( + allocator, + "/tmp/.mount_{s}", + .{ai_md5}, + ), - // TODO: fallback if `LOGNAME` not present - const logname = std.posix.getenv("LOGNAME") orelse ""; - const user = try std.process.getUserInfo(logname); + "--setenv", "APPIMAGE", + try std.fmt.allocPrint( + allocator, + "/app/{s}", + .{fs.path.basename(ai.path)}, + ), - // Bwrap args for AppImages regardless of level - try list.appendSlice(&[_][]const u8{ - "--setenv", "TMPDIR", "/tmp", - "--setenv", "HOME", home, - "--setenv", "ARGV0", fs.path.basename(ai.path), - - // If these directories are symlinks, they will be resolved, - // otherwise - "--ro-bind-try", try resolve(allocator, "/opt"), "/opt", - "--ro-bind-try", try resolve(allocator, "/bin"), "/bin", - "--ro-bind-try", try resolve(allocator, "/sbin"), "/sbin", - "--ro-bind-try", try resolve(allocator, "/lib"), "/lib", - "--ro-bind-try", try resolve(allocator, "/lib32"), "/lib32", - "--ro-bind-try", try resolve(allocator, "/lib64"), "/lib64", - "--ro-bind-try", try resolve(allocator, "/usr/bin"), "/usr/bin", - "--ro-bind-try", try resolve(allocator, "/usr/sbin"), "/usr/sbin", - "--ro-bind-try", try resolve(allocator, "/usr/lib"), "/usr/lib", - "--ro-bind-try", try resolve(allocator, "/usr/lib32"), "/usr/lib32", - "--ro-bind-try", try resolve(allocator, "/usr/lib64"), "/usr/lib64", - - "--setenv", "APPDIR", + // Set generic paths for all XDG standard dirs + "--setenv", "XDG_DESKTOP_DIR", + try std.fmt.allocPrint( + allocator, + "{s}/Desktop", + .{home}, + ), + "--setenv", "XDG_DOWNLOAD_DIR", + try std.fmt.allocPrint( + allocator, + "{s}/Downloads", + .{home}, + ), + "--setenv", "XDG_DOCUMENTS_DIR", + try std.fmt.allocPrint( + allocator, + "{s}/Documents", + .{home}, + ), + "--setenv", "XDG_MUSIC_DIR", + try std.fmt.allocPrint( + allocator, + "{s}/Music", + .{home}, + ), + "--setenv", "XDG_PICTURES_DIR", + try std.fmt.allocPrint( + allocator, + "{s}/Pictures", + .{home}, + ), + "--setenv", "XDG_VIDEOS_DIR", + try std.fmt.allocPrint( + allocator, + "{s}/Videos", + .{home}, + ), + "--setenv", "XDG_TEMPLATES_DIR", + try std.fmt.allocPrint( + allocator, + "{s}/Templates", + .{home}, + ), + "--setenv", "XDG_PUBLICSHARE_DIR", + try std.fmt.allocPrint( + allocator, + "{s}/Share", + .{home}, + ), + "--setenv", "XDG_DATA_HOME", + try std.fmt.allocPrint( + allocator, + "{s}/.local/share", + .{home}, + ), + "--setenv", "XDG_CONFIG_HOME", + try std.fmt.allocPrint( + allocator, + "{s}/.config", + .{home}, + ), + "--setenv", "XDG_CACHE_HOME", + try std.fmt.allocPrint( + allocator, + "{s}/.cache", + .{home}, + ), + "--setenv", "XDG_STATE_HOME", + try std.fmt.allocPrint( + allocator, + "{s}/.local/state", + .{home}, + ), + "--setenv", "XDG_RUNTIME_DIR", + try std.fmt.allocPrint( + allocator, + "/run/user/{d}", + .{user.uid}, + ), + "--perms", "0700", // + "--dir", + try std.fmt.allocPrint( + allocator, + "/run/user/{d}", + .{user.uid}, + ), + "--dev", "/dev", + "--proc", "/proc", + "--dir", "/app", + + "--bind", ai.path, + try std.fmt.allocPrint( + allocator, + "/app/{s}", + .{fs.path.basename(ai.path)}, + ), + + // TODO: fallback if no cache + "--bind-try", + try std.fmt.allocPrint( + allocator, + "{s}/appimage/{s}", + .{ + (try known_folders.getPath(allocator, .cache)).?, + ai_md5, + }, + ), + try std.fmt.allocPrint( + allocator, + "{s}/.cache", + .{home}, + ), + + "--die-with-parent", + }); + + const config = (try known_folders.getPath(allocator, .local_configuration)).?; + + // Per-level arguments + try list.appendSlice(switch (perms.level) { + 0 => unreachable, + 1 => &[_][]const u8{ + "--dev-bind", "/dev", "/dev", + "--ro-bind", "/sys", "/sys", + "--ro-bind-try", "/usr", "/usr", + "--ro-bind-try", "/etc", "/etc", + "--ro-bind-try", "/run/systemd", "/run/systemd", + // TODO: do this a better way + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "/tmp/.mount_{s}", - .{ai_md5}, + "{s}/.fonts", + .{home}, ), - - "--setenv", "APPIMAGE", try std.fmt.allocPrint( allocator, - "/app/{s}", - .{fs.path.basename(ai.path)}, + "{s}/.fonts", + .{home}, ), - - // Set generic paths for all XDG standard dirs - "--setenv", "XDG_DESKTOP_DIR", + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "{s}/Desktop", - .{home}, + "{s}/fontconfig", + .{config}, ), - "--setenv", "XDG_DOWNLOAD_DIR", try std.fmt.allocPrint( allocator, - "{s}/Downloads", - .{home}, + "{s}/fontconfig", + .{config}, ), - "--setenv", "XDG_DOCUMENTS_DIR", + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "{s}/Documents", - .{home}, + "{s}/gtk-3.0", + .{config}, ), - "--setenv", "XDG_MUSIC_DIR", try std.fmt.allocPrint( allocator, - "{s}/Music", - .{home}, + "{s}/gtk-3.0", + .{config}, ), - "--setenv", "XDG_PICTURES_DIR", + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "{s}/Pictures", - .{home}, + "{s}/kdeglobals", + .{config}, ), - "--setenv", "XDG_VIDEOS_DIR", try std.fmt.allocPrint( allocator, - "{s}/Videos", - .{home}, + "{s}/kdeglobals", + .{config}, ), - "--setenv", "XDG_TEMPLATES_DIR", + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "{s}/Templates", - .{home}, + "{s}/lxde/lxde.conf", + .{config}, ), - "--setenv", "XDG_PUBLICSHARE_DIR", try std.fmt.allocPrint( allocator, - "{s}/Share", - .{home}, + "{s}/lxde/lxde.conf", + .{config}, ), - "--setenv", "XDG_DATA_HOME", + }, + 2 => &[_][]const u8{ + "--ro-bind-try", "/etc/fonts", "/etc/fonts", + "--ro-bind-try", "/etc/ld.so.cache", "/etc/ld.so.cache", + "--ro-bind-try", "/etc/mime.types", "/etc/mime.types", + "--ro-bind-try", "/usr/share/fontconfig", "/usr/share/fontconfig", + "--ro-bind-try", "/usr/share/fonts", "/usr/share/fonts", + "--ro-bind-try", "/usr/share/icons", "/usr/share/icons", + "--ro-bind-try", "/usr/share/applications", "/usr/share/applications", + "--ro-bind-try", "/usr/share/mime", "/usr/share/mime", + "--ro-bind-try", "/usr/share/libdrm", "/usr/share/libdrm", + "--ro-bind-try", "/usr/share/glvnd", "/usr/share/glvnd", + "--ro-bind-try", "/usr/share/glib-2.0", "/usr/share/glib-2.0", + "--ro-bind-try", "/usr/share/terminfo", "/usr/share/terminfo", + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "{s}/.local/share", + "{s}/.fonts", .{home}, ), - "--setenv", "XDG_CONFIG_HOME", try std.fmt.allocPrint( allocator, - "{s}/.config", + "{s}/.fonts", .{home}, ), - "--setenv", "XDG_CACHE_HOME", + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "{s}/.cache", - .{home}, + "{s}/fontconfig", + .{config}, ), - "--setenv", "XDG_STATE_HOME", try std.fmt.allocPrint( allocator, - "{s}/.local/state", - .{home}, + "{s}/fontconfig", + .{config}, ), - "--setenv", "XDG_RUNTIME_DIR", + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "/run/user/{d}", - .{user.uid}, + "{s}/gtk-3.0", + .{config}, ), - "--perms", "0700", // - "--dir", try std.fmt.allocPrint( allocator, - "/run/user/{d}", - .{user.uid}, + "{s}/gtk-3.0", + .{config}, ), - "--dev", "/dev", - "--proc", "/proc", - "--dir", "/app", - - "--bind", ai.path, + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "/app/{s}", - .{fs.path.basename(ai.path)}, + "{s}/kdeglobals", + .{config}, ), - - // TODO: fallback if no cache - "--bind-try", try std.fmt.allocPrint( allocator, - "{s}/appimage/{s}", - .{ - (try known_folders.getPath(allocator, .cache)).?, - ai_md5, - }, + "{s}/kdeglobals", + .{config}, ), + "--ro-bind-try", try std.fmt.allocPrint( allocator, - "{s}/.cache", - .{home}, + "{s}/lxde/lxde.conf", + .{config}, ), + try std.fmt.allocPrint( + allocator, + "{s}/lxde/lxde.conf", + .{config}, + ), + }, + 3 => &[_][]const u8{}, + }); - "--die-with-parent", - }); - - const config = (try known_folders.getPath(allocator, .local_configuration)).?; - - // Per-level arguments - try list.appendSlice(switch (perms.level) { - 0 => unreachable, - 1 => &[_][]const u8{ - "--dev-bind", "/dev", "/dev", - "--ro-bind", "/sys", "/sys", - "--ro-bind-try", "/usr", "/usr", - "--ro-bind-try", "/etc", "/etc", - "--ro-bind-try", "/run/systemd", "/run/systemd", - // TODO: do this a better way - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/.fonts", - .{home}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/.fonts", - .{home}, - ), - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/fontconfig", - .{config}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/fontconfig", - .{config}, - ), - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/gtk-3.0", - .{config}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/gtk-3.0", - .{config}, - ), - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/kdeglobals", - .{config}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/kdeglobals", - .{config}, - ), - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/lxde/lxde.conf", - .{config}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/lxde/lxde.conf", - .{config}, - ), - }, - 2 => &[_][]const u8{ - "--ro-bind-try", "/etc/fonts", "/etc/fonts", - "--ro-bind-try", "/etc/ld.so.cache", "/etc/ld.so.cache", - "--ro-bind-try", "/etc/mime.types", "/etc/mime.types", - "--ro-bind-try", "/usr/share/fontconfig", "/usr/share/fontconfig", - "--ro-bind-try", "/usr/share/fonts", "/usr/share/fonts", - "--ro-bind-try", "/usr/share/icons", "/usr/share/icons", - "--ro-bind-try", "/usr/share/applications", "/usr/share/applications", - "--ro-bind-try", "/usr/share/mime", "/usr/share/mime", - "--ro-bind-try", "/usr/share/libdrm", "/usr/share/libdrm", - "--ro-bind-try", "/usr/share/glvnd", "/usr/share/glvnd", - "--ro-bind-try", "/usr/share/glib-2.0", "/usr/share/glib-2.0", - "--ro-bind-try", "/usr/share/terminfo", "/usr/share/terminfo", - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/.fonts", - .{home}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/.fonts", - .{home}, - ), - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/fontconfig", - .{config}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/fontconfig", - .{config}, - ), - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/gtk-3.0", - .{config}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/gtk-3.0", - .{config}, - ), - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/kdeglobals", - .{config}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/kdeglobals", - .{config}, - ), - "--ro-bind-try", - try std.fmt.allocPrint( - allocator, - "{s}/lxde/lxde.conf", - .{config}, - ), - try std.fmt.allocPrint( - allocator, - "{s}/lxde/lxde.conf", - .{config}, - ), - }, - 3 => &[_][]const u8{}, + if (perms.data_dir) { + // try list.appendSlice( + // "--bind", + // ai. + // ); + } else { + try list.appendSlice(&[_][]const u8{ + "--tmpfs", + home, }); + } - if (perms.data_dir) { - // try list.appendSlice( - // "--bind", - // ai. - // ); - } else { - try list.appendSlice(&[_][]const u8{ - "--tmpfs", - home, - }); - } - - if (perms.filesystem) |files| { - for (files) |*file| { - try list.appendSlice( - try file.toBwrapArgs(allocator), - ); - } - } - - if (perms.sockets) |sockets| { - for (sockets) |socket| { - const socket_slice = try socket.toBwrapArgs(allocator, .{ - // TODO: DO NOT HARD CODE - .runtime_dir = "/run/user/1000", - .uid = 1000, - }); - defer allocator.free(socket_slice); - - try list.appendSlice(socket_slice); - } + if (perms.filesystem) |files| { + for (files) |*file| { + try list.appendSlice( + try file.toBwrapArgs(allocator), + ); } + } - if (ai.mount_dir) |mount_dir| { - try list.appendSlice(&[_][]const u8{ - "--bind", - mount_dir, - try std.fmt.allocPrint( - allocator, - "/tmp/.mount_{s}", - .{ - ai_md5, - }, - ), + if (perms.sockets) |sockets| { + for (sockets) |socket| { + const socket_slice = try socket.toBwrapArgs(allocator, .{ + // TODO: DO NOT HARD CODE + .runtime_dir = "/run/user/1000", + .uid = 1000, }); + defer allocator.free(socket_slice); + + try list.appendSlice(socket_slice); } + } + if (ai.mount_dir) |mount_dir| { try list.appendSlice(&[_][]const u8{ - "--", + "--bind", + mount_dir, try std.fmt.allocPrint( allocator, - "/tmp/.mount_{s}/AppRun", - .{ai_md5}, + "/tmp/.mount_{s}", + .{ + ai_md5, + }, ), }); } + try list.appendSlice(&[_][]const u8{ + "--", + try std.fmt.allocPrint( + allocator, + "/tmp/.mount_{s}/AppRun", + .{ai_md5}, + ), + }); + return list.toOwnedSlice(); } @@ -1136,43 +1133,32 @@ pub const AppImage = struct { const off = try ai.offset(); if (opts.foreground) { - try fuse_helper.mountImage(ai.path, ai.mount_dir.?, off); + @panic("not yet implemented"); + //try fuse_helper.mountImage(ai.path, ai.mount_dir.?, off); } else { - const pid = try posix.fork(); - if (pid == 0) { - // _ = try std.Thread.spawn( - // .{}, - // fuse_helper.mountImage, - // .{ ai.path, ai.mount_dir.?, off }, - // ); - - if (true) { - try fuse_helper.mountImage( - ai.path, - ai.mount_dir.?, - off, - ); - } else { - const offset_string = try std.fmt.allocPrint( - ai.allocator, - "-ooffset={d}", - .{off}, - ); - defer ai.allocator.free(offset_string); - - var proc = std.process.Child.init(&[_][]const u8{ - "squashfuse", - offset_string, - ai.path, - ai.mount_dir.?, - }, ai.allocator); - - _ = try proc.spawnAndWait(); - } - - std.debug.print("UNMOUNT\n\n", .{}); - - posix.exit(0); + // TODO: fix squashfuse-zig crash here + if (false) { + try fuse_helper.mountImage( + ai.path, + ai.mount_dir.?, + off, + ); + } else { + const offset_string = try std.fmt.allocPrint( + ai.allocator, + "-ooffset={d}", + .{off}, + ); + defer ai.allocator.free(offset_string); + + var proc = std.process.Child.init(&[_][]const u8{ + "squashfuse", + offset_string, + ai.path, + ai.mount_dir.?, + }, ai.allocator); + + _ = try proc.spawnAndWait(); } // Values in nanoseconds @@ -1238,17 +1224,12 @@ pub const AppImage = struct { }; // This can't be finished until AppImage.wrapArgs works correctly - pub fn sandbox(ai: *AppImage, opts: SandboxOptions) !void { + pub fn sandbox(ai: *AppImage, perms: Permissions, opts: SandboxOptions) !void { var arena = std.heap.ArenaAllocator.init(ai.allocator); const arena_allocator = arena.allocator(); defer arena.deinit(); - const wrap_args = try ai.wrapArgs(arena_allocator); - - std.debug.print("DEBUG {s} {s}", .{ - @src().fn_name, - wrap_args, - }); + const wrap_args = try ai.wrapArgs(arena_allocator, perms); if (opts.args) |args| { var list = std.ArrayList([]const u8).init(arena_allocator); diff --git a/zig/sockets.json b/zig/sockets.json new file mode 100644 index 0000000..93e3718 --- /dev/null +++ b/zig/sockets.json @@ -0,0 +1,64 @@ +[ + { + "name": "alsa", + "flags": [ + "--ro-bind-try", "/usr/share/alsa", "/usr/share/alsa" + ] + }, + { "name": "cgroup" }, + { + "name": "dbus", + "flags": [ + "--ro-bind-try", "$XDG_RUNTIME_DIR/bus", "/run/user/$UID/bus" + ] + }, + { "name": "ipc" }, + { + "name": "network", + "flags": [ + "--share-net", + "--ro-bind-try", "/etc/ca-certificates", "/etc/ca-certificates", + "--ro-bind-try", "/etc/resolv.conf", "/etc/resolv.conf", + "--ro-bind-try", "/etc/ssl", "/etc/ssl", + "--ro-bind-try", "/etc/pki", "/etc/pki", + "--ro-bind-try", "/usr/share/ca-certificates", "/usr/share/ca-certificates" + ] + }, + { "name": "pid" }, + { + "name": "pipewire", + "flags": [ + "--ro-bind-try", "$XDG_RUNTIME_DIR/pipewire-0", "/run/user/$UID/pipewire-0" + ] + }, + { + "name": "pulseaudio", + "flags": [ + "--ro-bind-try", "$XDG_RUNTIME_DIR/pulse", "/run/user/$UID/pulse", + "--ro-bind-try", "/etc/pulse", "/etc/pulse" + ] + }, + { "name": "session" }, + { "name": "user" }, + { "name": "uts" }, + { + "name": "wayland", + "flags": [ + "--ro-bind-try", "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY", "/run/user/$UID/wayland-0", + "--ro-bind-try", "/usr/share/X11", "/usr/share/X11", + "--setenv", "WAYLAND_DISPLAY", "wayland-0", + "--setenv", "_JAVA_AWT_WM_NONPARENTING", "1", + "--setenv", "MOZ_ENABLE_WAYLAND", "1", + "--setenv", "XDG_SESSION_TYPE", "wayland" + ] + }, + { + "name": "x11", + "flags": [ + "--ro-bind-try", "$XAUTHORITY","$HOME/.Xauthority", + "--ro-bind-try", "$TMPDIR/.X11-unix/X$DISPLAY", "/usr/share/X11", + "--ro-bind-try", "/usr/share/X11", "/usr/share/X11", + "--setenv", "XAUTHORITY", "$HOME/.Xauthority" + ] + } +]