diff options
Diffstat (limited to 'Src/Components/wac_network/util.cpp')
-rw-r--r-- | Src/Components/wac_network/util.cpp | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/Src/Components/wac_network/util.cpp b/Src/Components/wac_network/util.cpp new file mode 100644 index 00000000..77493cf8 --- /dev/null +++ b/Src/Components/wac_network/util.cpp @@ -0,0 +1,211 @@ +/* +** JNetLib +** Copyright (C) 2000-2007 Nullsoft, Inc. +** Author: Justin Frankel +** File: util.cpp - JNL implementation of basic network utilities +** License: see jnetlib.h +*/ + +#include "netinc.h" +#include "util.h" +#include "foundation\error.h" + +#ifdef USE_SSL +#include "wac_network_ssl_connection.h" + +#ifdef _WIN32 +#include <wincrypt.h> +#endif // !_WIN32 + +#include <openssl/rand.h> + +#ifdef _WIN32 +static HCRYPTPROV GetKeySet() +{ + HCRYPTPROV hCryptProv; + LPCWSTR UserName = L"WinampKeyContainer"; // name of the key container + + if ( CryptAcquireContext( + &hCryptProv, // handle to the CSP + UserName, // container name + NULL, // use the default provider + PROV_RSA_FULL, // provider type + 0 ) ) // flag values + { + return hCryptProv; + } + else if ( CryptAcquireContext( + &hCryptProv, + UserName, + NULL, + PROV_RSA_FULL, + CRYPT_NEWKEYSET ) ) + { + return hCryptProv; + } + else + return 0; +} +#endif + +static void InitSSL() +{ + SSL_load_error_strings(); + SSL_library_init(); + +#ifdef _WIN32 + HCRYPTPROV hCryptProv = GetKeySet(); + if ( hCryptProv ) + { + BYTE pbData[ 8 * sizeof( unsigned long ) ] = { 0 }; + if ( CryptGenRandom( hCryptProv, 8 * sizeof( unsigned long ), pbData ) ) + { + RAND_seed( pbData, 16 ); + } + CryptReleaseContext( hCryptProv, 0 ); + } +#endif + + // sslContext = SSL_CTX_new(SSLv23_client_method()); + // SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL); + + // SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF); +} +static int open_ssl_initted = 0; +#endif + +static int was_initted = 0; + +int JNL::open_socketlib() +{ +#ifdef _WIN32 + if ( !was_initted ) + { + WSADATA wsaData = { 0 }; + if ( WSAStartup( MAKEWORD( 1, 1 ), &wsaData ) ) + { + return NErr_Error; + } + } +#endif // !_WIN32 + +#ifdef USE_SSL + if ( !open_ssl_initted ) + { + InitSSL(); + open_ssl_initted = 1; + } +#endif // !USE_SSL + + return NErr_Success; +} + +void JNL::close_socketlib() +{ +#ifdef _WIN32 + if ( was_initted ) + { + WSACleanup(); + } +#ifdef USE_SSL + // TODO need to do some reference counting to free this correctly + //SSL_CTX_free(sslContext); +#endif // !USE_SSL +#endif // !_WIN32 +} + +static char *jnl_strndup( const char *str, size_t n ) +{ + char *o = (char *)calloc( n + 1, sizeof( char ) ); + if ( !o ) + return 0; + + strncpy( o, str, n ); + o[ n ] = 0; + + return o; +} + +int JNL::parse_url( const char *url, char **prot, char **host, unsigned short *port, char **req, char **lp ) +{ + free( *prot ); *prot = 0; + free( *host ); *host = 0; + free( *req ); *req = 0; + free( *lp ); *lp = 0; + *port = 0; + + const char *p; + const char *protocol = strstr( url, "://" ); + if ( protocol ) + { + *prot = jnl_strndup( url, protocol - url ); + p = protocol + 3; + } + else + { + p = url; + } + + while ( p && *p && *p == '/' ) p++; // skip extra / + + size_t end = strcspn( p, "@/" ); + + // check for username + if ( p[ end ] == '@' ) + { + *lp = jnl_strndup( p, end ); + p = p + end + 1; + end = strcspn( p, "[:/" ); + } + + if ( p[ 0 ] == '[' ) // IPv6 style address + { + p++; + const char *ipv6_end = strchr( p, ']' ); + if ( !ipv6_end ) + return NErr_Malformed; + + *host = jnl_strndup( p, ipv6_end - p ); + p = ipv6_end + 1; + } + else + { + end = strcspn( p, ":/" ); + *host = jnl_strndup( p, end ); + p += end; + } + + // is there a port number? + if ( p[ 0 ] == ':' ) + { + char *new_end; + *port = (unsigned short)strtoul( p + 1, &new_end, 10 ); + p = new_end; + } + + if ( p[ 0 ] ) + { + // benski> this is here to workaround a bug with YP and NSV streams + if ( !strcmp( p, ";stream.nsv" ) ) + return NErr_Success; + + *req = _strdup( p ); + } + + return NErr_Success; +} + + +#if 0 +unsigned long JNL::ipstr_to_addr( const char *cp ) +{ + return inet_addr( cp ); +} + +void JNL::addr_to_ipstr( unsigned long addr, char *host, int maxhostlen ) +{ + in_addr a; a.s_addr = addr; + sprintf( host, /*maxhostlen,*/ "%u.%u.%u.%u", a.S_un.S_un_b.s_b1, a.S_un.S_un_b.s_b2, a.S_un.S_un_b.s_b3, a.S_un.S_un_b.s_b4 ); + //char *p=::inet_ntoa(a); strncpy(host,p?p:"",maxhostlen); +} +#endif
\ No newline at end of file |