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