⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vnc.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
	if (NEED_X509_AUTH(vs)) {	    gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);	    if (!x509_cred) {		gnutls_deinit(vs->tls_session);		vs->tls_session = NULL;		vnc_client_error(vs);		return -1;	    }	    if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {		gnutls_deinit(vs->tls_session);		vs->tls_session = NULL;		gnutls_certificate_free_credentials(x509_cred);		vnc_client_error(vs);		return -1;	    }	    if (vs->x509verify) {		VNC_DEBUG("Requesting a client certificate\n");		gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);	    }	} else {	    gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();	    if (!anon_cred) {		gnutls_deinit(vs->tls_session);		vs->tls_session = NULL;		vnc_client_error(vs);		return -1;	    }	    if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {		gnutls_deinit(vs->tls_session);		vs->tls_session = NULL;		gnutls_anon_free_server_credentials(anon_cred);		vnc_client_error(vs);		return -1;	    }	}	gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);	gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);	gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);    }    VNC_DEBUG("Start TLS handshake process\n");    return vnc_continue_handshake(vs);}static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len){    int auth = read_u32(data, 0);    if (auth != vs->subauth) {	VNC_DEBUG("Rejecting auth %d\n", auth);	vnc_write_u8(vs, 0); /* Reject auth */	vnc_flush(vs);	vnc_client_error(vs);    } else {	VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);	vnc_write_u8(vs, 1); /* Accept auth */	vnc_flush(vs);	if (vnc_start_tls(vs) < 0) {	    VNC_DEBUG("Failed to complete TLS\n");	    return 0;	}	if (vs->wiremode == VNC_WIREMODE_TLS) {	    VNC_DEBUG("Starting VeNCrypt subauth\n");	    return start_auth_vencrypt_subauth(vs);	} else {	    VNC_DEBUG("TLS handshake blocked\n");	    return 0;	}    }    return 0;}static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len){    if (data[0] != 0 ||	data[1] != 2) {	VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);	vnc_write_u8(vs, 1); /* Reject version */	vnc_flush(vs);	vnc_client_error(vs);    } else {	VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);	vnc_write_u8(vs, 0); /* Accept version */	vnc_write_u8(vs, 1); /* Number of sub-auths */	vnc_write_u32(vs, vs->subauth); /* The supported auth */	vnc_flush(vs);	vnc_read_when(vs, protocol_client_vencrypt_auth, 4);    }    return 0;}static int start_auth_vencrypt(VncState *vs){    /* Send VeNCrypt version 0.2 */    vnc_write_u8(vs, 0);    vnc_write_u8(vs, 2);    vnc_read_when(vs, protocol_client_vencrypt_init, 2);    return 0;}#endif /* CONFIG_VNC_TLS */static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len){    /* We only advertise 1 auth scheme at a time, so client     * must pick the one we sent. Verify this */    if (data[0] != vs->auth) { /* Reject auth */       VNC_DEBUG("Reject auth %d\n", (int)data[0]);       vnc_write_u32(vs, 1);       if (vs->minor >= 8) {           static const char err[] = "Authentication failed";           vnc_write_u32(vs, sizeof(err));           vnc_write(vs, err, sizeof(err));       }       vnc_client_error(vs);    } else { /* Accept requested auth */       VNC_DEBUG("Client requested auth %d\n", (int)data[0]);       switch (vs->auth) {       case VNC_AUTH_NONE:           VNC_DEBUG("Accept auth none\n");           if (vs->minor >= 8) {               vnc_write_u32(vs, 0); /* Accept auth completion */               vnc_flush(vs);           }           vnc_read_when(vs, protocol_client_init, 1);           break;       case VNC_AUTH_VNC:           VNC_DEBUG("Start VNC auth\n");           return start_auth_vnc(vs);#if CONFIG_VNC_TLS       case VNC_AUTH_VENCRYPT:           VNC_DEBUG("Accept VeNCrypt auth\n");;           return start_auth_vencrypt(vs);#endif /* CONFIG_VNC_TLS */       default: /* Should not be possible, but just in case */           VNC_DEBUG("Reject auth %d\n", vs->auth);           vnc_write_u8(vs, 1);           if (vs->minor >= 8) {               static const char err[] = "Authentication failed";               vnc_write_u32(vs, sizeof(err));               vnc_write(vs, err, sizeof(err));           }           vnc_client_error(vs);       }    }    return 0;}static int protocol_version(VncState *vs, uint8_t *version, size_t len){    char local[13];    memcpy(local, version, 12);    local[12] = 0;    if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {	VNC_DEBUG("Malformed protocol version %s\n", local);	vnc_client_error(vs);	return 0;    }    VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);    if (vs->major != 3 ||	(vs->minor != 3 &&	 vs->minor != 4 &&	 vs->minor != 5 &&	 vs->minor != 7 &&	 vs->minor != 8)) {	VNC_DEBUG("Unsupported client version\n");	vnc_write_u32(vs, VNC_AUTH_INVALID);	vnc_flush(vs);	vnc_client_error(vs);	return 0;    }    /* Some broken clients report v3.4 or v3.5, which spec requires to be treated     * as equivalent to v3.3 by servers     */    if (vs->minor == 4 || vs->minor == 5)	vs->minor = 3;    if (vs->minor == 3) {	if (vs->auth == VNC_AUTH_NONE) {            VNC_DEBUG("Tell client auth none\n");            vnc_write_u32(vs, vs->auth);            vnc_flush(vs);            vnc_read_when(vs, protocol_client_init, 1);       } else if (vs->auth == VNC_AUTH_VNC) {            VNC_DEBUG("Tell client VNC auth\n");            vnc_write_u32(vs, vs->auth);            vnc_flush(vs);            start_auth_vnc(vs);       } else {            VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);            vnc_write_u32(vs, VNC_AUTH_INVALID);            vnc_flush(vs);            vnc_client_error(vs);       }    } else {	VNC_DEBUG("Telling client we support auth %d\n", vs->auth);	vnc_write_u8(vs, 1); /* num auth */	vnc_write_u8(vs, vs->auth);	vnc_read_when(vs, protocol_client_auth, 1);	vnc_flush(vs);    }    return 0;}static void vnc_listen_read(void *opaque){    VncState *vs = opaque;    struct sockaddr_in addr;    socklen_t addrlen = sizeof(addr);    vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);    if (vs->csock != -1) {	VNC_DEBUG("New client on socket %d\n", vs->csock);        socket_set_nonblock(vs->csock);	qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);	vnc_write(vs, "RFB 003.008\n", 12);	vnc_flush(vs);	vnc_read_when(vs, protocol_version, 12);	memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);	memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));	vs->has_resize = 0;	vs->has_hextile = 0;	vs->ds->dpy_copy = NULL;    }}extern int parse_host_port(struct sockaddr_in *saddr, const char *str);void vnc_display_init(DisplayState *ds){    VncState *vs;    vs = qemu_mallocz(sizeof(VncState));    if (!vs)	exit(1);    ds->opaque = vs;    vnc_state = vs;    vs->display = NULL;    vs->password = NULL;    vs->lsock = -1;    vs->csock = -1;    vs->depth = 4;    vs->last_x = -1;    vs->last_y = -1;    vs->ds = ds;    if (!keyboard_layout)	keyboard_layout = "en-us";    vs->kbd_layout = init_keyboard_layout(keyboard_layout);    if (!vs->kbd_layout)	exit(1);    vs->ds->data = NULL;    vs->ds->dpy_update = vnc_dpy_update;    vs->ds->dpy_resize = vnc_dpy_resize;    vs->ds->dpy_refresh = vnc_dpy_refresh;    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));    vnc_dpy_resize(vs->ds, 640, 400);}#if CONFIG_VNC_TLSstatic int vnc_set_x509_credential(VncState *vs,				   const char *certdir,				   const char *filename,				   char **cred,				   int ignoreMissing){    struct stat sb;    if (*cred) {	qemu_free(*cred);	*cred = NULL;    }    if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))	return -1;    strcpy(*cred, certdir);    strcat(*cred, "/");    strcat(*cred, filename);    VNC_DEBUG("Check %s\n", *cred);    if (stat(*cred, &sb) < 0) {	qemu_free(*cred);	*cred = NULL;	if (ignoreMissing && errno == ENOENT)	    return 0;	return -1;    }    return 0;}static int vnc_set_x509_credential_dir(VncState *vs,				       const char *certdir){    if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)	goto cleanup;    if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)	goto cleanup;    if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)	goto cleanup;    if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)	goto cleanup;    return 0; cleanup:    qemu_free(vs->x509cacert);    qemu_free(vs->x509cacrl);    qemu_free(vs->x509cert);    qemu_free(vs->x509key);    vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;    return -1;}#endif /* CONFIG_VNC_TLS */void vnc_display_close(DisplayState *ds){    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;    if (vs->display) {	qemu_free(vs->display);	vs->display = NULL;    }    if (vs->lsock != -1) {	qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);	close(vs->lsock);	vs->lsock = -1;    }    if (vs->csock != -1) {	qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);	closesocket(vs->csock);	vs->csock = -1;	buffer_reset(&vs->input);	buffer_reset(&vs->output);	vs->need_update = 0;#if CONFIG_VNC_TLS	if (vs->tls_session) {	    gnutls_deinit(vs->tls_session);	    vs->tls_session = NULL;	}	vs->wiremode = VNC_WIREMODE_CLEAR;#endif /* CONFIG_VNC_TLS */    }    vs->auth = VNC_AUTH_INVALID;#if CONFIG_VNC_TLS    vs->subauth = VNC_AUTH_INVALID;    vs->x509verify = 0;#endif}int vnc_display_password(DisplayState *ds, const char *password){    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;    if (vs->password) {	qemu_free(vs->password);	vs->password = NULL;    }    if (password && password[0]) {	if (!(vs->password = qemu_strdup(password)))	    return -1;    }    return 0;}int vnc_display_open(DisplayState *ds, const char *display){    struct sockaddr *addr;    struct sockaddr_in iaddr;#ifndef _WIN32    struct sockaddr_un uaddr;#endif    int reuse_addr, ret;    socklen_t addrlen;    const char *p;    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;    const char *options;    int password = 0;#if CONFIG_VNC_TLS    int tls = 0, x509 = 0;#endif    vnc_display_close(ds);    if (strcmp(display, "none") == 0)	return 0;    if (!(vs->display = strdup(display)))	return -1;    options = display;    while ((options = strchr(options, ','))) {	options++;	if (strncmp(options, "password", 8) == 0) {	    password = 1; /* Require password auth */#if CONFIG_VNC_TLS	} else if (strncmp(options, "tls", 3) == 0) {	    tls = 1; /* Require TLS */	} else if (strncmp(options, "x509", 4) == 0) {	    char *start, *end;	    x509 = 1; /* Require x509 certificates */	    if (strncmp(options, "x509verify", 10) == 0)	        vs->x509verify = 1; /* ...and verify client certs */	    /* Now check for 'x509=/some/path' postfix	     * and use that to setup x509 certificate/key paths */	    start = strchr(options, '=');	    end = strchr(options, ',');	    if (start && (!end || (start < end))) {		int len = end ? end-(start+1) : strlen(start+1);		char *path = qemu_malloc(len+1);		strncpy(path, start+1, len);		path[len] = '\0';		VNC_DEBUG("Trying certificate path '%s'\n", path);		if (vnc_set_x509_credential_dir(vs, path) < 0) {		    fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);		    qemu_free(path);		    qemu_free(vs->display);		    vs->display = NULL;		    return -1;		}		qemu_free(path);	    } else {		fprintf(stderr, "No certificate path provided\n");		qemu_free(vs->display);		vs->display = NULL;		return -1;	    }#endif	}    }    if (password) {#if CONFIG_VNC_TLS	if (tls) {	    vs->auth = VNC_AUTH_VENCRYPT;	    if (x509) {		VNC_DEBUG("Initializing VNC server with x509 password auth\n");		vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;	    } else {		VNC_DEBUG("Initializing VNC server with TLS password auth\n");		vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;	    }	} else {#endif	    VNC_DEBUG("Initializing VNC server with password auth\n");	    vs->auth = VNC_AUTH_VNC;#if CONFIG_VNC_TLS	    vs->subauth = VNC_AUTH_INVALID;	}#endif    } else {#if CONFIG_VNC_TLS	if (tls) {	    vs->auth = VNC_AUTH_VENCRYPT;	    if (x509) {		VNC_DEBUG("Initializing VNC server with x509 no auth\n");		vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;	    } else {		VNC_DEBUG("Initializing VNC server with TLS no auth\n");		vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;	    }	} else {#endif	    VNC_DEBUG("Initializing VNC server with no auth\n");	    vs->auth = VNC_AUTH_NONE;#if CONFIG_VNC_TLS	    vs->subauth = VNC_AUTH_INVALID;	}#endif    }#ifndef _WIN32    if (strstart(display, "unix:", &p)) {	addr = (struct sockaddr *)&uaddr;	addrlen = sizeof(uaddr);	vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);	if (vs->lsock == -1) {	    fprintf(stderr, "Could not create socket\n");	    free(vs->display);	    vs->display = NULL;	    return -1;	}	uaddr.sun_family = AF_UNIX;	memset(uaddr.sun_path, 0, 108);	snprintf(uaddr.sun_path, 108, "%s", p);	unlink(uaddr.sun_path);    } else#endif    {	addr = (struct sockaddr *)&iaddr;	addrlen = sizeof(iaddr);	if (parse_host_port(&iaddr, display) < 0) {	    fprintf(stderr, "Could not parse VNC address\n");	    free(vs->display);	    vs->display = NULL;	    return -1;	}	iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);	vs->lsock = socket(PF_INET, SOCK_STREAM, 0);	if (vs->lsock == -1) {	    fprintf(stderr, "Could not create socket\n");	    free(vs->display);	    vs->display = NULL;	    return -1;	}	reuse_addr = 1;	ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,			 (const char *)&reuse_addr, sizeof(reuse_addr));	if (ret == -1) {	    fprintf(stderr, "setsockopt() failed\n");	    close(vs->lsock);	    vs->lsock = -1;	    free(vs->display);	    vs->display = NULL;	    return -1;	}    }    if (bind(vs->lsock, addr, addrlen) == -1) {	fprintf(stderr, "bind() failed\n");	close(vs->lsock);	vs->lsock = -1;	free(vs->display);	vs->display = NULL;	return -1;    }    if (listen(vs->lsock, 1) == -1) {	fprintf(stderr, "listen() failed\n");	close(vs->lsock);	vs->lsock = -1;	free(vs->display);	vs->display = NULL;	return -1;    }    return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -