diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 807670616..e14fffc53 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -201,6 +201,7 @@ struct rdp_settings uint32 encryption_level; boolean authentication; + char* home_path; boolean server_mode; rdpBlob server_random; diff --git a/include/freerdp/utils/certstore.h b/include/freerdp/utils/certstore.h index 4a90e157e..2a5f9bda2 100644 --- a/include/freerdp/utils/certstore.h +++ b/include/freerdp/utils/certstore.h @@ -1,8 +1,8 @@ #ifndef __CERTSTORE_UTILS_H #define __CERTSTORE_UTILS_H -typedef struct rdp_certstore rdpCertstore; -typedef struct rdp_certdata rdpCertdata; +typedef struct rdp_cert_store rdpCertStore; +typedef struct rdp_cert_data rdpCertData; #include #include @@ -11,33 +11,33 @@ typedef struct rdp_certdata rdpCertdata; #include #include -struct rdp_certdata +struct rdp_cert_data { - char* thumbprint; - char* hostname; + char* hostname; + char* fingerprint; }; -struct rdp_certstore +struct rdp_cert_store { FILE* fp; + int match; char* path; char* file; - char* home; - int match; - struct rdp_certdata* certdata; + char* home_path; + rdpCertData* certdata; }; -FREERDP_API void certstore_create(rdpCertstore* certstore); -FREERDP_API void certstore_open(rdpCertstore* certstore); -FREERDP_API void certstore_load(rdpCertstore* certstore); -FREERDP_API void certstore_close(rdpCertstore* certstore); +FREERDP_API void certstore_create(rdpCertStore* certstore); +FREERDP_API void certstore_open(rdpCertStore* certstore); +FREERDP_API void certstore_load(rdpCertStore* certstore); +FREERDP_API void certstore_close(rdpCertStore* certstore); FREERDP_API char* get_local_certloc(); -FREERDP_API rdpCertdata* certdata_new(char* host_name, char* fingerprint); -FREERDP_API void certdata_free(rdpCertdata* certdata); -FREERDP_API void certstore_init(rdpCertstore* certstore); -FREERDP_API rdpCertstore* certstore_new(rdpCertdata* certdata); -FREERDP_API void certstore_free(rdpCertstore* certstore); -FREERDP_API int match_certdata(rdpCertstore* certstore); -FREERDP_API void print_certdata(rdpCertstore* certstore); +FREERDP_API rdpCertData* certdata_new(char* hostname, char* fingerprint); +FREERDP_API void certdata_free(rdpCertData* certdata); +FREERDP_API void certstore_init(rdpCertStore* certstore); +FREERDP_API rdpCertStore* certstore_new(rdpCertData* certdata, char* home_path); +FREERDP_API void certstore_free(rdpCertStore* certstore); +FREERDP_API int cert_data_match(rdpCertStore* certstore); +FREERDP_API void cert_data_print(rdpCertStore* certstore); #endif /* __CERTSTORE_UTILS_H */ diff --git a/include/freerdp/utils/file.h b/include/freerdp/utils/file.h new file mode 100644 index 000000000..74a86b58d --- /dev/null +++ b/include/freerdp/utils/file.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * File Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FILE_UTILS_H +#define __FILE_UTILS_H + +#include + +FREERDP_API void freerdp_mkdir(char* path); + +#endif /* __FILE_UTILS_H */ diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c index 27134ebb7..1fc0bdd91 100644 --- a/libfreerdp-core/credssp.c +++ b/libfreerdp-core/credssp.c @@ -106,7 +106,7 @@ void credssp_ntlmssp_init(rdpCredssp* credssp) int credssp_get_public_key(rdpCredssp* credssp) { - int ret; + int status; CryptoCert cert; cert = tls_get_certificate(credssp->transport->tls); @@ -116,12 +116,14 @@ int credssp_get_public_key(rdpCredssp* credssp) printf("credssp_get_public_key: tls_get_certificate failed to return the server certificate.\n"); return 0; } - if(tls_verify_certificate(cert,credssp->transport->settings->hostname)) + + if(tls_verify_certificate(cert, credssp->transport->settings, credssp->transport->settings->hostname)) tls_disconnect(credssp->transport->tls); - ret = crypto_cert_get_public_key(cert, &credssp->public_key); + + status = crypto_cert_get_public_key(cert, &credssp->public_key); crypto_cert_free(cert); - return ret; + return status; } /** @@ -620,6 +622,7 @@ rdpCredssp* credssp_new(rdpTransport* transport) self->transport = transport; self->send_seq_num = 0; self->ntlmssp = ntlmssp_new(); + self->settings = transport->settings; } return self; diff --git a/libfreerdp-core/credssp.h b/libfreerdp-core/credssp.h index ee42c16b7..32774259a 100644 --- a/libfreerdp-core/credssp.h +++ b/libfreerdp-core/credssp.h @@ -42,6 +42,7 @@ struct rdp_credssp int send_seq_num; rdpBlob public_key; rdpBlob ts_credentials; + rdpSettings* settings; CryptoRc4 rc4_seal_state; struct _NTLMSSP *ntlmssp; struct rdp_transport* transport; diff --git a/libfreerdp-core/crypto.c b/libfreerdp-core/crypto.c index 817dc5481..bea62cacd 100644 --- a/libfreerdp-core/crypto.c +++ b/libfreerdp-core/crypto.c @@ -333,10 +333,10 @@ end: return status; } -rdpCertdata* crypto_get_certdata(X509* xcert, char* hostname) +rdpCertData* crypto_get_cert_data(X509* xcert, char* hostname) { char* fp; - rdpCertdata* certdata; + rdpCertData* certdata; fp = crypto_cert_fingerprint(xcert); certdata = certdata_new(hostname, fp); @@ -345,7 +345,7 @@ rdpCertdata* crypto_get_certdata(X509* xcert, char* hostname) return certdata; } -void crypto_cert_printinfo(X509* xcert) +void crypto_cert_print_info(X509* xcert) { char* fp; char* issuer; diff --git a/libfreerdp-core/crypto.h b/libfreerdp-core/crypto.h index c5dd05a24..26b786bcd 100644 --- a/libfreerdp-core/crypto.h +++ b/libfreerdp-core/crypto.h @@ -110,11 +110,11 @@ void crypto_hmac_free(CryptoHmac hmac); typedef struct crypto_cert_struct* CryptoCert; CryptoCert crypto_cert_read(uint8* data, uint32 length); char* cypto_cert_fingerprint(X509* xcert); -void crypto_cert_printinfo(X509* xcert); +void crypto_cert_print_info(X509* xcert); void crypto_cert_free(CryptoCert cert); boolean x509_verify_cert(CryptoCert cert); boolean crypto_cert_verify(CryptoCert server_cert, CryptoCert cacert); -rdpCertdata* crypto_get_certdata(X509* xcert, char* hostname); +rdpCertData* crypto_get_cert_data(X509* xcert, char* hostname); boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key); void crypto_rsa_encrypt(uint8* input, int length, uint32 key_length, uint8* modulus, uint8* exponent, uint8* output); diff --git a/libfreerdp-core/tls.c b/libfreerdp-core/tls.c index 55af6f191..ad8cebf32 100644 --- a/libfreerdp-core/tls.c +++ b/libfreerdp-core/tls.c @@ -242,25 +242,25 @@ rdpTls* tls_new() return tls; } -int tls_verify_certificate(CryptoCert cert, char* hostname) +int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostname) { boolean status; - rdpCertstore* certstore; + rdpCertStore* certstore; status = x509_verify_cert(cert); if (status != True) { - rdpCertdata* certdata; - certdata = crypto_get_certdata(cert->px509, hostname); - certstore = certstore_new(certdata); + rdpCertData* certdata; + certdata = crypto_get_cert_data(cert->px509, hostname); + certstore = certstore_new(certdata, settings->home_path); - if (match_certdata(certstore) == 0) + if (cert_data_match(certstore) == 0) goto end; if (certstore->match == 1) { char answer; - crypto_cert_printinfo(cert->px509); + crypto_cert_print_info(cert->px509); #ifndef _WIN32 while (1) @@ -270,7 +270,7 @@ int tls_verify_certificate(CryptoCert cert, char* hostname) if (answer == 'y' || answer == 'Y') { - print_certdata(certstore); + cert_data_print(certstore); break; } else if (answer == 'n' || answer == 'N') diff --git a/libfreerdp-core/tls.h b/libfreerdp-core/tls.h index a4d42d591..369cd3260 100644 --- a/libfreerdp-core/tls.h +++ b/libfreerdp-core/tls.h @@ -43,7 +43,7 @@ boolean tls_disconnect(rdpTls* tls); int tls_read(rdpTls* tls, uint8* data, int length); int tls_write(rdpTls* tls, uint8* data, int length); CryptoCert tls_get_certificate(rdpTls* tls); -int tls_verify_certificate(CryptoCert cert,char* hostname); +int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostname); void tls_print_cert_error(); boolean tls_print_error(char* func, SSL* connection, int value); rdpTls* tls_new(); diff --git a/libfreerdp-utils/CMakeLists.txt b/libfreerdp-utils/CMakeLists.txt index b64263047..cc941cc23 100644 --- a/libfreerdp-utils/CMakeLists.txt +++ b/libfreerdp-utils/CMakeLists.txt @@ -28,6 +28,7 @@ set(FREERDP_UTILS_SRCS bitmap.c hexdump.c list.c + file.c load_plugin.c memory.c mutex.c diff --git a/libfreerdp-utils/certstore.c b/libfreerdp-utils/certstore.c index e6c1d3eff..871891eb8 100644 --- a/libfreerdp-utils/certstore.c +++ b/libfreerdp-utils/certstore.c @@ -17,19 +17,16 @@ * limitations under the License. */ +#include #include -#ifdef _WIN32 -#include -#endif - static char cert_dir[] = "freerdp"; static char cert_loc[] = "cacert"; static char certstore_file[] = "known_hosts"; -void certstore_create(rdpCertstore* certstore) +void certstore_create(rdpCertStore* certstore) { - certstore->fp = fopen((char*)certstore->file, "w+"); + certstore->fp = fopen((char*) certstore->file, "w+"); if (certstore->fp == NULL) { @@ -40,12 +37,12 @@ void certstore_create(rdpCertstore* certstore) fflush(certstore->fp); } -void certstore_load(rdpCertstore* certstore) +void certstore_load(rdpCertStore* certstore) { certstore->fp = fopen((char*) certstore->file, "r+"); } -void certstore_open(rdpCertstore* certstore) +void certstore_open(rdpCertStore* certstore) { struct stat stat_info; @@ -55,7 +52,7 @@ void certstore_open(rdpCertstore* certstore) certstore_load(certstore); } -void certstore_close(rdpCertstore* certstore) +void certstore_close(rdpCertStore* certstore) { if (certstore->fp != NULL) fclose(certstore->fp); @@ -66,31 +63,30 @@ char* get_local_certloc() char* home_path; char* certloc; struct stat stat_info; + home_path = getenv("HOME"); certloc = (char*) xmalloc(strlen(home_path) + strlen("/.") + strlen(cert_dir) + strlen("/") + strlen(cert_loc) + 1); sprintf(certloc,"%s/.%s/%s",home_path,cert_dir,cert_loc); if(stat((char*) certloc, &stat_info) != 0) - { -#ifndef _WIN32 - mkdir(certloc, S_IRUSR | S_IWUSR | S_IXUSR); -#else - CreateDirectoryA(certloc, 0); -#endif - } + freerdp_mkdir(certloc); return certloc; } -void certstore_init(rdpCertstore* certstore) +void certstore_init(rdpCertStore* certstore) { int length; char* home_path; struct stat stat_info; - certstore->match=1; - home_path = getenv("HOME"); + certstore->match = 1; + + if (certstore->home_path == NULL) + home_path = getenv("HOME"); + else + home_path = certstore->home_path; if (home_path == NULL) { @@ -98,63 +94,60 @@ void certstore_init(rdpCertstore* certstore) return; } - certstore->home = (char*) xstrdup(home_path); + certstore->home_path = (char*) xstrdup(home_path); - certstore->path = (char*) xmalloc(strlen(certstore->home) + strlen("/.") + strlen(cert_dir) + 1); - sprintf(certstore->path, "%s/.%s", certstore->home, cert_dir); + certstore->path = (char*) xmalloc(strlen(certstore->home_path) + 2 + strlen(cert_dir) + 1); + sprintf(certstore->path, "%s/.%s", certstore->home_path, cert_dir); if (stat(certstore->path, &stat_info) != 0) { -#ifndef _WIN32 - mkdir(certstore->path, S_IRUSR | S_IWUSR | S_IXUSR); -#else - CreateDirectoryA(certstore->path, 0); -#endif + freerdp_mkdir(certstore->path); printf("creating directory %s\n", certstore->path); } length = strlen(certstore->path); - certstore->file = (char*) xmalloc(strlen(certstore->path) + strlen("/") + strlen(certstore_file) + 1); + certstore->file = (char*) xmalloc(strlen(certstore->path) + 1 + strlen(certstore_file) + 1); sprintf(certstore->file, "%s/%s", certstore->path, certstore_file); certstore_open(certstore); } -rdpCertdata* certdata_new(char* host_name,char* fingerprint) +rdpCertData* certdata_new(char* hostname, char* fingerprint) { - rdpCertdata* certdata; + rdpCertData* certdata; - certdata = (rdpCertdata*) xzalloc(sizeof(rdpCertdata)); + certdata = (rdpCertData*) xzalloc(sizeof(rdpCertData)); - if (certdata !=NULL) + if (certdata != NULL) { - certdata->hostname = xzalloc(strlen(host_name) + 1); - certdata->thumbprint = xzalloc(strlen(fingerprint) + 1); - sprintf(certdata->hostname, "%s", host_name); - sprintf(certdata->thumbprint, "%s", fingerprint); + certdata->hostname = xzalloc(strlen(hostname) + 1); + certdata->fingerprint = xzalloc(strlen(fingerprint) + 1); + sprintf(certdata->hostname, "%s", hostname); + sprintf(certdata->fingerprint, "%s", fingerprint); } return certdata; } -void certdata_free(rdpCertdata* certdata) +void certdata_free(rdpCertData* certdata) { if(certdata != NULL) { xfree(certdata->hostname); - xfree(certdata->thumbprint); + xfree(certdata->fingerprint); xfree(certdata); } } -rdpCertstore* certstore_new(rdpCertdata* certdata) +rdpCertStore* certstore_new(rdpCertData* certdata, char* home_path) { - rdpCertstore* certstore; + rdpCertStore* certstore; - certstore = (rdpCertstore*) xzalloc(sizeof(rdpCertstore)); + certstore = (rdpCertStore*) xzalloc(sizeof(rdpCertStore)); if (certstore != NULL) { + certstore->home_path = home_path; certstore->certdata = certdata; certstore_init(certstore); } @@ -162,27 +155,27 @@ rdpCertstore* certstore_new(rdpCertdata* certdata) return certstore; } -void certstore_free(rdpCertstore* certstore) +void certstore_free(rdpCertStore* certstore) { if (certstore != NULL) { certstore_close(certstore); xfree(certstore->path); xfree(certstore->file); - xfree(certstore->home); + xfree(certstore->home_path); certdata_free(certstore->certdata); xfree(certstore); } } -int match_certdata(rdpCertstore* certstore) +int cert_data_match(rdpCertStore* certstore) { FILE* fp; int length; char* data; char* pline; long int size; - rdpCertdata* cert_data; + rdpCertData* cert_data; fp = certstore->fp; cert_data = certstore->certdata; @@ -213,7 +206,7 @@ int match_certdata(rdpCertstore* certstore) { pline = &pline[length + 1]; - if (strcmp(pline, cert_data->thumbprint) == 0) + if (strcmp(pline, cert_data->fingerprint) == 0) certstore->match = 0; else certstore->match = -1; @@ -228,8 +221,8 @@ int match_certdata(rdpCertstore* certstore) return certstore->match; } -void print_certdata(rdpCertstore* certstore) +void cert_data_print(rdpCertStore* certstore) { - fseek(certstore->fp,0,SEEK_END); - fprintf(certstore->fp,"%s %s\n",certstore->certdata->hostname,certstore->certdata->thumbprint); + fseek(certstore->fp, 0, SEEK_END); + fprintf(certstore->fp,"%s %s\n", certstore->certdata->hostname, certstore->certdata->fingerprint); } diff --git a/libfreerdp-utils/file.c b/libfreerdp-utils/file.c new file mode 100644 index 000000000..32b42ebf6 --- /dev/null +++ b/libfreerdp-utils/file.c @@ -0,0 +1,38 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * File Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +#ifdef _WIN32 +#include +#endif + +void freerdp_mkdir(char* path) +{ +#ifndef _WIN32 + mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR); +#else + CreateDirectoryA(path, 0); +#endif +} + diff --git a/libfreerdp-utils/registry.c b/libfreerdp-utils/registry.c index f50053e15..513cf74a4 100644 --- a/libfreerdp-utils/registry.c +++ b/libfreerdp-utils/registry.c @@ -17,11 +17,9 @@ * limitations under the License. */ -#include +#include -#ifdef _WIN32 -#include -#endif +#include static char registry_dir[] = "freerdp"; static char registry_file[] = "config.txt"; @@ -96,13 +94,14 @@ void registry_create(rdpRegistry* registry) printf("registry_create: error opening [%s] for writing\n", registry->file); return; } + registry_print(registry, registry->fp); fflush(registry->fp); } void registry_load(rdpRegistry* registry) { - registry->fp = fopen((char*)registry->file, "r+"); + registry->fp = fopen((char*) registry->file, "r+"); } void registry_open(rdpRegistry* registry) @@ -127,7 +126,18 @@ void registry_init(rdpRegistry* registry) char* home_path; struct stat stat_info; - home_path = getenv("HOME"); + if (registry->settings->home_path == NULL) + home_path = getenv("HOME"); + else + home_path = registry->settings->home_path; + + if (home_path == NULL) + { + printf("could not get home path\n"); + registry->available = False; + return; + } + registry->available = True; if (home_path == NULL) @@ -146,11 +156,7 @@ void registry_init(rdpRegistry* registry) if (stat(registry->path, &stat_info) != 0) { -#ifndef _WIN32 - mkdir(registry->path, S_IRUSR | S_IWUSR | S_IXUSR); -#else - CreateDirectoryA(registry->path, 0); -#endif + freerdp_mkdir(registry->path); printf("creating directory %s\n", registry->path); }