]> git.proxmox.com Git - spiceterm.git/blame - auth-pve.c
use SASL for auth, always use TLS
[spiceterm.git] / auth-pve.c
CommitLineData
1631c5a9
DM
1#include <stdlib.h>
2#include <stdio.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <netdb.h>
7
8#include "spiceterm.h"
9
10static char *auth_path = "/";
11static char *auth_perm = "Sys.Console";
12
13static char *
14urlencode(char *buf, const char *value)
15{
16 static const char *hexchar = "0123456789abcdef";
17 char *p = buf;
18 int i;
19 int l = strlen(value);
20 for (i = 0; i < l; i++) {
21 char c = value[i];
22 if (('a' <= c && c <= 'z') ||
23 ('A' <= c && c <= 'Z') ||
24 ('0' <= c && c <= '9')) {
25 *p++ = c;
26 } else if (c == 32) {
27 *p++ = '+';
28 } else {
29 *p++ = '%';
30 *p++ = hexchar[c >> 4];
31 *p++ = hexchar[c & 15];
32 }
33 }
34 *p = 0;
35
36 return p;
37}
38
39int
40pve_auth_verify(const char *clientip, const char *username, const char *passwd)
41{
42 struct sockaddr_in server;
43
44 int sfd = socket(AF_INET, SOCK_STREAM, 0);
45 if (sfd == -1) {
46 perror("pve_auth_verify: socket failed");
47 return -1;
48 }
49
50 struct hostent *he;
51 if ((he = gethostbyname("localhost")) == NULL) {
52 fprintf(stderr, "pve_auth_verify: error resolving hostname\n");
53 goto err;
54 }
55
56 memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
57 server.sin_family = AF_INET;
58 server.sin_port = htons(85);
59
60 if (connect(sfd, (struct sockaddr *)&server, sizeof(server))) {
61 perror("pve_auth_verify: error connecting to server");
62 goto err;
63 }
64
65 char buf[8192];
66 char form[8192];
67
68 char *p = form;
69 p = urlencode(p, "username");
70 *p++ = '=';
71 p = urlencode(p, username);
72
73 *p++ = '&';
74 p = urlencode(p, "password");
75 *p++ = '=';
76 p = urlencode(p, passwd);
77
78 *p++ = '&';
79 p = urlencode(p, "path");
80 *p++ = '=';
81 p = urlencode(p, auth_path);
82
83 *p++ = '&';
84 p = urlencode(p, "privs");
85 *p++ = '=';
86 p = urlencode(p, auth_perm);
87
88 sprintf(buf, "POST /api2/json/access/ticket HTTP/1.1\n"
89 "Host: localhost:85\n"
90 "Connection: close\n"
91 "PVEClientIP: %s\n"
92 "Content-Type: application/x-www-form-urlencoded\n"
93 "Content-Length: %zd\n\n%s\n", clientip, strlen(form), form);
94 ssize_t len = strlen(buf);
95 ssize_t sb = send(sfd, buf, len, 0);
96 if (sb < 0) {
97 perror("pve_auth_verify: send failed");
98 goto err;
99 }
100 if (sb != len) {
101 fprintf(stderr, "pve_auth_verify: partial send error\n");
102 goto err;
103 }
104
105 len = recv(sfd, buf, sizeof(buf) - 1, 0);
106 if (len < 0) {
107 perror("pve_auth_verify: recv failed");
108 goto err;
109 }
110
111 buf[len] = 0;
112
113 //printf("DATA:%s\n", buf);
114
115 shutdown(sfd, SHUT_RDWR);
116
117 if (!strncmp(buf, "HTTP/1.1 200 OK", 15)) {
118 return 0;
119 }
120
121 char *firstline = strtok(buf, "\n");
122
123 fprintf(stderr, "auth failed: %s\n", firstline);
124
125 return -1;
126
127err:
128 shutdown(sfd, SHUT_RDWR);
129 return -1;
130}