123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- /*
- ** 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
|