diff --git a/qubes-rpc/dvm2.h b/qubes-rpc/dvm2.h index 0e5922c..72b73f7 100644 --- a/qubes-rpc/dvm2.h +++ b/qubes-rpc/dvm2.h @@ -1,2 +1,3 @@ #define DVM_FILENAME_SIZE 256 #define DVM_SPOOL "/home/user/.dvmspool" +#define DVM_VIEW_ONLY_PREFIX "view-only-" diff --git a/qubes-rpc/qopen-in-vm.c b/qubes-rpc/qopen-in-vm.c index 8d2b24f..5e796a5 100644 --- a/qubes-rpc/qopen-in-vm.c +++ b/qubes-rpc/qopen-in-vm.c @@ -13,22 +13,27 @@ #include #include "dvm2.h" -void send_file(const char *fname) +void send_file(const char *fname, int view_only) { const char *base; - char sendbuf[DVM_FILENAME_SIZE]; + char sendbuf[DVM_FILENAME_SIZE] = {0}; + size_t sendbuf_size = DVM_FILENAME_SIZE; int fd = open(fname, O_RDONLY); if (fd < 0) gui_fatal("open %s", fname); + if (view_only) { + strncpy(sendbuf, DVM_VIEW_ONLY_PREFIX, sendbuf_size); + sendbuf_size -= strlen(DVM_VIEW_ONLY_PREFIX); + } base = rindex(fname, '/'); if (!base) base = fname; else base++; - if (strlen(base) >= DVM_FILENAME_SIZE) - base += strlen(base) - DVM_FILENAME_SIZE + 1; - strncpy(sendbuf,base,DVM_FILENAME_SIZE - 1); /* fills out with NULs */ - sendbuf[DVM_FILENAME_SIZE - 1] = '\0'; + if (strlen(base) >= sendbuf_size) + base += strlen(base) - sendbuf_size + 1; + strncat(sendbuf,base,sendbuf_size - 1); /* fills out with NULs */ + sendbuf[DVM_FILENAME_SIZE - 1] = '\0'; if (!write_all(1, sendbuf, DVM_FILENAME_SIZE)) gui_fatal("send filename to dispVM"); if (!copy_fd_all(1, fd)) @@ -114,7 +119,7 @@ int main(int argc, char ** argv) if (optind >= argc) gui_fatal("OpenInVM - no file given?"); fname = argv[optind]; - send_file(fname); + send_file(fname, view_only); if (!view_only) { recv_file(fname); } else { diff --git a/qubes-rpc/vm-file-editor.c b/qubes-rpc/vm-file-editor.c index 054fef3..45004e8 100644 --- a/qubes-rpc/vm-file-editor.c +++ b/qubes-rpc/vm-file-editor.c @@ -79,9 +79,10 @@ fail: exit(1); } -char *get_filename(void) +char *get_filename(int *view_only) { char buf[DVM_FILENAME_SIZE]; + char *fname = buf; static char *retname; int i; char *directory; @@ -100,13 +101,17 @@ char *get_filename(void) if (index(" !?\"#$%^&*()[]<>;`~|", buf[i])) buf[i]='_'; } - len = strlen(directory)+1+strlen(buf)+1; + if (strncmp(buf, DVM_VIEW_ONLY_PREFIX, strlen(DVM_VIEW_ONLY_PREFIX)) == 0) { + *view_only = 1; + fname += strlen(DVM_VIEW_ONLY_PREFIX); + } + len = strlen(directory)+1+strlen(fname)+1; retname = malloc(len); if (!retname) { fprintf(stderr, "Cannot allocate memory\n"); exit(1); } - snprintf(retname, len, "%s/%s", directory, buf); + snprintf(retname, len, "%s/%s", directory, fname); free(directory); return retname; } @@ -143,11 +148,16 @@ int main() { struct stat stat_pre, stat_post, session_stat; - char *filename = get_filename(); + int view_only = 0; + char *filename = get_filename(&view_only); int child, status, log_fd, null_fd; FILE *waiter_pidfile; copy_file_by_name(filename); + if (view_only) { + // mark file as read-only so applications will signal it to the user + chmod(filename, 0400); + } if (stat(filename, &stat_pre)) { perror("stat pre"); exit(1);