PERFORCE change 164095 for review
Jonathan Anderson
jona at FreeBSD.org
Thu Jun 11 12:01:15 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=164095
Change 164095 by jona at jona-trustedbsd-belle-vm on 2009/06/11 12:00:09
user_angel can now handle requests for powerboxes (although the powerbox isn't actually implemented yet)
Affected files ...
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/Makefile#3 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/fdcomm.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/protocol.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/protocol.h#3 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/server.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/test_client.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/user_angel.c#3 edit
Differences ...
==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/Makefile#3 (text+ko) ====
@@ -1,7 +1,7 @@
CFLAGS=-g -ggdb --std=c99 -Wall -Werror -pedantic-errors
BIN=user_angel test_client
-AGENT_OBJ = user_angel.o server.o cap.o protocol.o fdcomm.o
+AGENT_OBJ = user_angel.o server.o cap.o protocol.o fdcomm.o powerbox.o
CLIENT_OBJ = test_client.o protocol.o fdcomm.o
@@ -16,7 +16,8 @@
cap.o: cap.c cap.h
fdcomm.o: fdcomm.c fdcomm.h
-protocol.o: protocol.c protocol.h
+powerbox.o: powerbox.c powerbox.h
+protocol.o: protocol.c protocol.h powerbox.h
server.o: server.c protocol.h server.h
user_angel.o: user_angel.c protocol.h server.h
==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/fdcomm.c#3 (text+ko) ====
@@ -100,6 +100,7 @@
anc_data.hdr.cmsg_len = sizeof(struct fdhdr);
anc_data.hdr.cmsg_level = SOL_SOCKET;
anc_data.hdr.cmsg_type = SCM_RIGHTS;
+ anc_data.fd = -1;
struct msghdr header;
header.msg_name = NULL;
==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/protocol.c#3 (text+ko) ====
@@ -33,32 +33,152 @@
#include <sys/socket.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "protocol.h"
-int get_int_from(int client, int *value)
+
+int cap_send_int(int client, int value)
+{
+ return send(client, &value, sizeof(int), 0);
+}
+
+int cap_recv_int(int client, int *value)
+{
+ int bytes = -1;
+ while(bytes < 0)
+ {
+ bytes = recv(client, value, sizeof(int), 0);
+
+ if((bytes < 0) && (errno == EAGAIN)) continue;
+ else break;
+ }
+
+ return bytes;
+}
+
+
+int cap_send_string(int client, char *str, int len)
{
- return recv(client, value, sizeof(int), 0);
+ int total_bytes;
+ int bytes = cap_send_int(client, len);
+ if(bytes < 0) return bytes;
+ else total_bytes = bytes;
+
+ if(len > 0)
+ {
+ bytes = send(client, str, len, 0);
+ if(bytes < 0) { perror("Error sending string"); return bytes; }
+ else total_bytes += bytes;
+ }
+
+ return total_bytes;
}
-int get_string_from(int client, char *value, int maxlen)
+int cap_recv_string(int client, char **value)
{
- int len;
- int bytes = get_int_from(client, &len);
- if(bytes <= 0) return bytes;
+ int len, total_bytes;
+ int bytes = cap_recv_int(client, &len);
+ if(bytes<= 0) return bytes;
+ else total_bytes = bytes;
+
+ *value = (char*) malloc(len + 1);
bytes = 0;
while(bytes < len)
{
- int new_bytes = recv(client, value + bytes, maxlen - bytes, 0);
+ int new_bytes = recv(client, *value + bytes, len - bytes, 0);
if(new_bytes < 0) return new_bytes;
- bytes = bytes + new_bytes;
+ bytes += new_bytes;
}
- return bytes;
+ (*value)[len] = '\0';
+ total_bytes += bytes;
+
+ return total_bytes;
+}
+
+
+int cap_send_capbox_options(int client, struct capbox_options *options)
+{
+ int bytes, total_bytes = 0;
+
+ bytes = cap_send_int(client, options->ui);
+ if(bytes <= 0) return bytes;
+ total_bytes += bytes;
+
+ bytes = cap_send_int(client, options->operation);
+ if(bytes <= 0) return bytes;
+ total_bytes += bytes;
+
+ bytes = cap_send_int(client, options->parent_window);
+ if(bytes <= 0) return bytes;
+ total_bytes += bytes;
+
+ bytes = cap_send_string(client, options->start_path, options->pathlen);
+ if(bytes <= 0) return bytes;
+ total_bytes += bytes;
+/* TODO: need to do a sendmsg with SCM_RIGHTS
+ bytes = cap_send_int(client, options->start_fd);
+ if(bytes <= 0) return bytes;
+ total_bytes += bytes;
+*/
+ bytes = cap_send_int(client, options->mult);
+ if(bytes <= 0) return bytes;
+ total_bytes += bytes;
+
+ bytes = cap_send_string(client, options->filter, options->filterlen);
+ if(bytes <= 0) return bytes;
+ total_bytes += bytes;
+
+ return total_bytes;
}
+int cap_recv_capbox_options(int client, struct capbox_options *options)
+{
+ int bytes, total_bytes = 0;
+
+ bytes = cap_recv_int(client, (int*) &options->ui);
+ if(bytes <= 0) { perror("Error receiving UI option"); return bytes; }
+ total_bytes += bytes;
+
+ bytes = cap_recv_int(client, (int*) &options->operation);
+ if(bytes <= 0) { perror("Error receiving operation"); return bytes; }
+ total_bytes += bytes;
+
+ bytes = cap_recv_int(client, &options->parent_window);
+ if(bytes <= 0) { perror("Error receiving parent winid"); return bytes; }
+ total_bytes += bytes;
+
+ bytes = cap_recv_string(client, &options->start_path);
+ if(bytes < 0) { perror("Error receiving start path"); return bytes; }
+ total_bytes += bytes;
+
+ options->pathlen = bytes;
+/* TODO: need to do a sendmsg with SCM_RIGHTS
+ bytes = cap_recv_int(client, &options->start_fd);
+ if(bytes <= 0) { perror("Error receiving path FD"); return bytes; }
+ total_bytes += bytes;
+*/
+ options->start_fd = -1;
+
+ bytes = cap_recv_int(client, &options->mult);
+ if(bytes <= 0) { perror("Error receiving multiple option"); return bytes; }
+ total_bytes += bytes;
+
+ bytes = cap_recv_string(client, &options->filter);
+ if(bytes <= 0) { perror("Error receiving filter"); return bytes; }
+ total_bytes += bytes;
+
+ options->filterlen = bytes;
+
+ return total_bytes;
+}
==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/protocol.h#3 (text+ko) ====
@@ -34,27 +34,24 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "powerbox.h"
+
/** Requests that clients can make */
-enum user_angel_request
+enum capangel_req_t
{
FD_FROM_PATH,
- FD_POWERBOX,
- FD_POWERBOX_RELATIVE_PATH,
- FD_POWERBOX_RELATIVE_FD
+ FD_POWERBOX
};
-typedef int user_angel_powerbox_options;
-#define POWERBOX_KDE 0x01
-#define POWERBOX_GNOME 0x02 /* currently no support */
+int cap_send_int(int client, int value);
+int cap_recv_int(int client, int *value);
+int cap_send_string(int client, char *value, int len);
+int cap_recv_string(int client, char **value);
-
-
-
-int get_int_from(int client, int *value);
-int get_string_from(int client, char *value, int maxlen);
-
+int cap_send_capbox_options(int client, struct capbox_options *options);
+int cap_recv_capbox_options(int client, struct capbox_options *options);
==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/server.c#3 (text+ko) ====
@@ -72,7 +72,7 @@
-int handle_request(int client, enum user_angel_request req);
+int handle_request(int client, enum capangel_req_t req);
int bind_to_path(const char *path);
void accept_client(int fd_server);
void service_clients(void);
@@ -204,19 +204,25 @@
void service_clients(void)
{
- enum user_angel_request req;
+ enum capangel_req_t req;
for(int i = 0; i < clientslen; i++)
{
int client = clients[i];
- int bytes = get_int_from(client, (int*) &req);
+ if(client == -1) continue;
+
+ int bytes = cap_recv_int(client, (int*) &req);
if(bytes > 0)
{
if(handle_request(client, req))
+ {
perror("Error handling client request");
+ close(client);
+ clients[i] = -1;
+ }
}
- else if((bytes == 0) && (errno == EAGAIN)) continue;
+ else if(errno == EAGAIN) continue;
else
{
if(shutting_down) return;
@@ -229,7 +235,7 @@
-int handle_request(int client, enum user_angel_request req)
+int handle_request(int client, enum capangel_req_t req)
{
printf("Client %i requests ", client);
@@ -237,33 +243,57 @@
{
case FD_FROM_PATH:
;
- char path[256];
- int bytes = get_string_from(client, path, sizeof(path) - 1);
+ char *path;
+ int bytes = cap_recv_string(client, &path);
if(bytes < 0)
{
perror("Error getting string from client");
return -1;
}
- path[bytes] = '\0';
printf("FD_FROM_PATH: %s\n", path);
int cap = cap_open(path, O_RDONLY, CAP_SET_FILE_READ);
if(fd_send(client, cap))
+ {
perror("Error sending file descriptor");
-
- break;
+ return -1;
+ }
+ else return 0;
case FD_POWERBOX:
puts("FD_POWERBOX");
- break;
+
+ struct capbox_options options;
+ if(cap_recv_capbox_options(client, &options) < 0)
+ {
+ perror("Error receiving capbox_options");
+ return -1;
+ }
+
+ // TODO: some more sophisticated per-client state (eg name)
+ options.window_title = (char*) malloc(80);
+ sprintf(options.window_title,
+ "Powerbox for user_angel client %i", client);
+
+ int fd = capbox_display(&options);
+ if(fd < 0)
+ {
+ perror("Error in powerbox");
+ cap_send_string(client, "error in powerbox", 17);
+ return 0;
+ }
+
+ free(options.window_title);
+ free(options.start_path);
- case FD_POWERBOX_RELATIVE_PATH:
- puts("FD_POWERBOX_RELATIVE_PATH");
- break;
+ if(fd_send(client, cap))
+ {
+ perror("Error sending file descriptor");
+ return -1;
+ }
+ else return 0;
- case FD_POWERBOX_RELATIVE_FD:
- puts("FD_POWERBOX_RELATIVE_FD");
break;
default:
==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/test_client.c#3 (text+ko) ====
@@ -18,10 +18,13 @@
int connect_to_user_angel(void);
-int
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
- int fd_control = connect_to_user_angel();
+ int fd_angel = connect_to_user_angel();
+ printf("angel FD: %i\n", fd_angel);
+
+ fd_angel = cap_new(fd_angel, CAP_CONNECT | CAP_READ | CAP_WRITE);
+ printf("angel cap: %i\n", fd_angel);
int proc;
pid_t pid = pdfork(&proc);
@@ -31,64 +34,69 @@
else if(pid == 0) return 0;
// enter capability mode
-// if(cap_enter()) err(EX_SOFTWARE, "Failed to enter capability mode");
-// else printf("Now operating in capability mode\n");
+ if(cap_enter()) err(EX_SOFTWARE, "Failed to enter capability mode");
+ else printf("Now operating in capability mode\n");
+ // make sure that we are, in fact, sandboxed
+ char *path = "/etc/passwd";
+ if(open(path, O_RDONLY) < 0) printf("Sandbox is working\n");
+ else fprintf(stderr, "Was able to open %s directly\n", path);
- enum user_angel_request req = FD_FROM_PATH;
- char *path = "/etc/passwd";
- int len = strlen(path);
- // make sure that we are, in fact, sandboxed
- if(open(path, O_RDONLY) < 0) printf("Sandbox is working\n");
- else fprintf(stderr, "Was able to open %s directly\n", path);
+ enum capangel_req_t req = FD_FROM_PATH;
+// char *path = "/etc/passwd";
+ int len = strlen(path);
// get the user angel to open the file for us
- if(send(fd_control, &req, sizeof(int), 0) < 0)
+ if(cap_send_int(fd_angel, req) < 0)
err(EX_IOERR, "Error sending request type %i", req);
- if(send(fd_control, &len, sizeof(int), 0) < 0)
- err(EX_IOERR, "Error sending path length %i", len);
-
- if(send(fd_control, path, len, 0) < 0)
+ if(cap_send_string(fd_angel, path, len) < 0)
err(EX_IOERR, "Error sending path '%s'", path);
// retrieve the file descriptor
- int fd = fd_recv(fd_control);
+ int fd = fd_recv(fd_angel);
if(fd >= 0) printf("Got file descriptor %i\n", fd);
- else { fprintf(stderr, "Error receiving descriptor\n"); return 1; }
+ else err(EX_IOERR, "Error receiving file descriptor");
+ // do some reading
+ char buf[40];
+ read(fd, buf, 40);
+ printf("Data from %s: %s\n", path, buf);
-
- path = "/etc/group";
- // get the user angel to open the file for us
- if(send(fd_control, &req, sizeof(int), 0) < 0)
- err(EX_IOERR, "Error sending request type %i", req);
- if(send(fd_control, &len, sizeof(int), 0) < 0)
- err(EX_IOERR, "Error sending path length %i", len);
+ // now, let's try a powerbox!
+ req = FD_POWERBOX;
- if(send(fd_control, path, len, 0) < 0)
- err(EX_IOERR, "Error sending path '%s'", path);
+ struct capbox_options options;
+ options.ui = KDE;
+ options.operation = OPEN_FILE;
+ options.parent_window = 0;
+ options.start_path = NULL;
+ options.pathlen = 0;
+ options.start_fd = -1;
+ options.mult = 1;
+ options.filter = "*.c";
+ options.filterlen = strlen(options.filter);
+ if(cap_send_int(fd_angel, req) < 0)
+ err(EX_IOERR, "Error sending powerbox request");
+ int bytes = cap_send_capbox_options(fd_angel, &options);
+ if(bytes < 0)
+ err(EX_IOERR, "Error sending capbox_options");
- // retrieve the file descriptor
- fd = fd_recv(fd_control);
+ fd = fd_recv(fd_angel);
if(fd >= 0) printf("Got file descriptor %i\n", fd);
- else { fprintf(stderr, "Error receiving descriptor\n"); return 1; }
+ else err(EX_IOERR, "Error receiving file descriptor");
- char buf[40];
- read(fd, buf, 40);
- printf("Data from %s: %s\n", path, buf);
-
return 0;
}
@@ -109,10 +117,10 @@
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, control_socket_name);
- int fd_control = socket(AF_UNIX, SOCK_STREAM, 0);
- if(connect(fd_control, (struct sockaddr*) &addr, sizeof(addr)))
+ int fd_angel = socket(AF_UNIX, SOCK_STREAM, 0);
+ if(connect(fd_angel, (struct sockaddr*) &addr, sizeof(addr)))
err(EX_IOERR, "Error connecting to angel at '%s'", addr.sun_path);
- return fd_control;
+ return fd_angel;
}
==== //depot/projects/trustedbsd/capabilities/src/tools/cap/user_angel/user_angel.c#3 (text+ko) ====
@@ -45,6 +45,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
#include "server.h"
@@ -59,18 +60,22 @@
void sighandle(int sig)
{
- fprintf(stderr, "Caught signal %i\n", sig);
-
switch(sig)
{
case SIGINT:
fprintf(stderr, "Caught SIGINT, shutting down...\n");
user_angel_server_shutdown();
- break;
+ exit(0);
+
+ case SIGSEGV:
+ fprintf(stderr, "Caught SIGSEGV, shutting down...\n");
+ user_angel_server_shutdown();
+ exit(EX_SOFTWARE);
default:
fprintf(stderr, "Unexpected signal %i; panic!\n", sig);
user_angel_server_shutdown();
+ exit(EX_SOFTWARE);
}
}
@@ -81,6 +86,7 @@
char *homedir = getenv("HOME");
signal(SIGINT, sighandle);
+ signal(SIGSEGV, sighandle);
if(strlen(homedir) >= 80)
{
More information about the p4-projects
mailing list