123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /*
- ** 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 "sslconnection.h"
- #ifdef _WIN32
- #include <wincrypt.h>
- #endif
- #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
- #ifdef USE_SSL
- if (!open_ssl_initted)
- {
- InitSSL();
- open_ssl_initted=1;
- }
- #endif
- 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
- #endif
- }
- 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])
- {
- *req = _strdup(p);
- }
-
- return NErr_Success;
- }
|