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

📄 vnc.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
    }    if (bits_per_pixel == 32 &&        host_big_endian_flag == big_endian_flag &&        red_max == 0xff && green_max == 0xff && blue_max == 0xff &&        red_shift == 16 && green_shift == 8 && blue_shift == 0) {        vs->depth = 4;        vs->write_pixels = vnc_write_pixels_copy;        vs->send_hextile_tile = send_hextile_tile_32;    } else    if (bits_per_pixel == 16 &&        host_big_endian_flag == big_endian_flag &&        red_max == 31 && green_max == 63 && blue_max == 31 &&        red_shift == 11 && green_shift == 5 && blue_shift == 0) {        vs->depth = 2;        vs->write_pixels = vnc_write_pixels_copy;        vs->send_hextile_tile = send_hextile_tile_16;    } else    if (bits_per_pixel == 8 &&        red_max == 7 && green_max == 7 && blue_max == 3 &&        red_shift == 5 && green_shift == 2 && blue_shift == 0) {        vs->depth = 1;        vs->write_pixels = vnc_write_pixels_copy;        vs->send_hextile_tile = send_hextile_tile_8;    } else    {        /* generic and slower case */        if (bits_per_pixel != 8 &&            bits_per_pixel != 16 &&            bits_per_pixel != 32)            goto fail;        vs->depth = 4;        vs->red_shift = red_shift;        vs->red_max = red_max;        vs->red_shift1 = 24 - compute_nbits(red_max);        vs->green_shift = green_shift;        vs->green_max = green_max;        vs->green_shift1 = 16 - compute_nbits(green_max);        vs->blue_shift = blue_shift;        vs->blue_max = blue_max;        vs->blue_shift1 = 8 - compute_nbits(blue_max);        vs->pix_bpp = bits_per_pixel / 8;        vs->pix_big_endian = big_endian_flag;        vs->write_pixels = vnc_write_pixels_generic;        vs->send_hextile_tile = send_hextile_tile_generic;    }    vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));    memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);    vga_hw_invalidate();    vga_hw_update();}static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len){    int i;    uint16_t limit;    switch (data[0]) {    case 0:	if (len == 1)	    return 20;	set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),			 read_u8(data, 6), read_u8(data, 7),			 read_u16(data, 8), read_u16(data, 10),			 read_u16(data, 12), read_u8(data, 14),			 read_u8(data, 15), read_u8(data, 16));	break;    case 2:	if (len == 1)	    return 4;	if (len == 4)	    return 4 + (read_u16(data, 2) * 4);	limit = read_u16(data, 2);	for (i = 0; i < limit; i++) {	    int32_t val = read_s32(data, 4 + (i * 4));	    memcpy(data + 4 + (i * 4), &val, sizeof(val));	}	set_encodings(vs, (int32_t *)(data + 4), limit);	break;    case 3:	if (len == 1)	    return 10;	framebuffer_update_request(vs,				   read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),				   read_u16(data, 6), read_u16(data, 8));	break;    case 4:	if (len == 1)	    return 8;	key_event(vs, read_u8(data, 1), read_u32(data, 4));	break;    case 5:	if (len == 1)	    return 6;	pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));	break;    case 6:	if (len == 1)	    return 8;	if (len == 8) {            uint32_t dlen = read_u32(data, 4);            if (dlen > 0)                return 8 + dlen;        }	client_cut_text(vs, read_u32(data, 4), data + 8);	break;    default:	printf("Msg: %d\n", data[0]);	vnc_client_error(vs);	break;    }    vnc_read_when(vs, protocol_client_msg, 1);    return 0;}static int protocol_client_init(VncState *vs, uint8_t *data, size_t len){    char pad[3] = { 0, 0, 0 };    char buf[1024];    int size;    vs->width = vs->ds->width;    vs->height = vs->ds->height;    vnc_write_u16(vs, vs->ds->width);    vnc_write_u16(vs, vs->ds->height);    vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */    vnc_write_u8(vs, vs->depth * 8); /* depth */#ifdef WORDS_BIGENDIAN    vnc_write_u8(vs, 1);             /* big-endian-flag */#else    vnc_write_u8(vs, 0);             /* big-endian-flag */#endif    vnc_write_u8(vs, 1);             /* true-color-flag */    if (vs->depth == 4) {	vnc_write_u16(vs, 0xFF);     /* red-max */	vnc_write_u16(vs, 0xFF);     /* green-max */	vnc_write_u16(vs, 0xFF);     /* blue-max */	vnc_write_u8(vs, 16);        /* red-shift */	vnc_write_u8(vs, 8);         /* green-shift */	vnc_write_u8(vs, 0);         /* blue-shift */        vs->send_hextile_tile = send_hextile_tile_32;    } else if (vs->depth == 2) {	vnc_write_u16(vs, 31);       /* red-max */	vnc_write_u16(vs, 63);       /* green-max */	vnc_write_u16(vs, 31);       /* blue-max */	vnc_write_u8(vs, 11);        /* red-shift */	vnc_write_u8(vs, 5);         /* green-shift */	vnc_write_u8(vs, 0);         /* blue-shift */        vs->send_hextile_tile = send_hextile_tile_16;    } else if (vs->depth == 1) {        /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */	vnc_write_u16(vs, 7);        /* red-max */	vnc_write_u16(vs, 7);        /* green-max */	vnc_write_u16(vs, 3);        /* blue-max */	vnc_write_u8(vs, 5);         /* red-shift */	vnc_write_u8(vs, 2);         /* green-shift */	vnc_write_u8(vs, 0);         /* blue-shift */        vs->send_hextile_tile = send_hextile_tile_8;    }    vs->write_pixels = vnc_write_pixels_copy;    vnc_write(vs, pad, 3);           /* padding */    if (qemu_name)        size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);    else        size = snprintf(buf, sizeof(buf), "QEMU");    vnc_write_u32(vs, size);    vnc_write(vs, buf, size);    vnc_flush(vs);    vnc_read_when(vs, protocol_client_msg, 1);    return 0;}static void make_challenge(VncState *vs){    int i;    srand(time(NULL)+getpid()+getpid()*987654+rand());    for (i = 0 ; i < sizeof(vs->challenge) ; i++)        vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));}static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len){    unsigned char response[VNC_AUTH_CHALLENGE_SIZE];    int i, j, pwlen;    unsigned char key[8];    if (!vs->password || !vs->password[0]) {	VNC_DEBUG("No password configured on server");	vnc_write_u32(vs, 1); /* Reject auth */	if (vs->minor >= 8) {	    static const char err[] = "Authentication failed";	    vnc_write_u32(vs, sizeof(err));	    vnc_write(vs, err, sizeof(err));	}	vnc_flush(vs);	vnc_client_error(vs);	return 0;    }    memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);    /* Calculate the expected challenge response */    pwlen = strlen(vs->password);    for (i=0; i<sizeof(key); i++)        key[i] = i<pwlen ? vs->password[i] : 0;    deskey(key, EN0);    for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)        des(response+j, response+j);    /* Compare expected vs actual challenge response */    if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {	VNC_DEBUG("Client challenge reponse did not match\n");	vnc_write_u32(vs, 1); /* Reject auth */	if (vs->minor >= 8) {	    static const char err[] = "Authentication failed";	    vnc_write_u32(vs, sizeof(err));	    vnc_write(vs, err, sizeof(err));	}	vnc_flush(vs);	vnc_client_error(vs);    } else {	VNC_DEBUG("Accepting VNC challenge response\n");	vnc_write_u32(vs, 0); /* Accept auth */	vnc_flush(vs);	vnc_read_when(vs, protocol_client_init, 1);    }    return 0;}static int start_auth_vnc(VncState *vs){    make_challenge(vs);    /* Send client a 'random' challenge */    vnc_write(vs, vs->challenge, sizeof(vs->challenge));    vnc_flush(vs);    vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));    return 0;}#if CONFIG_VNC_TLS#define DH_BITS 1024static gnutls_dh_params_t dh_params;static int vnc_tls_initialize(void){    static int tlsinitialized = 0;    if (tlsinitialized)	return 1;    if (gnutls_global_init () < 0)	return 0;    /* XXX ought to re-generate diffie-hellmen params periodically */    if (gnutls_dh_params_init (&dh_params) < 0)	return 0;    if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)	return 0;#if _VNC_DEBUG == 2    gnutls_global_set_log_level(10);    gnutls_global_set_log_function(vnc_debug_gnutls_log);#endif    tlsinitialized = 1;    return 1;}static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void){    gnutls_anon_server_credentials anon_cred;    int ret;    if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {	VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));	return NULL;    }    gnutls_anon_set_server_dh_params(anon_cred, dh_params);    return anon_cred;}static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs){    gnutls_certificate_credentials_t x509_cred;    int ret;    if (!vs->x509cacert) {	VNC_DEBUG("No CA x509 certificate specified\n");	return NULL;    }    if (!vs->x509cert) {	VNC_DEBUG("No server x509 certificate specified\n");	return NULL;    }    if (!vs->x509key) {	VNC_DEBUG("No server private key specified\n");	return NULL;    }    if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {	VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));	return NULL;    }    if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,						      vs->x509cacert,						      GNUTLS_X509_FMT_PEM)) < 0) {	VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));	gnutls_certificate_free_credentials(x509_cred);	return NULL;    }    if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,						     vs->x509cert,						     vs->x509key,						     GNUTLS_X509_FMT_PEM)) < 0) {	VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));	gnutls_certificate_free_credentials(x509_cred);	return NULL;    }    if (vs->x509cacrl) {	if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,							vs->x509cacrl,							GNUTLS_X509_FMT_PEM)) < 0) {	    VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));	    gnutls_certificate_free_credentials(x509_cred);	    return NULL;	}    }    gnutls_certificate_set_dh_params (x509_cred, dh_params);    return x509_cred;}static int vnc_validate_certificate(struct VncState *vs){    int ret;    unsigned int status;    const gnutls_datum_t *certs;    unsigned int nCerts, i;    time_t now;    VNC_DEBUG("Validating client certificate\n");    if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {	VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));	return -1;    }    if ((now = time(NULL)) == ((time_t)-1)) {	return -1;    }    if (status != 0) {	if (status & GNUTLS_CERT_INVALID)	    VNC_DEBUG("The certificate is not trusted.\n");	if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)	    VNC_DEBUG("The certificate hasn't got a known issuer.\n");	if (status & GNUTLS_CERT_REVOKED)	    VNC_DEBUG("The certificate has been revoked.\n");	if (status & GNUTLS_CERT_INSECURE_ALGORITHM)	    VNC_DEBUG("The certificate uses an insecure algorithm\n");	return -1;    } else {	VNC_DEBUG("Certificate is valid!\n");    }    /* Only support x509 for now */    if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)	return -1;    if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))	return -1;    for (i = 0 ; i < nCerts ; i++) {	gnutls_x509_crt_t cert;	VNC_DEBUG ("Checking certificate chain %d\n", i);	if (gnutls_x509_crt_init (&cert) < 0)	    return -1;	if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {	    gnutls_x509_crt_deinit (cert);	    return -1;	}	if (gnutls_x509_crt_get_expiration_time (cert) < now) {	    VNC_DEBUG("The certificate has expired\n");	    gnutls_x509_crt_deinit (cert);	    return -1;	}	if (gnutls_x509_crt_get_activation_time (cert) > now) {	    VNC_DEBUG("The certificate is not yet activated\n");	    gnutls_x509_crt_deinit (cert);	    return -1;	}	if (gnutls_x509_crt_get_activation_time (cert) > now) {	    VNC_DEBUG("The certificate is not yet activated\n");	    gnutls_x509_crt_deinit (cert);	    return -1;	}	gnutls_x509_crt_deinit (cert);    }    return 0;}static int start_auth_vencrypt_subauth(VncState *vs){    switch (vs->subauth) {    case VNC_AUTH_VENCRYPT_TLSNONE:    case VNC_AUTH_VENCRYPT_X509NONE:       VNC_DEBUG("Accept TLS auth none\n");       vnc_write_u32(vs, 0); /* Accept auth completion */       vnc_read_when(vs, protocol_client_init, 1);       break;    case VNC_AUTH_VENCRYPT_TLSVNC:    case VNC_AUTH_VENCRYPT_X509VNC:       VNC_DEBUG("Start TLS auth VNC\n");       return start_auth_vnc(vs);    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[] = "Unsupported authentication type";           vnc_write_u32(vs, sizeof(err));           vnc_write(vs, err, sizeof(err));       }       vnc_client_error(vs);    }    return 0;}static void vnc_handshake_io(void *opaque);static int vnc_continue_handshake(struct VncState *vs) {    int ret;    if ((ret = gnutls_handshake(vs->tls_session)) < 0) {       if (!gnutls_error_is_fatal(ret)) {           VNC_DEBUG("Handshake interrupted (blocking)\n");           if (!gnutls_record_get_direction(vs->tls_session))               qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);           else               qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);           return 0;       }       VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));       vnc_client_error(vs);       return -1;    }    if (vs->x509verify) {	if (vnc_validate_certificate(vs) < 0) {	    VNC_DEBUG("Client verification failed\n");	    vnc_client_error(vs);	    return -1;	} else {	    VNC_DEBUG("Client verification passed\n");	}    }    VNC_DEBUG("Handshake done, switching to TLS data mode\n");    vs->wiremode = VNC_WIREMODE_TLS;    qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);    return start_auth_vencrypt_subauth(vs);}static void vnc_handshake_io(void *opaque) {    struct VncState *vs = (struct VncState *)opaque;    VNC_DEBUG("Handshake IO continue\n");    vnc_continue_handshake(vs);}#define NEED_X509_AUTH(vs)			      \    ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \     (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \     (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)static int vnc_start_tls(struct VncState *vs) {    static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };    static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };    static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};    static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};    VNC_DEBUG("Do TLS setup\n");    if (vnc_tls_initialize() < 0) {	VNC_DEBUG("Failed to init TLS\n");	vnc_client_error(vs);	return -1;    }    if (vs->tls_session == NULL) {	if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {	    vnc_client_error(vs);	    return -1;	}	if (gnutls_set_default_priority(vs->tls_session) < 0) {	    gnutls_deinit(vs->tls_session);	    vs->tls_session = NULL;	    vnc_client_error(vs);	    return -1;	}	if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {	    gnutls_deinit(vs->tls_session);	    vs->tls_session = NULL;	    vnc_client_error(vs);	    return -1;	}	if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {	    gnutls_deinit(vs->tls_session);	    vs->tls_session = NULL;	    vnc_client_error(vs);	    return -1;	}	if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {	    gnutls_deinit(vs->tls_session);	    vs->tls_session = NULL;	    vnc_client_error(vs);	    return -1;	}

⌨️ 快捷键说明

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