PERFORCE change 166063 for review

Jonathan Anderson jona at FreeBSD.org
Tue Jul 14 06:43:55 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=166063

Change 166063 by jona at jona-trustedbsd-belle-vmware on 2009/07/14 06:43:49

	Lots of changes to user_angel that happened on the plane (and are thus not little atoms of changes)

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/Makefile#10 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/policy.c#1 add
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/powerbox.c#8 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/powerbox.h#8 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/server.c#14 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/server.h#3 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/test_client.c#14 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/Makefile#10 (text+ko) ====

@@ -9,7 +9,7 @@
 LIBS=-lcapability -luserangel -lsbuf
 
 BIN=user_angel test_client
-AGENT_OBJ = user_angel.o server.o cap.o powerbox.o dbus.o
+AGENT_OBJ = user_angel.o server.o policy.o cap.o powerbox.o dbus.o
 CLIENT_OBJ = test_client.o
 
 

==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/powerbox.c#8 (text+ko) ====

@@ -41,6 +41,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "cap.h"
 #include "dbus.h"
 #include "powerbox.h"
 

==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/powerbox.h#8 (text+ko) ====

@@ -37,35 +37,6 @@
 
 #include <libuserangel-powerbox.h>
 
-#include "cap.h"
-
-#if 0
-enum capbox_ui_t { QT, KDE /* TODO, GNOME, NCURSES*/ };
-
-enum capbox_op_t
-{
-	OPEN_FILE,
-	SAVE_FILE,
-	SELECT_DIR
-};
-
-struct capbox_options
-{
-	enum capbox_ui_t	ui;            /* UI type */
-	enum capbox_op_t	operation;     /* operation to perform */
-	char*			window_title;  /* set by user_angel, not sandbox */
-	int			parent_window; /* X11 window to attach to (or 0) */
-	const char*		start_path;    /* path to start in (or NULL) */
-	int			pathlen;       /* length of start path */
-	int			start_fd;      /* FD to start in (or -1) */
-	int			mult;          /* allow multiple selection */
-	const char*		filter;        /* filter expression (or NULL) */
-	int			filterlen;     /* length of filter expression */
-	int			flags;         /* open() flags, e.g. O_RDONLY */
-	cap_rights_t		rights;        /* capabilities, e.g. CAP_SEEK */
-};
-#endif
-
 
 /**
  * Open a powerbox.

==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/server.c#14 (text+ko) ====

@@ -51,15 +51,17 @@
 #include "server.h"
 
 
+
+struct client *clients = NULL;
+
+struct fd_set client_fds;
+int highest_fd;
+
+
 int fd_control;
 int shutting_down = 0;
 char control_socket_name[256] = "";
 
-char current_error[512];
-
-struct fd_set clients;
-int highest_fd;
-
 
 void user_angel_server_shutdown(void)
 {
@@ -76,11 +78,12 @@
 int	bind_to_path(const char *path);
 void	serve(int fd_server, struct fd_set *clients);
 void	accept_client(int fd_server);
-int	service_client(int client);
-int	handle_request(int client, enum ua_request_t req);
-int	handle_path_request(int client);
-int	handle_powerbox_request(int client);
-void	close_client(int client, int errnum, const char *msg);
+int	service_client(struct client*);
+int	handle_request(struct client*, enum ua_request_t);
+int	handle_path_request(struct client*, struct ua_datum*);
+int	handle_powerbox_request(struct client*, struct ua_datum*);
+void	client_error(struct client*, const char *message, int errnum,
+                     int close_connection);
 
 
 
@@ -98,7 +101,7 @@
 	}
 
 
-	while(fd_control) serve(fd_control, &clients);
+	while(fd_control) serve(fd_control, &client_fds);
 	user_angel_server_shutdown();
 
 	return 0;
@@ -107,7 +110,7 @@
 
 int bind_to_path(const char *path)
 {
-	FD_ZERO(&clients);
+	FD_ZERO(&client_fds);
 
 	struct sockaddr_un addr;
 	addr.sun_family = AF_UNIX;
@@ -157,7 +160,7 @@
 		return -1;
 	}
 
-	FD_SET(fd, &clients);
+	FD_SET(fd, &client_fds);
 
 
 
@@ -168,14 +171,13 @@
 
 void accept_client(int fd_server)
 {
-	int client;
 	struct sockaddr_un clientaddr;
 	unsigned int clientaddrlen;
 
-	client = accept(fd_server, (struct sockaddr*) &clientaddr,
-	                &clientaddrlen);
+	int sock = accept(fd_server, (struct sockaddr*) &clientaddr,
+	                  &clientaddrlen);
 
-	if(client < 0)
+	if(sock < 0)
 	{
 		if(errno == EAGAIN) { usleep(1); return; }
 		if(shutting_down) return;
@@ -184,25 +186,50 @@
 		return;
 	}
 
-	printf("Client %4i: Accepted\n", client);
+
+	struct client *client = malloc(sizeof(struct client) + 16);
+	client->policy_callback = default_policy;
+
+	client->socket = sock;
+	FD_SET(sock, &client_fds);
+	if(sock > highest_fd) highest_fd = sock;
+
+	client->name = ((char*) client) + sizeof(struct client);
+	sprintf(client->name, "FD %i", client->socket);   /* TODO: nicer name? */
+
+	if(clients == NULL)
+	{
+		client->next = NULL;
+		client->prev = NULL;
+		clients = client;
+	}
+	else
+		for(struct client *c = clients; ; c = c->next)
+			if(c->next == NULL)
+			{
+				c->next = client;
+				client->prev = c;
+				client->next = NULL;
+				break;
+			}
 
