From 68c2b067e2ec1fb7ff1975e849da15c2d8f37d3a Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 25 Oct 2013 13:31:16 +0200 Subject: [PATCH] implement command line options using getopt --- Makefile | 4 +-- auth-pve.c | 12 +++++++ input.c | 6 ++-- screen.c | 35 ++++++++++++------- spiceterm.c | 97 ++++++++++++++++++++++++++++++++++++++++------------- spiceterm.h | 16 ++++++--- 6 files changed, 125 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index af66df6..128a8c5 100644 --- a/Makefile +++ b/Makefile @@ -14,8 +14,8 @@ spiceterm: ${SOURCES} ${HEADERS} spiceterm.c .PHONY: test test: spiceterm - #./spiceterm & remote-viewer spice://localhost:5912 - G_MESSAGES_DEBUG=all SPICE_DEBUG=1 ./spiceterm & G_MESSAGES_DEBUG=all SPICE_DEBUG=1 remote-viewer --debug 'spice://localhost?tls-port=5912' --spice-ca-file /etc/pve/pve-root-ca.pem --spice-secure-channels=all + #./spiceterm & remote-viewer spice://localhost:5900 + G_MESSAGES_DEBUG=all SPICE_DEBUG=1 SPICE_TICKET=test ./spiceterm & G_MESSAGES_DEBUG=all SPICE_DEBUG=1 remote-viewer --debug 'spice://localhost?tls-port=5900' --spice-ca-file /etc/pve/pve-root-ca.pem --spice-secure-channels=all .PHONY: distclean distclean: clean diff --git a/auth-pve.c b/auth-pve.c index 7dd5953..d41f8bd 100644 --- a/auth-pve.c +++ b/auth-pve.c @@ -10,6 +10,18 @@ static char *auth_path = "/"; static char *auth_perm = "Sys.Console"; +void +pve_auth_set_path(char *path) +{ + auth_path = path; +} + +void +pve_auth_set_permissions(char *perm) +{ + auth_perm = perm; +} + static char * urlencode(char *buf, const char *value) { diff --git a/input.c b/input.c index 30c9069..fdd6cfe 100644 --- a/input.c +++ b/input.c @@ -620,10 +620,10 @@ static SpiceCharDeviceInterface my_vdagent_sif = { }; spiceTerm * -create_spiceterm(int argc, char** argv, uint32_t maxx, uint32_t maxy, guint timeout) +spiceterm_create(uint32_t width, uint32_t height, SpiceTermOptions *opts) { SpiceCoreInterface *core = basic_event_loop_init(); - SpiceScreen *spice_screen = spice_screen_new(core, maxx, maxy, timeout); + SpiceScreen *spice_screen = spice_screen_new(core, width, height, opts); //spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF); @@ -639,7 +639,7 @@ create_spiceterm(int argc, char** argv, uint32_t maxx, uint32_t maxy, guint time spice_server_add_interface(spice_screen->server, &vt->vdagent_sin.base); vt->screen = spice_screen; - init_spiceterm(vt, maxx, maxy); + init_spiceterm(vt, width, height); return vt; } diff --git a/screen.c b/screen.c index b3b8eaf..ff42b38 100644 --- a/screen.c +++ b/screen.c @@ -752,9 +752,9 @@ static sasl_callback_t sasl_callbacks[] = { }; SpiceScreen * -spice_screen_new(SpiceCoreInterface *core, uint32_t width, uint32_t height, guint timeout) +spice_screen_new(SpiceCoreInterface *core, uint32_t width, uint32_t height, + SpiceTermOptions *opts) { - int port = 5912; SpiceScreen *spice_screen = g_new0(SpiceScreen, 1); SpiceServer* server = spice_server_new(); char *x509_key_file = "/etc/pve/local/pve-ssl.key"; @@ -764,8 +764,6 @@ spice_screen_new(SpiceCoreInterface *core, uint32_t width, uint32_t height, guin char *x509_dh_file = NULL; char *tls_ciphers = "DES-CBC3-SHA"; - gboolean use_auth = TRUE; - spice_screen->width = width; spice_screen->height = height; @@ -781,12 +779,17 @@ spice_screen_new(SpiceCoreInterface *core, uint32_t width, uint32_t height, guin spice_screen->core = core; spice_screen->server = server; - printf("listening on port %d (secure)\n", port); - // spice_server_set_addr(); + if (opts->addr) { + printf("listening on '%s:%d' (TLS)\n", opts->addr, opts->port); + spice_server_set_addr(server, opts->addr, 0); + } else { + printf("listening on '*:%d' (TLS)\n", opts->port); + } + // spice_server_set_port(spice_server, port); //spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF); - spice_server_set_tls(server, port, + spice_server_set_tls(server, opts->port, x509_cacert_file, x509_cert_file, x509_key_file, @@ -794,11 +797,19 @@ spice_screen_new(SpiceCoreInterface *core, uint32_t width, uint32_t height, guin x509_dh_file, tls_ciphers); - if (use_auth) { - spice_server_set_sasl(server, 1); - spice_server_set_sasl_callbacks(server, sasl_callbacks); - } else { + if (opts->noauth) { spice_server_set_noauth(server); + } else { + if (opts->sasl) { + spice_server_set_sasl(server, 1); + spice_server_set_sasl_appname(server, NULL); // enforce pve auth + spice_server_set_sasl_callbacks(server, sasl_callbacks); + } else { + char *ticket = getenv("SPICE_TICKET"); + if (ticket) { + spice_server_set_ticket(server, ticket, 300, 0, 0); + } + } } int res = spice_server_init(server, core); @@ -809,7 +820,7 @@ spice_screen_new(SpiceCoreInterface *core, uint32_t width, uint32_t height, guin cursor_init(); spice_screen->conn_timeout_timer = core->timer_add(do_conn_timeout, spice_screen); - spice_screen->core->timer_start(spice_screen->conn_timeout_timer, timeout*1000); + spice_screen->core->timer_start(spice_screen->conn_timeout_timer, opts->timeout*1000); spice_server_add_interface(spice_screen->server, &spice_screen->qxl_instance.base); diff --git a/spiceterm.c b/spiceterm.c index 8506790..5149bbf 100644 --- a/spiceterm.c +++ b/spiceterm.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "spiceterm.h" @@ -67,24 +68,11 @@ static int debug = 0; #define TERMIDCODE "[?1;2c" // vt100 ID -#define CHECK_ARGC(argc,argv,i) if (i >= argc-1) { \ - fprintf(stderr, "ERROR: not enough arguments for: %s\n", argv[i]); \ - print_usage(NULL); \ - exit(1); \ -} - /* these colours are from linux kernel drivers/char/vt.c */ unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, 8,12,10,14, 9,13,11,15 }; -static void -print_usage(const char *msg) -{ - if (msg) { fprintf(stderr, "ERROR: %s\n", msg); } - fprintf(stderr, "USAGE: spiceterm [spiceopts] [-c command [args]]\n"); -} - static void draw_char_at(spiceTerm *vt, int x, int y, gunichar2 ch, TextAttributes attrib) { @@ -1611,32 +1599,93 @@ master_watch(int master, int event, void *opaque) } } +static void +spiceterm_print_usage(const char *msg) +{ + if (msg) { + fprintf(stderr, "ERROR: %s\n", msg); + } + fprintf(stderr, "USAGE: spiceterm [OPTIONS] [-- command [args]]\n"); + fprintf(stderr, " --timeout Wait this time before aborting (default is 10 seconds)\n"); + fprintf(stderr, " --authpath Authentication path (PVE AUTH)\n"); + fprintf(stderr, " --permission Required permissions (PVE AUTH)\n"); + fprintf(stderr, " --port Bind to port \n"); + fprintf(stderr, " --addr Bind to address \n"); + fprintf(stderr, " --sasl Enable SASL based authentication\n"); + fprintf(stderr, " --noauth Disable authentication\n"); +} + int main (int argc, char** argv) { - int i; + int c; char **cmdargv = NULL; char *command = "/bin/bash"; // execute normal shell as default int pid; int master; char ptyname[1024]; struct winsize dimensions; + SpiceTermOptions opts = { + .timeout = 10, + .port = 5900, + .addr = NULL, + .noauth = FALSE, + .sasl = FALSE, + }; g_thread_init(NULL); - for (i = 1; i < argc; i++) { - if (!strcmp (argv[i], "-c")) { - command = argv[i+1]; - cmdargv = &argv[i+1]; - argc = i; - argv[i] = NULL; + static struct option long_options[] = { + { "timeout", required_argument, 0, 't' }, + { "authpath", required_argument, 0, 'A' }, + { "permissions", required_argument, 0, 'P' }, + { "port", required_argument, 0, 'p' }, + { "addr", required_argument, 0, 'a' }, + { "noauth", no_argument, 0, 'n' }, + { "sasl", no_argument, 0, 's' }, + { NULL, 0, 0, 0 }, + }; + + while ((c = getopt_long(argc, argv, "nst:a:p:P:", long_options, NULL)) != -1) { + + switch (c) { + case 'n': + opts.noauth = TRUE; + break; + case 's': + opts.sasl = TRUE; + break; + case 'A': + pve_auth_set_path(optarg); + break; + case 'P': + pve_auth_set_permissions(optarg); + break; + case 'p': + opts.port = atoi(optarg); + break; + case 'a': + opts.addr = optarg; + break; + case 't': + opts.timeout = atoi(optarg); break; + case '?': + spiceterm_print_usage(NULL); + exit(-1); + break; + default: + spiceterm_print_usage("getopt returned unknown character code"); + exit(-1); } } - - if (0) print_usage(NULL); // fixme: - - spiceTerm *vt = create_spiceterm (argc, argv, 744, 400, 10); + + if (optind < argc) { + command = argv[optind+1]; + cmdargv = &argv[optind+1]; + } + + spiceTerm *vt = spiceterm_create(744, 400, &opts); setlocale(LC_ALL, ""); // set from environment diff --git a/spiceterm.h b/spiceterm.h index 95c9b55..3df2ef8 100644 --- a/spiceterm.h +++ b/spiceterm.h @@ -24,6 +24,14 @@ typedef struct TextCell { #define MAX_HEIGHT 1440 #define MAX_WIDTH 2560 +typedef struct SpiceTermOptions { + guint timeout; + int port; + char *addr; + gboolean noauth; + gboolean sasl; +} SpiceTermOptions; + typedef struct SpiceScreen SpiceScreen; typedef struct CachedImage { @@ -66,7 +74,7 @@ struct SpiceScreen { void (*on_client_disconnected)(SpiceScreen *spice_screen); }; -SpiceScreen* spice_screen_new(SpiceCoreInterface* core, uint32_t width, uint32_t height, guint timeout); +SpiceScreen* spice_screen_new(SpiceCoreInterface* core, uint32_t width, uint32_t height, SpiceTermOptions *opts); void spice_screen_resize(SpiceScreen *spice_screen, uint32_t width, uint32_t height); void spice_screen_draw_char(SpiceScreen *spice_screen, int x, int y, gunichar2 ch, TextAttributes attrib); @@ -152,13 +160,13 @@ void spiceterm_respond_esc(spiceTerm *vt, const char *esc); void spiceterm_respond_data(spiceTerm *vt, int len, uint8_t *data); void spiceterm_update_watch_mask(spiceTerm *vt, gboolean writable); -spiceTerm *create_spiceterm(int argc, char** argv, uint32_t maxx, - uint32_t maxy, guint timeout); +spiceTerm *spiceterm_create(uint32_t width, uint32_t height, SpiceTermOptions *opts); gboolean vdagent_owns_clipboard(spiceTerm *vt); void vdagent_request_clipboard(spiceTerm *vt); void vdagent_grab_clipboard(spiceTerm *vt); int pve_auth_verify(const char *clientip, const char *username, const char *passwd); - +void pve_auth_set_path(char *path); +void pve_auth_set_permissions(char *perm); -- 2.39.2