예제 #1
0
파일: tls.c 프로젝트: Devolutions/FreeRDP
static BOOL is_accepted(rdpTls* tls, const BYTE* pem, size_t length)
{
	rdpSettings* settings = tls->settings;
	char* AccpetedKey;
	UINT32 AcceptedKeyLength;

	if (tls->isGatewayTransport)
	{
		AccpetedKey = settings->GatewayAcceptedCert;
		AcceptedKeyLength = settings->GatewayAcceptedCertLength;
	}
	else if (is_redirected(tls))
	{
		AccpetedKey = settings->RedirectionAcceptedCert;
		AcceptedKeyLength = settings->RedirectionAcceptedCertLength;
	}
	else
	{
		AccpetedKey = settings->AcceptedCert;
		AcceptedKeyLength = settings->AcceptedCertLength;
	}

	if (AcceptedKeyLength > 0)
	{
		if (AcceptedKeyLength == length)
		{
			if (memcmp(AccpetedKey, pem, AcceptedKeyLength) == 0)
				return TRUE;
		}
	}

	if (tls->isGatewayTransport)
	{
		free(settings->GatewayAcceptedCert);
		settings->GatewayAcceptedCert = NULL;
		settings->GatewayAcceptedCertLength = 0;
	}
	else if (is_redirected(tls))
	{
		free(settings->RedirectionAcceptedCert);
		settings->RedirectionAcceptedCert = NULL;
		settings->RedirectionAcceptedCertLength = 0;
	}
	else
	{
		free(settings->AcceptedCert);
		settings->AcceptedCert = NULL;
		settings->AcceptedCertLength = 0;
	}

	return FALSE;
}
예제 #2
0
파일: tls.c 프로젝트: Devolutions/FreeRDP
static BOOL accept_cert(rdpTls* tls, BYTE* pem, UINT32 length)
{
	rdpSettings* settings = tls->settings;

	if (tls->isGatewayTransport)
	{
		settings->GatewayAcceptedCert = (char*)pem;
		settings->GatewayAcceptedCertLength = length;
	}
	else if (is_redirected(tls))
	{
		settings->RedirectionAcceptedCert = (char*)pem;
		settings->RedirectionAcceptedCertLength = length;
	}
	else
	{
		settings->AcceptedCert = (char*)pem;
		settings->AcceptedCertLength = length;
	}

	return TRUE;
}
예제 #3
0
파일: tls.c 프로젝트: Devolutions/FreeRDP
int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname,
                           int port)
{
	int match;
	int index;
	char* common_name = NULL;
	int common_name_length = 0;
	char** dns_names = 0;
	int dns_names_count = 0;
	int* dns_names_lengths = NULL;
	BOOL certificate_status;
	BOOL hostname_match = FALSE;
	BOOL verification_status = FALSE;
	rdpCertificateData* certificate_data;
	freerdp* instance = (freerdp*) tls->settings->instance;
	DWORD length;
	BYTE* pemCert;

	if (!tls_extract_pem(cert, &pemCert, &length))
		return -1;

	/* Check, if we already accepted this key. */
	if (is_accepted(tls, pemCert, length))
	{
		free(pemCert);
		return 1;
	}

	if (tls->settings->ExternalCertificateManagement)
	{
		int status = -1;

		if (instance->VerifyX509Certificate)
			status = instance->VerifyX509Certificate(instance, pemCert, length, hostname,
			         port, tls->isGatewayTransport | is_redirected(tls) ? 2 : 0);
		else
			WLog_ERR(TAG, "No VerifyX509Certificate callback registered!");

		if (status > 0)
		{
			accept_cert(tls, pemCert, length);
		}
		else if (status < 0)
		{
			WLog_ERR(TAG, "VerifyX509Certificate failed: (length = %d) status: [%d] %s",
			         length, status, pemCert);
			free(pemCert);
			return -1;
		}
		else
			free(pemCert);

		return (status == 0) ? 0 : 1;
	}

	/* ignore certificate verification if user explicitly required it (discouraged) */
	if (tls->settings->IgnoreCertificate)
	{
		free(pemCert);
		return 1;  /* success! */
	}

	if (!tls->isGatewayTransport && tls->settings->AuthenticationLevel == 0)
	{
		free(pemCert);
		return 1;  /* success! */
	}

	/* if user explicitly specified a certificate name, use it instead of the hostname */
	if (!tls->isGatewayTransport && tls->settings->CertificateName)
		hostname = tls->settings->CertificateName;

	/* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */
	certificate_status = x509_verify_certificate(cert,
	                     tls->certificate_store->path);
	/* verify certificate name match */
	certificate_data = crypto_get_certificate_data(cert->px509, hostname, port);
	/* extra common name and alternative names */
	common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length);
	dns_names = crypto_cert_get_dns_names(cert->px509, &dns_names_count,
	                                      &dns_names_lengths);

	/* compare against common name */

	if (common_name)
	{
		if (tls_match_hostname(common_name, common_name_length, hostname))
			hostname_match = TRUE;
	}

	/* compare against alternative names */

	if (dns_names)
	{
		for (index = 0; index < dns_names_count; index++)
		{
			if (tls_match_hostname(dns_names[index], dns_names_lengths[index], hostname))
			{
				hostname_match = TRUE;
				break;
			}
		}
	}

	/* if the certificate is valid and the certificate name matches, verification succeeds */
	if (certificate_status && hostname_match)
		verification_status = TRUE; /* success! */

	/* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */
	if (!certificate_status || !hostname_match)
	{
		char* issuer;
		char* subject;
		char* fingerprint;
		DWORD accept_certificate = 0;
		issuer = crypto_cert_issuer(cert->px509);
		subject = crypto_cert_subject(cert->px509);
		fingerprint = crypto_cert_fingerprint(cert->px509);
		/* search for matching entry in known_hosts file */
		match = certificate_data_match(tls->certificate_store, certificate_data);

		if (match == 1)
		{
			/* no entry was found in known_hosts file, prompt user for manual verification */
			if (!hostname_match)
				tls_print_certificate_name_mismatch_error(
				    hostname, port,
				    common_name, dns_names,
				    dns_names_count);

			/* Automatically accept certificate on first use */
			if (tls->settings->AutoAcceptCertificate)
			{
				WLog_INFO(TAG, "No certificate stored, automatically accepting.");
				accept_certificate = 1;
			}
			else if (instance->VerifyCertificate)
			{
				accept_certificate = instance->VerifyCertificate(
				                         instance, common_name,
				                         subject, issuer,
				                         fingerprint, !hostname_match);
			}

			switch (accept_certificate)
			{
				case 1:
					/* user accepted certificate, add entry in known_hosts file */
					verification_status = certificate_data_print(tls->certificate_store,
					                      certificate_data);
					break;

				case 2:
					/* user did accept temporaty, do not add to known hosts file */
					verification_status = TRUE;
					break;

				default:
					/* user did not accept, abort and do not add entry in known_hosts file */
					verification_status = FALSE; /* failure! */
					break;
			}
		}
		else if (match == -1)
		{
			char* old_subject = NULL;
			char* old_issuer = NULL;
			char* old_fingerprint = NULL;
			/* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */
			tls_print_certificate_error(hostname, port, fingerprint,
			                            tls->certificate_store->file);

			if (!certificate_get_stored_data(tls->certificate_store,
			                                 certificate_data, &old_subject,
			                                 &old_issuer, &old_fingerprint))
				WLog_WARN(TAG, "Failed to get certificate entry for %s:%d",
				          hostname, port);

			if (instance->VerifyChangedCertificate)
			{
				accept_certificate = instance->VerifyChangedCertificate(
				                         instance, common_name, subject, issuer,
				                         fingerprint, old_subject, old_issuer,
				                         old_fingerprint);
			}

			free(old_subject);
			free(old_issuer);
			free(old_fingerprint);

			switch (accept_certificate)
			{
				case 1:
					/* user accepted certificate, add entry in known_hosts file */
					verification_status = certificate_data_replace(tls->certificate_store,
					                      certificate_data);
					break;

				case 2:
					/* user did accept temporaty, do not add to known hosts file */
					verification_status = TRUE;
					break;

				default:
					/* user did not accept, abort and do not add entry in known_hosts file */
					verification_status = FALSE; /* failure! */
					break;
			}
		}
		else if (match == 0)
			verification_status = TRUE; /* success! */

		free(issuer);
		free(subject);
		free(fingerprint);
	}

	certificate_data_free(certificate_data);
	free(common_name);

	if (dns_names)
		crypto_cert_dns_names_free(dns_names_count, dns_names_lengths,
		                           dns_names);

	if (verification_status > 0)
	{
		accept_cert(tls, pemCert, length);
	}
	else
	{
		free(pemCert);
	}

	return (verification_status == 0) ? 0 : 1;
}
예제 #4
0
파일: dump.c 프로젝트: c0ns0le/SysToolsLib
int main(int argc, char *argv[])
    {
    int i;
    DWORD dwBase = 0xFFFFFFFFL;     /* First address to dump */
    DWORD dwLength = 0xFFFFFFFFL;   /* Number of bytes to dump */
    BYTE table[16];		    /* 16 bytes table */
    DWORD ul;
    WORD u;
    char *pszName = NULL;	    /* File name */
    FILE *f;

#ifndef __unix__
    /* Force stdin and stdout to untranslated */
    _setmode( _fileno( stdin ), _O_BINARY );
#endif

    for (i=1; i<argc; i++)
        {
        if (IsSwitch(argv[i]))
            {
	    if (   streq(argv[i]+1, "?")
	        || streq(argv[i]+1, "h")
	        || streq(argv[i]+1, "-help"))
                {
		usage();
                }
	    if (streq(argv[i]+1, "p"))
                {
		paginate = GetScreenRows() - 1;  /* Pause once per screen */
		continue;
                }
	    if (streq(argv[i]+1, "V")) {	    /* -V: Display the version */
		printf("%s\n", PROGRAM_VERSION " " PROGRAM_DATE " " OS_NAME);
		exit(0);
	    }
	    printf("Unrecognized switch %s. Ignored.\n", argv[i]);
            continue;
	    }
	if (!pszName)
	    {
	    pszName = argv[i];
	    continue;
	    }
	if (dwBase == 0xFFFFFFFFL)
            {
	    if (sscanf(argv[i], "%lX", &ul)) dwBase = ul;
            continue;
            }
	if (dwLength == 0xFFFFFFFFL)
            {
	    if (sscanf(argv[i], "%lX", &ul)) dwLength = ul;
            continue;
            }
        printf("Unexpected argument: %s\nIgnored.\n", argv[i]);
        break;  /* Ignore other arguments */
	}

    if (pszName)
	{
        f = fopen(pszName, "rb");
        if (!f)
            {
            printf("Cannot open file %s.\n", pszName);
            exit(1);
            }
        }
    else
        {
	if (!is_redirected(stdin)) usage();
        f = stdin;
        paginate = FALSE;  /* Avoid waiting forever */
        }

    printf("\n\
Offset    00           04           08           0C           0   4    8   C   \n\
--------  -----------  -----------  -----------  -----------  -------- --------\n\
");

    if (dwBase == 0xFFFFFFFFL) dwBase = 0;
    fseek(f, dwBase & 0xFFFFFFF0L, SEEK_SET);

    for (ul = dwBase & 0xFFFFFFF0L;
	 between(dwBase & 0xFFFFFFF0L, ul, dwBase+dwLength);
         ul += 16)
	{
	size_t nRead;

	nRead = fread(table, 1, 16, f);
	if (!nRead) break;

	printf("%08lX ", ul);

	/* Display the hex dump */

	for (u=0; u<nRead; u++)
            {
	    if (!(u&3)) printf(" ");
	    if (between(dwBase, ul+u, dwBase+dwLength))
		printf("%02X ", (WORD)table[u]);
            else
		printf("   ");
            }
	for ( ; u<16; u++)
	    {
	    if (!(u&3)) printf(" ");
	    printf("   ");
	    }

	/* Display the character dump */

	for (u=0; u<nRead; u++)
	    {
	    if (!(u&7)) printf(" ");
#ifdef __unix__
	    if ( (table[u] & 0x7F) < 0x20) table[u] = ' ';
#else
	    switch (table[u])
		{
		case '\x07': table[u] = ' '; break;
		case '\x08': table[u] = ' '; break; /* Backspace	*/
		case '\x09': table[u] = ' '; break; /* Tab		*/
		case '\x0A': table[u] = ' '; break; /* Line feed	*/
		case '\x0D': table[u] = ' '; break; /* Carrier return	*/
		case '\x1A': table[u] = ' '; break; 
		default: break;
		}
#endif
	    if (between(dwBase, ul+u, dwBase+dwLength) && (table[u]>' '))
		printf("%c", table[u]);
            else
		printf(" ");
            }
	for ( ; u<16; u++)
	    {
	    if (!(u&7)) printf(" ");
	    printf(" ");
	    }

	printflf();
	}

    printflf();

    return 0;
    }