-	FD_SET(client, &clients);
-	if(client > highest_fd) highest_fd = client;
 
 	char hello[80];
 	sprintf(hello, "user_angel %s", ua_protocol_version());
 	struct ua_datum *d = ua_marshall_string(hello, strlen(hello));
 
-	ua_send(client, d, NULL, 0);
+	ua_send(client->socket, d, NULL, 0);
 	free(d);
+
+	printf("Accepted client '%s'\n", client->name);
 }
 
 
 
-void serve(int fd_server, struct fd_set *clients)
+void serve(int fd_server, struct fd_set *client_fds)
 {
 	struct fd_set selected;
-	memcpy(&selected, clients, sizeof(*clients));
+	memcpy(&selected, client_fds, sizeof(*client_fds));
  
 
 	int ready = select(highest_fd + 1, &selected, NULL, NULL, NULL);
@@ -217,31 +244,38 @@
 		return;
 	}
 
-	for(int i = 0; (i <= highest_fd) && (ready > 0); i++)
+	if(FD_ISSET(fd_server, &selected))
 	{
-		if(FD_ISSET(i, &selected))
+		accept_client(fd_server);
+
+		FD_CLR(fd_server, &selected);
+		ready--;
+	}
+
+	for(struct client *c = clients; c && ready; c = c->next)
+		if(FD_ISSET(c->socket, &selected))
 		{
-			if(i == fd_server) accept_client(i);
-			else if FD_ISSET(i, clients) service_client(i);
+			int sock = c->socket;
+			service_client(c);
 
+			FD_CLR(sock, &selected);
 			ready--;
 		}
-	}
 }
 
 
-int service_client(int client)
+int service_client(struct client *client)
 {
 	enum ua_request_t req;
-	struct ua_datum *d = ua_recv(client, NULL, NULL);
+	struct ua_datum *d = ua_recv(client->socket, NULL, NULL);
 
 	if(!d)
 	{
 		if((errno == ENOENT) || (errno == ECONNRESET) || (errno == EAGAIN)
 		   || (errno == EPIPE))
-			close_client(client, errno, "Client socket closed");
+			client_error(client, "Socket closed", errno, 1);
 
-		else perror("Error receiving from client");
+		else client_error(client, "Error receiving from client", errno, 1);
 
 		return -1;
 	}
@@ -253,115 +287,107 @@
 
 	else
 	{
-		sprintf(current_error, "enum size is %iB",
-		                       sizeof(enum ua_request_t));
+		errno = EINVAL;
 		return -1;
 	}
 
-	if(bytes < 0)
+	if(bytes < 0) return -1;
+
+	for(struct client *client = clients; client; client = client->next)
 	{
-		strcpy(current_error, ua_protocol_error());
-		return -1;
-	}
+		int ret = handle_request(client, req);
+		if(ret)
+		{
+			int close_connection = (ret < 0);
+			client_error(client, "Error handling client request",
+			             errno, close_connection);
+			return ret;
+		}
+		else return 0;
 
-	if(handle_request(client, req))
-	{
-		close_client(client, errno, current_error);
-		return 0;
 	}
 
-	return 0;
+	fprintf(stderr, "No clients defined\n");
+	return -1;
 }
 
 
