From 12fe052c0947d5eae07274e98165f0dc6efce134 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 17 Oct 2013 13:25:50 +0200 Subject: [PATCH] use new auth framework --- event_loop.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++ input.c | 2 +- 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/event_loop.c b/event_loop.c index 1583a18..5235b87 100644 --- a/event_loop.c +++ b/event_loop.c @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include #include @@ -41,6 +44,10 @@ static int debug = 0; } \ } +static char *auth_path = "/"; +static char *auth_perm = "Sys.Console"; +static char clientip[INET6_ADDRSTRLEN]; + static GMainLoop *main_loop; static SpiceCoreInterface core; @@ -222,6 +229,131 @@ static void ignore_sigpipe(void) sigaction(SIGPIPE, &act, NULL); } +static char * +urlencode(char *buf, const char *value) +{ + static const char *hexchar = "0123456789abcdef"; + char *p = buf; + int i; + int l = strlen(value); + for (i = 0; i < l; i++) { + char c = value[i]; + if (('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + ('0' <= c && c <= '9')) { + *p++ = c; + } else if (c == 32) { + *p++ = '+'; + } else { + *p++ = '%'; + *p++ = hexchar[c >> 4]; + *p++ = hexchar[c & 15]; + } + } + *p = 0; + + return p; +} + +static int +pve_auth_verify(const char *clientip, const char *username, const char *passwd) +{ + struct sockaddr_in server; + + int sfd = socket(AF_INET, SOCK_STREAM, 0); + if (sfd == -1) { + perror("pve_auth_verify: socket failed"); + return -1; + } + + struct hostent *he; + if ((he = gethostbyname("localhost")) == NULL) { + fprintf(stderr, "pve_auth_verify: error resolving hostname\n"); + goto err; + } + + memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length); + server.sin_family = AF_INET; + server.sin_port = htons(85); + + if (connect(sfd, (struct sockaddr *)&server, sizeof(server))) { + perror("pve_auth_verify: error connecting to server"); + goto err; + } + + char buf[8192]; + char form[8192]; + + char *p = form; + p = urlencode(p, "username"); + *p++ = '='; + p = urlencode(p, username); + + *p++ = '&'; + p = urlencode(p, "password"); + *p++ = '='; + p = urlencode(p, passwd); + + *p++ = '&'; + p = urlencode(p, "path"); + *p++ = '='; + p = urlencode(p, auth_path); + + *p++ = '&'; + p = urlencode(p, "privs"); + *p++ = '='; + p = urlencode(p, auth_perm); + + sprintf(buf, "POST /api2/json/access/ticket HTTP/1.1\n" + "Host: localhost:85\n" + "Connection: close\n" + "PVEClientIP: %s\n" + "Content-Type: application/x-www-form-urlencoded\n" + "Content-Length: %zd\n\n%s\n", clientip, strlen(form), form); + ssize_t len = strlen(buf); + ssize_t sb = send(sfd, buf, len, 0); + if (sb < 0) { + perror("pve_auth_verify: send failed"); + goto err; + } + if (sb != len) { + fprintf(stderr, "pve_auth_verify: partial send error\n"); + goto err; + } + + len = recv(sfd, buf, sizeof(buf) - 1, 0); + if (len < 0) { + perror("pve_auth_verify: recv failed"); + goto err; + } + + buf[len] = 0; + + //printf("DATA:%s\n", buf); + + shutdown(sfd, SHUT_RDWR); + + if (!strncmp(buf, "HTTP/1.1 200 OK", 15)) { + return 0; + } + + char *firstline = strtok(buf, "\n"); + + fprintf(stderr, "auth failed: %s\n", firstline); + + return -1; + +err: + shutdown(sfd, SHUT_RDWR); + return -1; +} + +static int +verify_credentials(const char *username, const char *password) +{ + return pve_auth_verify(clientip, username, password); +} + SpiceCoreInterface *basic_event_loop_init(void) { main_loop = g_main_loop_new(NULL, FALSE); @@ -238,6 +370,8 @@ SpiceCoreInterface *basic_event_loop_init(void) core.watch_remove = watch_remove; core.channel_event = channel_event; + core.auth_plain_verify_credentials = verify_credentials; + ignore_sigpipe(); return &core; diff --git a/input.c b/input.c index 6c51279..30c9069 100644 --- a/input.c +++ b/input.c @@ -626,7 +626,7 @@ create_spiceterm(int argc, char** argv, uint32_t maxx, uint32_t maxy, guint time SpiceScreen *spice_screen = spice_screen_new(core, maxx, maxy, timeout); //spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF); - + spice_screen->image_cache = g_hash_table_new(g_int_hash, g_int_equal); spiceTerm *vt = (spiceTerm *)calloc (sizeof(spiceTerm), 1);