]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/old/pve-auth.patch
bump version to 2.9.0-1~rc2+5
[pve-qemu-kvm.git] / debian / patches / old / pve-auth.patch
1 Index: new/qemu-options.hx
2 ===================================================================
3 --- new.orig/qemu-options.hx 2014-11-20 06:45:06.000000000 +0100
4 +++ new/qemu-options.hx 2014-11-20 06:50:44.000000000 +0100
5 @@ -411,6 +411,9 @@
6 @table @option
7 ETEXI
8
9 +DEF("id", HAS_ARG, QEMU_OPTION_id,
10 + "-id n set the VMID\n", QEMU_ARCH_ALL)
11 +
12 DEF("fda", HAS_ARG, QEMU_OPTION_fda,
13 "-fda/-fdb file use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
14 DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
15 Index: new/vl.c
16 ===================================================================
17 --- new.orig/vl.c 2014-11-20 06:45:06.000000000 +0100
18 +++ new/vl.c 2014-11-20 06:50:44.000000000 +0100
19 @@ -2730,6 +2730,7 @@
20 int main(int argc, char **argv, char **envp)
21 {
22 int i;
23 + long int vm_id_long = 0;
24 int snapshot, linux_boot;
25 const char *initrd_filename;
26 const char *kernel_filename, *kernel_cmdline;
27 @@ -3477,6 +3478,14 @@
28 exit(1);
29 }
30 break;
31 + case QEMU_OPTION_id:
32 + vm_id_long = strtol(optarg, (char **) &optarg, 10);
33 + if (*optarg != 0 || vm_id_long < 100 || vm_id_long > INT_MAX) {
34 + fprintf(stderr, "Invalid ID\n");
35 + exit(1);
36 + }
37 + pve_auth_setup(vm_id_long);
38 + break;
39 case QEMU_OPTION_vnc:
40 {
41 #ifdef CONFIG_VNC
42 Index: new/include/ui/console.h
43 ===================================================================
44 --- new.orig/include/ui/console.h 2014-11-20 06:45:06.000000000 +0100
45 +++ new/include/ui/console.h 2014-11-20 06:50:55.000000000 +0100
46 @@ -328,6 +328,7 @@
47 void cocoa_display_init(DisplayState *ds, int full_screen);
48
49 /* vnc.c */
50 +void pve_auth_setup(int vmid);
51 void vnc_display_init(const char *id);
52 void vnc_display_open(const char *id, Error **errp);
53 void vnc_display_add_client(const char *id, int csock, bool skipauth);
54 Index: new/ui/vnc.c
55 ===================================================================
56 --- new.orig/ui/vnc.c 2014-11-20 06:50:51.000000000 +0100
57 +++ new/ui/vnc.c 2014-11-20 06:50:55.000000000 +0100
58 @@ -48,6 +48,125 @@
59 #include "vnc_keysym.h"
60 #include "crypto/cipher.h"
61
62 +static int pve_vmid = 0;
63 +
64 +void pve_auth_setup(int vmid) {
65 + pve_vmid = vmid;
66 +}
67 +
68 +static char *
69 +urlencode(char *buf, const char *value)
70 +{
71 + static const char *hexchar = "0123456789abcdef";
72 + char *p = buf;
73 + int i;
74 + int l = strlen(value);
75 + for (i = 0; i < l; i++) {
76 + char c = value[i];
77 + if (('a' <= c && c <= 'z') ||
78 + ('A' <= c && c <= 'Z') ||
79 + ('0' <= c && c <= '9')) {
80 + *p++ = c;
81 + } else if (c == 32) {
82 + *p++ = '+';
83 + } else {
84 + *p++ = '%';
85 + *p++ = hexchar[c >> 4];
86 + *p++ = hexchar[c & 15];
87 + }
88 + }
89 + *p = 0;
90 +
91 + return p;
92 +}
93 +
94 +int
95 +pve_auth_verify(const char *clientip, const char *username, const char *passwd)
96 +{
97 + struct sockaddr_in server;
98 +
99 + int sfd = socket(AF_INET, SOCK_STREAM, 0);
100 + if (sfd == -1) {
101 + perror("pve_auth_verify: socket failed");
102 + return -1;
103 + }
104 +
105 + struct hostent *he;
106 + if ((he = gethostbyname("localhost")) == NULL) {
107 + fprintf(stderr, "pve_auth_verify: error resolving hostname\n");
108 + goto err;
109 + }
110 +
111 + memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
112 + server.sin_family = AF_INET;
113 + server.sin_port = htons(85);
114 +
115 + if (connect(sfd, (struct sockaddr *)&server, sizeof(server))) {
116 + perror("pve_auth_verify: error connecting to server");
117 + goto err;
118 + }
119 +
120 + char buf[8192];
121 + char form[8192];
122 +
123 + char *p = form;
124 + p = urlencode(p, "username");
125 + *p++ = '=';
126 + p = urlencode(p, username);
127 +
128 + *p++ = '&';
129 + p = urlencode(p, "password");
130 + *p++ = '=';
131 + p = urlencode(p, passwd);
132 +
133 + *p++ = '&';
134 + p = urlencode(p, "path");
135 + *p++ = '=';
136 + char authpath[256];
137 + sprintf(authpath, "/vms/%d", pve_vmid);
138 + p = urlencode(p, authpath);
139 +
140 + *p++ = '&';
141 + p = urlencode(p, "privs");
142 + *p++ = '=';
143 + p = urlencode(p, "VM.Console");
144 +
145 + sprintf(buf, "POST /api2/json/access/ticket HTTP/1.1\n"
146 + "Host: localhost:85\n"
147 + "Connection: close\n"
148 + "PVEClientIP: %s\n"
149 + "Content-Type: application/x-www-form-urlencoded\n"
150 + "Content-Length: %zd\n\n%s\n", clientip, strlen(form), form);
151 + ssize_t len = strlen(buf);
152 + ssize_t sb = send(sfd, buf, len, 0);
153 + if (sb < 0) {
154 + perror("pve_auth_verify: send failed");
155 + goto err;
156 + }
157 + if (sb != len) {
158 + fprintf(stderr, "pve_auth_verify: partial send error\n");
159 + goto err;
160 + }
161 +
162 + len = recv(sfd, buf, sizeof(buf) - 1, 0);
163 + if (len < 0) {
164 + perror("pve_auth_verify: recv failed");
165 + goto err;
166 + }
167 +
168 + buf[len] = 0;
169 +
170 + //printf("DATA:%s\n", buf);
171 +
172 + shutdown(sfd, SHUT_RDWR);
173 +
174 + return strncmp(buf, "HTTP/1.1 200 OK", 15);
175 +
176 +err:
177 + shutdown(sfd, SHUT_RDWR);
178 + return -1;
179 +}
180 +
181 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
182 QTAILQ_HEAD_INITIALIZER(vnc_displays);
183
184 @@ -3393,10 +3512,10 @@
185 }
186 if (x509) {
187 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
188 - vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
189 + vs->subauth = VNC_AUTH_VENCRYPT_X509PLAIN;
190 } else {
191 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
192 - vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
193 + vs->subauth = VNC_AUTH_VENCRYPT_TLSPLAIN;
194 }
195 } else {
196 VNC_DEBUG("Initializing VNC server with password auth\n");
197 @@ -3557,7 +3676,14 @@
198 vs->tls.x509verify = true;
199 }
200 }
201 - if (path) {
202 + if (path && strcmp(path, "on") == 0) {
203 + x509 = true;
204 + tls = true;
205 + if (pve_tls_set_x509_creds_dir(vs) < 0) {
206 + error_setg(errp, "No certificate path provided");
207 + goto fail;
208 + }
209 + } else if (path) {
210 x509 = true;
211 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
212 error_setg(errp, "Failed to find x509 certificates/keys in %s",
213 Index: new/ui/vnc-auth-vencrypt.c
214 ===================================================================
215 --- new.orig/ui/vnc-auth-vencrypt.c 2014-11-20 06:45:06.000000000 +0100
216 +++ new/ui/vnc-auth-vencrypt.c 2014-11-20 06:50:55.000000000 +0100
217 @@ -26,6 +26,107 @@
218
219 #include "vnc.h"
220 #include "qemu/main-loop.h"
221 +#include "qemu/sockets.h"
222 +
223 +static int protocol_client_auth_plain(VncState *vs, uint8_t *data, size_t len)
224 +{
225 + const char *err = NULL;
226 + char username[256];
227 + char passwd[512];
228 +
229 + char clientip[256];
230 + clientip[0] = 0;
231 + struct sockaddr_in client;
232 + socklen_t addrlen = sizeof(client);
233 + if (getpeername(vs->csock, &client, &addrlen) == 0) {
234 + inet_ntop(client.sin_family, &client.sin_addr,
235 + clientip, sizeof(clientip));
236 + }
237 +
238 + if ((len != (vs->username_len + vs->password_len)) ||
239 + (vs->username_len >= (sizeof(username)-1)) ||
240 + (vs->password_len >= (sizeof(passwd)-1)) ) {
241 + err = "Got unexpected data length";
242 + goto err;
243 + }
244 +
245 + strncpy(username, (char *)data, vs->username_len);
246 + username[vs->username_len] = 0;
247 + strncpy(passwd, (char *)data + vs->username_len, vs->password_len);
248 + passwd[vs->password_len] = 0;
249 +
250 + VNC_DEBUG("AUTH PLAIN username: %s pw: %s\n", username, passwd);
251 +
252 + if (pve_auth_verify(clientip, username, passwd) == 0) {
253 + vnc_write_u32(vs, 0); /* Accept auth completion */
254 + start_client_init(vs);
255 + return 0;
256 + }
257 +
258 + err = "Authentication failed";
259 +err:
260 + if (err) {
261 + VNC_DEBUG("AUTH PLAIN ERROR: %s\n", err);
262 + vnc_write_u32(vs, 1); /* Reject auth */
263 + if (vs->minor >= 8) {
264 + int elen = strlen(err);
265 + vnc_write_u32(vs, elen);
266 + vnc_write(vs, err, elen);
267 + }
268 + }
269 + vnc_flush(vs);
270 + vnc_client_error(vs);
271 +
272 + return 0;
273 +
274 +}
275 +
276 +static int protocol_client_auth_plain_start(VncState *vs, uint8_t *data, size_t len)
277 +{
278 + uint32_t ulen = read_u32(data, 0);
279 + uint32_t pwlen = read_u32(data, 4);
280 + const char *err = NULL;
281 +
282 + VNC_DEBUG("AUTH PLAIN START %u %u\n", ulen, pwlen);
283 +
284 + if (!ulen) {
285 + err = "No User name.";
286 + goto err;
287 + }
288 + if (ulen >= 255) {
289 + err = "User name too long.";
290 + goto err;
291 + }
292 + if (!pwlen) {
293 + err = "Password too short";
294 + goto err;
295 + }
296 + if (pwlen >= 511) {
297 + err = "Password too long.";
298 + goto err;
299 + }
300 +
301 + vs->username_len = ulen;
302 + vs->password_len = pwlen;
303 +
304 + vnc_read_when(vs, protocol_client_auth_plain, ulen + pwlen);
305 +
306 + return 0;
307 +err:
308 + if (err) {
309 + VNC_DEBUG("AUTH PLAIN ERROR: %s\n", err);
310 + vnc_write_u32(vs, 1); /* Reject auth */
311 + if (vs->minor >= 8) {
312 + int elen = strlen(err);
313 + vnc_write_u32(vs, elen);
314 + vnc_write(vs, err, elen);
315 + }
316 + }
317 + vnc_flush(vs);
318 + vnc_client_error(vs);
319 +
320 + return 0;
321 +}
322
323 static void start_auth_vencrypt_subauth(VncState *vs)
324 {
325 @@ -37,6 +138,12 @@
326 start_client_init(vs);
327 break;
328
329 + case VNC_AUTH_VENCRYPT_TLSPLAIN:
330 + case VNC_AUTH_VENCRYPT_X509PLAIN:
331 + VNC_DEBUG("Start TLS auth PLAIN\n");
332 + vnc_read_when(vs, protocol_client_auth_plain_start, 8);
333 + break;
334 +
335 case VNC_AUTH_VENCRYPT_TLSVNC:
336 case VNC_AUTH_VENCRYPT_X509VNC:
337 VNC_DEBUG("Start TLS auth VNC\n");
338 Index: new/ui/vnc.h
339 ===================================================================
340 --- new.orig/ui/vnc.h 2014-11-20 06:45:06.000000000 +0100
341 +++ new/ui/vnc.h 2014-11-20 06:50:55.000000000 +0100
342 @@ -288,6 +288,8 @@
343 int auth;
344 int subauth; /* Used by VeNCrypt */
345 char challenge[VNC_AUTH_CHALLENGE_SIZE];
346 + int username_len;
347 + int password_len;
348 #ifdef CONFIG_VNC_TLS
349 VncStateTLS tls;
350 #endif
351 @@ -603,4 +605,6 @@
352 int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
353 void vnc_zrle_clear(VncState *vs);
354
355 +int pve_auth_verify(const char *clientip, const char *username, const char *passwd);
356 +
357 #endif /* __QEMU_VNC_H */
358 Index: new/ui/vnc-tls.c
359 ===================================================================
360 --- new.orig/ui/vnc-tls.c 2014-11-20 06:45:06.000000000 +0100
361 +++ new/ui/vnc-tls.c 2014-11-20 06:50:55.000000000 +0100
362 @@ -302,6 +302,14 @@
363
364 static int vnc_set_gnutls_priority(gnutls_session_t s, int x509)
365 {
366 + /* optimize for speed */
367 + static const int ciphers[] = {
368 + GNUTLS_CIPHER_ARCFOUR_128,
369 + GNUTLS_CIPHER_AES_128_CBC,
370 + GNUTLS_CIPHER_3DES_CBC,
371 + 0
372 + };
373 +
374 static const int cert_types[] = { GNUTLS_CRT_X509, 0 };
375 static const int protocols[] = {
376 GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0
377 @@ -313,6 +321,11 @@
378 };
379 int rc;
380
381 + rc = gnutls_cipher_set_priority(s, ciphers);
382 + if (rc != GNUTLS_E_SUCCESS) {
383 + return -1;
384 + }
385 +
386 rc = gnutls_kx_set_priority(s, x509 ? kx_x509 : kx_anon);
387 if (rc != GNUTLS_E_SUCCESS) {
388 return -1;
389 @@ -448,6 +460,24 @@
390 return 0;
391 }
392
393 +int pve_tls_set_x509_creds_dir(VncDisplay *vd)
394 +{
395 + if (vnc_set_x509_credential(vd, "/etc/pve", "pve-root-ca.pem", &vd->tls.x509cacert, 0) < 0)
396 + goto cleanup;
397 + if (vnc_set_x509_credential(vd, "/etc/pve/local", "pve-ssl.pem", &vd->tls.x509cert, 0) < 0)
398 + goto cleanup;
399 + if (vnc_set_x509_credential(vd, "/etc/pve/local", "pve-ssl.key", &vd->tls.x509key, 0) < 0)
400 + goto cleanup;
401 +
402 + return 0;
403 +
404 + cleanup:
405 + g_free(vd->tls.x509cacert);
406 + g_free(vd->tls.x509cert);
407 + g_free(vd->tls.x509key);
408 + vd->tls.x509cacert = vd->tls.x509cacrl = vd->tls.x509cert = vd->tls.x509key = NULL;
409 + return -1;
410 +}
411
412 int vnc_tls_set_x509_creds_dir(VncDisplay *vd,
413 const char *certdir)
414 Index: new/ui/vnc-tls.h
415 ===================================================================
416 --- new.orig/ui/vnc-tls.h 2014-11-20 06:45:06.000000000 +0100
417 +++ new/ui/vnc-tls.h 2014-11-20 06:50:55.000000000 +0100
418 @@ -61,6 +61,8 @@
419
420 int vnc_tls_validate_certificate(VncState *vs);
421
422 +int pve_tls_set_x509_creds_dir(VncDisplay *vd);
423 +
424 int vnc_tls_set_x509_creds_dir(VncDisplay *vd,
425 const char *path);
426