qvm-open-in-vm: mark file as read-only if opened with --view-only

This will cause most applications to disallow changing the file and also
add some visual indication about the view being read only. This will
avoid making the changes that would be discarded later.

QubesOS/qubes-issues#1118
This commit is contained in:
Marek Marczykowski-Górecki 2018-05-26 01:41:16 +02:00
parent ef557ca460
commit 42b1355957
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 27 additions and 11 deletions

View File

@ -1,2 +1,3 @@
#define DVM_FILENAME_SIZE 256
#define DVM_SPOOL "/home/user/.dvmspool"
#define DVM_VIEW_ONLY_PREFIX "view-only-"

View File

@ -13,22 +13,27 @@
#include <gui-fatal.h>
#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 {

View File

@ -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);