]> git.proxmox.com Git - spiceterm.git/commitdiff
use new auth framework
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 17 Oct 2013 11:25:50 +0000 (13:25 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 17 Oct 2013 11:25:50 +0000 (13:25 +0200)
event_loop.c
input.c

index 1583a1884ae9e803de9174312fc38089402c6a4a..5235b87ce2acf75da38c3f7fe2796b1d94bd1532 100644 (file)
@@ -27,6 +27,9 @@
 #include <sys/time.h>
 #include <signal.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
 
 #include <glib.h>
 
@@ -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 6c512795e2e9bc884de4b4954335e0db8f544329..30c9069e705f5a06bf2c9d3b2450ed22ed3c9b21 100644 (file)
--- 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);