Date: Tue, 14 Jul 2009 06:43:53 GMT From: Jonathan Anderson <jona@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 166063 for review Message-ID: <200907140643.n6E6hrWk033376@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=166063 Change 166063 by jona@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++) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907140643.n6E6hrWk033376>