diff options
| author | C. McEnroe | 2021-01-23 00:03:58 -0500 | 
|---|---|---|
| committer | C. McEnroe | 2021-01-23 00:48:15 -0500 | 
| commit | 95bb627ffbb5fcbf9462b5957d0cb25072d8c64e (patch) | |
| tree | d1da30e906765df8f4f61ef886936270e80f1539 | |
| parent | 6ee0aea9e55cd72102a7abee26481179311273f2 (diff) | |
Separate kiosk mode from restrict mode
Restrict mode will focus on sandboxing, while kiosk will continue
to restrict IRC access through a public kiosk. Kiosk mode without
restrict mode allows execution of man 1 catgirl with /help, assuming
external sandboxing.
The /list and /part commands are also added to the list of disabled
commands in kiosk mode, since they are pointless without access to
/join.
| -rw-r--r-- | catgirl.1 | 39 | ||||
| -rw-r--r-- | chat.c | 8 | ||||
| -rw-r--r-- | chat.h | 1 | ||||
| -rw-r--r-- | command.c | 38 | 
4 files changed, 58 insertions, 28 deletions
| @@ -1,4 +1,4 @@ -.Dd January 16, 2021 +.Dd January 22, 2021  .Dt CATGIRL 1  .Os  . @@ -8,7 +8,7 @@  .  .Sh SYNOPSIS  .Nm -.Op Fl Relv +.Op Fl KRelv  .Op Fl C Ar copy  .Op Fl H Ar hash  .Op Fl I Ar highlight @@ -123,6 +123,20 @@ The commands which can be filtered are:  .Sy QUIT ,  .Sy SETNAME .  . +.It Fl K , Cm kiosk +Disable the +.Ic /copy , +.Ic /debug , +.Ic /exec , +.Ic /join , +.Ic /list , +.Ic /msg , +.Ic /open , +.Ic /part , +.Ic /query , +.Ic /quote +commands. +.  .It Fl N Ar util , Cm notify = Ar util  Send notifications using a utility.  Use more than once to add arguments to @@ -145,14 +159,19 @@ The default is the first available of  .It Fl R , Cm restrict  Disable the  .Ic /copy , -.Ic /debug , -.Ic /exec , -.Ic /join , -.Ic /msg , -.Ic /open , -.Ic /query , -.Ic /quote -commands. +.Ic /exec +and +.Ic /open +commands, +as well as viewing this manual with +.Ic /help . +On +.Ox , +restrict system operations +and filesystem access with +.Xr pledge 2 +and +.Xr unveil 2 .  .  .It Fl S Ar host , Cm bind = Ar host  Bind to source address @@ -159,7 +159,6 @@ static void sandbox(const char *trust, const char *cert, const char *priv) {  		const char *path;  		const char *perm;  	} paths[] = { -		{ "/usr/bin/man", "x" },  		{ "/usr/share/terminfo", "r" },  		{ tls_default_ca_cert_file(), "r" },  		{ NULL, NULL }, @@ -200,6 +199,7 @@ int main(int argc, char *argv[]) {  		{ .val = 'C', .name = "copy", required_argument },  		{ .val = 'H', .name = "hash", required_argument },  		{ .val = 'I', .name = "highlight", required_argument }, +		{ .val = 'K', .name = "kiosk", no_argument },  		{ .val = 'N', .name = "notify", required_argument },  		{ .val = 'O', .name = "open", required_argument },  		{ .val = 'R', .name = "restrict", no_argument }, @@ -236,6 +236,7 @@ int main(int argc, char *argv[]) {  			break; case 'C': utilPush(&urlCopyUtil, optarg);  			break; case 'H': parseHash(optarg);  			break; case 'I': filterAdd(Hot, optarg); +			break; case 'K': self.kiosk = true;  			break; case 'N': utilPush(&uiNotifyUtil, optarg);  			break; case 'O': utilPush(&urlOpenUtil, optarg);  			break; case 'R': self.restricted = true; @@ -325,7 +326,8 @@ int main(int argc, char *argv[]) {  	sig_t cursesWinch = signal(SIGWINCH, signalHandler);  	fcntl(irc, F_SETFD, FD_CLOEXEC); -	if (!self.restricted) { +	bool pipes = !self.kiosk && !self.restricted; +	if (pipes) {  		int error = pipe(utilPipe);  		if (error) err(EX_OSERR, "pipe"); @@ -345,7 +347,7 @@ int main(int argc, char *argv[]) {  		{ .events = POLLIN, .fd = execPipe[0] },  	};  	while (!self.quit) { -		int nfds = poll(fds, (self.restricted ? 2 : ARRAY_LEN(fds)), -1); +		int nfds = poll(fds, (pipes ? ARRAY_LEN(fds) : 2), -1);  		if (nfds < 0 && errno != EINTR) err(EX_IOERR, "poll");  		if (nfds > 0) {  			if (fds[0].revents) uiRead(); @@ -183,6 +183,7 @@ enum Cap {  extern struct Self {  	bool debug; +	bool kiosk;  	bool restricted;  	size_t pos;  	enum Cap caps; @@ -457,6 +457,10 @@ static void commandHelp(uint id, char *params) {  		replies[ReplyHelp]++;  		return;  	} +	if (self.restricted) { +		uiFormat(id, Warm, NULL, "See catgirl(1) or /help index"); +		return; +	}  	uiHide();  	pid_t pid = fork(); @@ -474,7 +478,8 @@ static void commandHelp(uint id, char *params) {  enum Flag {  	BIT(Multiline), -	BIT(Restricted), +	BIT(Restrict), +	BIT(Kiosk),  };  static const struct Handler { @@ -485,37 +490,37 @@ static const struct Handler {  	{ "/away", commandAway, 0 },  	{ "/ban", commandBan, 0 },  	{ "/close", commandClose, 0 }, -	{ "/copy", commandCopy, Restricted }, +	{ "/copy", commandCopy, Restrict | Kiosk },  	{ "/cs", commandCS, 0 }, -	{ "/debug", commandDebug, Restricted }, +	{ "/debug", commandDebug, Kiosk },  	{ "/deop", commandDeop, 0 },  	{ "/devoice", commandDevoice, 0 },  	{ "/except", commandExcept, 0 }, -	{ "/exec", commandExec, Multiline | Restricted }, -	{ "/help", commandHelp, 0 }, +	{ "/exec", commandExec, Multiline | Restrict }, +	{ "/help", commandHelp, 0 }, // Restrict special case.  	{ "/highlight", commandHighlight, 0 },  	{ "/ignore", commandIgnore, 0 },  	{ "/invex", commandInvex, 0 },  	{ "/invite", commandInvite, 0 }, -	{ "/join", commandJoin, Restricted }, +	{ "/join", commandJoin, Kiosk },  	{ "/kick", commandKick, 0 }, -	{ "/list", commandList, 0 }, +	{ "/list", commandList, Kiosk },  	{ "/me", commandMe, 0 },  	{ "/mode", commandMode, 0 },  	{ "/move", commandMove, 0 }, -	{ "/msg", commandMsg, Multiline | Restricted }, +	{ "/msg", commandMsg, Multiline | Kiosk },  	{ "/names", commandNames, 0 },  	{ "/nick", commandNick, 0 },  	{ "/notice", commandNotice, Multiline },  	{ "/ns", commandNS, 0 }, -	{ "/o", commandOpen, Restricted }, +	{ "/o", commandOpen, Restrict | Kiosk },  	{ "/op", commandOp, 0 }, -	{ "/open", commandOpen, Restricted }, +	{ "/open", commandOpen, Restrict | Kiosk },  	{ "/ops", commandOps, 0 }, -	{ "/part", commandPart, 0 }, -	{ "/query", commandQuery, Restricted }, +	{ "/part", commandPart, Kiosk }, +	{ "/query", commandQuery, Kiosk },  	{ "/quit", commandQuit, 0 }, -	{ "/quote", commandQuote, Multiline | Restricted }, +	{ "/quote", commandQuote, Multiline | Kiosk },  	{ "/say", commandPrivmsg, Multiline },  	{ "/setname", commandSetname, 0 },  	{ "/topic", commandTopic, 0 }, @@ -584,8 +589,11 @@ void command(uint id, char *input) {  		uiFormat(id, Warm, NULL, "No such command %s", cmd);  		return;  	} -	if (self.restricted && handler->flags & Restricted) { -		uiFormat(id, Warm, NULL, "Command %s is restricted", cmd); +	if ( +		(self.restricted && handler->flags & Restrict) || +		(self.kiosk && handler->flags & Kiosk) +	) { +		uiFormat(id, Warm, NULL, "Command %s is unavailable", cmd);  		return;  	} | 