-int handle_request(int client, enum ua_request_t req)
+int handle_request(struct client *client, enum ua_request_t req)
 {
-	printf("Client %4i: ", client);
+	printf("Client %s: ", client->name);
+	fflush(stdout);
+
+	struct ua_datum *datum = ua_recv(client->socket, NULL, NULL);
+
+	if(client->policy_callback == NULL)
+	{
+		fprintf(stderr, "No policy callback set for %s\n", client->name);
+		errno = EPERM;
+		return -1;
+	}
+	else if(!(client->policy_callback(client, req, datum)))
+	{
+		errno = EPERM;
+		return -1;
+	}
 
+	int retval;
 	switch(req)
 	{
 		case UA_OPEN_PATH:
-			return handle_path_request(client);
+			retval = handle_path_request(client, datum);
+			break;
 
 		case UA_POWERBOX:
 			puts("UA_POWERBOX");
-			return handle_powerbox_request(client);
+			retval = handle_powerbox_request(client, datum);
+			break;
 
 		default:
-			sprintf(current_error, "Unknown request %i", req);
-			return -1;
+			errno = EINVAL;
+			retval = -1;
 	}
 
-	return 0;
+	free(datum);
+	return retval;
 }
 
 
-int handle_path_request(int client)
+int handle_path_request(struct client *client, struct ua_datum *d)
 {
-	unsigned int fdlen = 0;
+//	unsigned int fdlen = 0;
 	char path[256] = "";
 	unsigned int pathlen = 256;
 
 	printf("UA_OPEN_PATH");
 
-	struct ua_datum *d = ua_recv(client, NULL, &fdlen);
-	if(ua_unmarshall_string(d, path, &pathlen) < 0)
-	{
-		strcpy(current_error, ua_protocol_error());
-		return -1;
-	}
-	free(d);
+	int sock = client->socket;
+
+//	struct ua_datum *d = ua_recv(sock, NULL, &fdlen);
+	if(ua_unmarshall_string(d, path, &pathlen) < 0) return -1;
+//	free(d);
 
 	printf(": %s\n", path);
 
 	int32_t flags, rights;
-	if(ua_unmarshall_int(ua_recv(client, NULL, NULL), &flags) < 0)
-	{
-		fprintf(stderr, "Error unmarshalling flags: %s\n", ua_protocol_error());
-		return -1;
-	}
+	if(ua_unmarshall_int(ua_recv(sock, NULL, NULL), &flags) < 0) return -1;
+	if(ua_unmarshall_int(ua_recv(sock, NULL, NULL), &rights) < 0) return -1;
 
-	if(ua_unmarshall_int(ua_recv(client, NULL, NULL), &rights) < 0)
-	{
-		fprintf(stderr, "Error unmarshalling rights: %s\n", ua_protocol_error());
-		return -1;
-	}
 
-
 	int cap = cap_open(path, flags, rights);
-	if(cap < 0)
-	{
-		strcpy(current_error, cap_error());
-		return -1;
-	}
+	if(cap < 0) return 1;
 
 	d = ua_marshall_int(1);
-	if(!d)
-	{
-		strcpy(current_error, ua_protocol_error());
-		return -1;
-	}
+	if(!d) return -1;
 
-	if(ua_send(client, d, NULL, 0) < 0)
-	{
-		sprintf(current_error, "Error sending FD count: %s", strerror(errno));
-		return -1;
-	}
+	if(ua_send(sock, d, NULL, 0) < 0) return -1;
 	free(d);
 
 	d = ua_marshall_string(path, pathlen);
-	if(!d)
-	{
-		strcpy(current_error, ua_protocol_error());
-		return -1;
-	}
+	if(!d) return -1;
+
+	if(ua_send(sock, d, &cap, 1) < 0) return -1;
 
-	if(ua_send(client, d, &cap, 1) < 0)
-	{
-		sprintf(current_error, "Error sending FD: %i (%s)",
-		                        errno, strerror(errno));
-		return -1;
-	}
 	close(cap);
 	free(d);
 
@@ -369,45 +395,27 @@
 }
 
 
-int handle_powerbox_request(int client)
+int handle_powerbox_request(struct client *client, struct ua_datum *d)
 {
 	struct ua_powerbox_options options;
-	unsigned int fdlen = 1;
+	if(ua_unmarshall_powerbox(d, &options) < 0) return -1;
 
-	struct ua_datum *d = ua_recv(client, &options.start_fd, &fdlen);
-	if(!d)
-	{
-		perror("Error receiving powerbox options");
-		return -1;
-	}
 
-	if(ua_unmarshall_powerbox(d, &options) < 0)
-	{
-		strcpy(current_error, ua_protocol_error());
-		return -1;
-	}
-
-
-	// TODO: some more sophisticated per-client state (eg name)
-	options.window_title = (char*) malloc(80);
+	options.window_title = (char*) malloc(strlen(client->name) + 64);
 	sprintf(options.window_title,
-	        "Powerbox for user_angel client %i", client);
+	        "Powerbox for user_angel client %s", client->name);
 
 
 	int fds[32];
 	char *names[32];
 	int len = 32;
