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