|
|
1.1 root 1: /*
2: * QEMU VNC display driver: VeNCrypt authentication setup
3: *
4: * Copyright (C) 2006 Anthony Liguori <[email protected]>
5: * Copyright (C) 2006 Fabrice Bellard
6: * Copyright (C) 2009 Red Hat, Inc
7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy
9: * of this software and associated documentation files (the "Software"), to deal
10: * in the Software without restriction, including without limitation the rights
11: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12: * copies of the Software, and to permit persons to whom the Software is
13: * furnished to do so, subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in
16: * all copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24: * THE SOFTWARE.
25: */
26:
27: #include "vnc.h"
28:
29:
30: static void start_auth_vencrypt_subauth(VncState *vs)
31: {
1.1.1.2 ! root 32: switch (vs->subauth) {
1.1 root 33: case VNC_AUTH_VENCRYPT_TLSNONE:
34: case VNC_AUTH_VENCRYPT_X509NONE:
35: VNC_DEBUG("Accept TLS auth none\n");
36: vnc_write_u32(vs, 0); /* Accept auth completion */
37: start_client_init(vs);
38: break;
39:
40: case VNC_AUTH_VENCRYPT_TLSVNC:
41: case VNC_AUTH_VENCRYPT_X509VNC:
42: VNC_DEBUG("Start TLS auth VNC\n");
43: start_auth_vnc(vs);
44: break;
45:
46: #ifdef CONFIG_VNC_SASL
47: case VNC_AUTH_VENCRYPT_TLSSASL:
48: case VNC_AUTH_VENCRYPT_X509SASL:
49: VNC_DEBUG("Start TLS auth SASL\n");
50: return start_auth_sasl(vs);
51: #endif /* CONFIG_VNC_SASL */
52:
53: default: /* Should not be possible, but just in case */
1.1.1.2 ! root 54: VNC_DEBUG("Reject subauth %d server bug\n", vs->auth);
1.1 root 55: vnc_write_u8(vs, 1);
56: if (vs->minor >= 8) {
57: static const char err[] = "Unsupported authentication type";
58: vnc_write_u32(vs, sizeof(err));
59: vnc_write(vs, err, sizeof(err));
60: }
61: vnc_client_error(vs);
62: }
63: }
64:
65: static void vnc_tls_handshake_io(void *opaque);
66:
67: static int vnc_start_vencrypt_handshake(struct VncState *vs) {
68: int ret;
69:
70: if ((ret = gnutls_handshake(vs->tls.session)) < 0) {
71: if (!gnutls_error_is_fatal(ret)) {
72: VNC_DEBUG("Handshake interrupted (blocking)\n");
73: if (!gnutls_record_get_direction(vs->tls.session))
74: qemu_set_fd_handler(vs->csock, vnc_tls_handshake_io, NULL, vs);
75: else
76: qemu_set_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, vs);
77: return 0;
78: }
79: VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
80: vnc_client_error(vs);
81: return -1;
82: }
83:
84: if (vs->vd->tls.x509verify) {
85: if (vnc_tls_validate_certificate(vs) < 0) {
86: VNC_DEBUG("Client verification failed\n");
87: vnc_client_error(vs);
88: return -1;
89: } else {
90: VNC_DEBUG("Client verification passed\n");
91: }
92: }
93:
94: VNC_DEBUG("Handshake done, switching to TLS data mode\n");
95: vs->tls.wiremode = VNC_WIREMODE_TLS;
96: qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
97:
98: start_auth_vencrypt_subauth(vs);
99:
100: return 0;
101: }
102:
103: static void vnc_tls_handshake_io(void *opaque) {
104: struct VncState *vs = (struct VncState *)opaque;
105:
106: VNC_DEBUG("Handshake IO continue\n");
107: vnc_start_vencrypt_handshake(vs);
108: }
109:
110:
111:
112: #define NEED_X509_AUTH(vs) \
1.1.1.2 ! root 113: ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
! 114: (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
! 115: (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN || \
! 116: (vs)->subauth == VNC_AUTH_VENCRYPT_X509SASL)
1.1 root 117:
118:
119: static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
120: {
121: int auth = read_u32(data, 0);
122:
1.1.1.2 ! root 123: if (auth != vs->subauth) {
1.1 root 124: VNC_DEBUG("Rejecting auth %d\n", auth);
125: vnc_write_u8(vs, 0); /* Reject auth */
126: vnc_flush(vs);
127: vnc_client_error(vs);
128: } else {
129: VNC_DEBUG("Accepting auth %d, setting up TLS for handshake\n", auth);
130: vnc_write_u8(vs, 1); /* Accept auth */
131: vnc_flush(vs);
132:
133: if (vnc_tls_client_setup(vs, NEED_X509_AUTH(vs)) < 0) {
134: VNC_DEBUG("Failed to setup TLS\n");
135: return 0;
136: }
137:
138: VNC_DEBUG("Start TLS VeNCrypt handshake process\n");
139: if (vnc_start_vencrypt_handshake(vs) < 0) {
140: VNC_DEBUG("Failed to start TLS handshake\n");
141: return 0;
142: }
143: }
144: return 0;
145: }
146:
147: static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
148: {
149: if (data[0] != 0 ||
150: data[1] != 2) {
151: VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
152: vnc_write_u8(vs, 1); /* Reject version */
153: vnc_flush(vs);
154: vnc_client_error(vs);
155: } else {
1.1.1.2 ! root 156: VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1.1 root 157: vnc_write_u8(vs, 0); /* Accept version */
158: vnc_write_u8(vs, 1); /* Number of sub-auths */
1.1.1.2 ! root 159: vnc_write_u32(vs, vs->subauth); /* The supported auth */
1.1 root 160: vnc_flush(vs);
161: vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
162: }
163: return 0;
164: }
165:
166:
167: void start_auth_vencrypt(VncState *vs)
168: {
169: /* Send VeNCrypt version 0.2 */
170: vnc_write_u8(vs, 0);
171: vnc_write_u8(vs, 2);
172:
173: vnc_read_when(vs, protocol_client_vencrypt_init, 2);
174: }
175:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.