aboutsummaryrefslogtreecommitdiff
path: root/Src/replicant/jnetlib/util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/replicant/jnetlib/util.cpp')
-rw-r--r--Src/replicant/jnetlib/util.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/Src/replicant/jnetlib/util.cpp b/Src/replicant/jnetlib/util.cpp
new file mode 100644
index 00000000..3b2b5a11
--- /dev/null
+++ b/Src/replicant/jnetlib/util.cpp
@@ -0,0 +1,185 @@
+/*
+** 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;
+}