-	if(capbox_display(&options, fds, names, &len))
-	{
-		strcpy(current_error, "Unknown error in powerbox");
-		return -1;
-	}
+	if(capbox_display(&options, fds, names, &len)) return -1;
 
 	free(options.window_title);
 
 
 	struct ua_datum *fdcount = ua_marshall_int(len);
-	if(ua_send(client, fdcount, NULL, 0) < 0)
+	if(ua_send(client->socket, fdcount, NULL, 0) < 0)
 	{
 		perror("Error sending FD count");
 		return -1;
@@ -419,7 +427,7 @@
 		struct ua_datum *d
 			= ua_marshall_string(name, strlen(name));
 
-		if(ua_send(client, d, fds + i, 1) < 0)
+		if(ua_send(client->socket, d, fds + i, 1) < 0)
 		{
 			printf("Error sending file descriptor");
 			return -1;
@@ -430,24 +438,29 @@
 }
 
 
-void close_client(int client, int errnum, const char *reason)
+void client_error(struct client *client, const char *message, int errnum, int close_connection)
 {
-	printf("Client %4i: Closing", client);
+	fprintf(stderr, "%s: %i (%s)\n",
+	                 message, errnum, strerror(errnum));
+
+	ua_send(client->socket, ua_marshall_error(errnum, message, strlen(message)),
+	        NULL, 0);
+
+	if(close_connection)
+	{
+		close(client->socket);
+		FD_CLR(client->socket, &client_fds);
 
-	if((errnum == ECONNRESET) || (errnum == EAGAIN))
-		printf(" (client connection closed)");
-	else
-       		printf(" (reason: '%s', errno: %i/'%s')",
-		        reason, errnum, strerror(errnum));
-	printf("\n");
+		if(client->socket == highest_fd)
+			while(!FD_ISSET(highest_fd, &client_fds) && (highest_fd >= 0))
+				highest_fd--;
 
-	ua_send(client, ua_marshall_error(errnum, reason, strlen(reason)), NULL, 0);
+		if(client->prev) client->prev->next = client->next;
+		if(client->next) client->next->prev = client->prev;
 
-	close(client);
-	FD_CLR(client, &clients);
+		if(!client->prev && !client->next) clients = NULL;
 
-	if(client == highest_fd)
-		while(!FD_ISSET(highest_fd, &clients) && (highest_fd >= 0))
-			highest_fd--;
+		free(client);
+	}
 }
 

==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/server.h#3 (text+ko) ====

@@ -31,8 +31,31 @@
  * SUCH DAMAGE.
  */
 
+#ifndef UA_SERVER_H
+
+#include <libuserangel.h>
+
+#include "policy.h"
+
 
+
+/* Represents a client of the User Angel */
+struct client
+{
+	char *name;
+	int socket;
+
+	policy_callback_ptr policy_callback;
+	
+	struct client *next;
+	struct client *prev;
+};
+
+
 void user_angel_server_shutdown(void);
 
 int run_server(const char* address);
 
+#define UA_SERVER_H
+#endif
+

==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/test_client.c#14 (text+ko) ====

@@ -6,6 +6,7 @@
 #include <libuserangel.h>
 
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -24,8 +25,7 @@
 	int fd_angel = ua_find();
 	if(fd_angel < 0)
 	{
-		fprintf(stderr, "Error finding user angel: %s\n",
-		                ua_protocol_error());
+		errno = ENOENT;
 		return -1;
 	}
 	printf("Connected to user angel via FD %i\n", fd_angel);
@@ -104,11 +104,7 @@
 
 	int fdcount;
 	if(ua_unmarshall_int(fdcountd, &fdcount) < 0)
-	{
-		fprintf(stderr, "Error unmarshalling FD count: %s\n",
-		                 ua_protocol_error());
-		return;
-	}
+		err(EX_SOFTWARE, "Error unmarshalling FD count");
 
 	for(int i = 0; i < fdcount; i++)
 	{


More information about the p4-projects mailing list