зеркало из https://github.com/mozilla/pjs.git
Bug 542207 - ssltunnel: clean up and update logging and make it optional, r=ted, a=test-only-change
This commit is contained in:
Родитель
2ae655ca5e
Коммит
5df1da2ced
|
@ -51,8 +51,10 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdarg.h>
|
||||
#include "prinit.h"
|
||||
#include "prerror.h"
|
||||
#include "prenv.h"
|
||||
#include "prio.h"
|
||||
#include "prnetdb.h"
|
||||
#include "prtpool.h"
|
||||
|
@ -71,6 +73,68 @@ using std::vector;
|
|||
#define SET_DELIM(m, c) ((m)[(c) >> 3] |= (1 << ((c) & 7)))
|
||||
#define DELIM_TABLE_SIZE 32
|
||||
|
||||
// You can set the level of logging by env var SSLTUNNEL_LOG_LEVEL=n, where n
|
||||
// is 0 through 3. The default is 1, INFO level logging.
|
||||
enum LogLevel {
|
||||
LEVEL_DEBUG = 0,
|
||||
LEVEL_INFO = 1,
|
||||
LEVEL_ERROR = 2,
|
||||
LEVEL_SILENT = 3
|
||||
} gLogLevel, gLastLogLevel;
|
||||
|
||||
#define _LOG_OUTPUT(level, func, params) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (level >= gLogLevel) { \
|
||||
gLastLogLevel = level; \
|
||||
func params;\
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
// The most verbose output
|
||||
#define LOG_DEBUG(params) \
|
||||
_LOG_OUTPUT(LEVEL_DEBUG, printf, params)
|
||||
|
||||
// Top level informative messages
|
||||
#define LOG_INFO(params) \
|
||||
_LOG_OUTPUT(LEVEL_INFO, printf, params)
|
||||
|
||||
// Serious errors that must be logged always until completely gag
|
||||
#define LOG_ERROR(params) \
|
||||
_LOG_OUTPUT(LEVEL_ERROR, eprintf, params)
|
||||
|
||||
// Same as LOG_ERROR, but when logging is set to LEVEL_DEBUG, the message
|
||||
// will be put to the stdout instead of stderr to keep continuity with other
|
||||
// LOG_DEBUG message output
|
||||
#define LOG_ERRORD(params) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (gLogLevel == LEVEL_DEBUG) \
|
||||
_LOG_OUTPUT(LEVEL_ERROR, printf, params); \
|
||||
else \
|
||||
_LOG_OUTPUT(LEVEL_ERROR, eprintf, params); \
|
||||
PR_END_MACRO
|
||||
|
||||
// If there is any output written between LOG_BEGIN_BLOCK() and
|
||||
// LOG_END_BLOCK() then a new line will be put to the proper output (out/err)
|
||||
#define LOG_BEGIN_BLOCK() \
|
||||
gLastLogLevel = LEVEL_SILENT;
|
||||
|
||||
#define LOG_END_BLOCK() \
|
||||
PR_BEGIN_MACRO \
|
||||
if (gLastLogLevel == LEVEL_ERROR) \
|
||||
LOG_ERROR(("\n")); \
|
||||
if (gLastLogLevel < LEVEL_ERROR) \
|
||||
_LOG_OUTPUT(gLastLogLevel, printf, ("\n")); \
|
||||
PR_END_MACRO
|
||||
|
||||
int eprintf(const char* str, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
int result = vfprintf(stderr, str, ap);
|
||||
va_end(ap);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Copied from nsCRT
|
||||
char* strtok2(char* string, const char* delims, char* *newStr)
|
||||
{
|
||||
|
@ -264,19 +328,19 @@ bool ReadConnectRequest(server_info_t* server_info,
|
|||
client_auth_option* clientauth, string& host)
|
||||
{
|
||||
if (buffer.present() < 4) {
|
||||
printf(" !! only %d bytes present in the buffer", (int)buffer.present());
|
||||
LOG_DEBUG((" !! only %d bytes present in the buffer", (int)buffer.present()));
|
||||
return false;
|
||||
}
|
||||
if (strncmp(buffer.buffertail-4, "\r\n\r\n", 4)) {
|
||||
printf(" !! request is not tailed with CRLFCRLF but with %x %x %x %x",
|
||||
*(buffer.buffertail-4),
|
||||
*(buffer.buffertail-3),
|
||||
*(buffer.buffertail-2),
|
||||
*(buffer.buffertail-1));
|
||||
LOG_ERRORD((" !! request is not tailed with CRLFCRLF but with %x %x %x %x",
|
||||
*(buffer.buffertail-4),
|
||||
*(buffer.buffertail-3),
|
||||
*(buffer.buffertail-2),
|
||||
*(buffer.buffertail-1)));
|
||||
return false;
|
||||
}
|
||||
|
||||
printf(" parsing initial connect request, dump:\n%.*s\n", (int)buffer.present(), buffer.bufferhead);
|
||||
LOG_DEBUG((" parsing initial connect request, dump:\n%.*s\n", (int)buffer.present(), buffer.bufferhead));
|
||||
|
||||
*result = 400;
|
||||
|
||||
|
@ -284,11 +348,11 @@ bool ReadConnectRequest(server_info_t* server_info,
|
|||
char* _caret;
|
||||
token = strtok2(buffer.bufferhead, " ", &_caret);
|
||||
if (!token) {
|
||||
printf(" no space found");
|
||||
LOG_ERRORD((" no space found"));
|
||||
return true;
|
||||
}
|
||||
if (strcmp(token, "CONNECT")) {
|
||||
printf(" not CONNECT request but %s", token);
|
||||
LOG_ERRORD((" not CONNECT request but %s", token));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -308,7 +372,7 @@ bool ReadConnectRequest(server_info_t* server_info,
|
|||
|
||||
token = strtok2(_caret, "/", &_caret);
|
||||
if (strcmp(token, "HTTP")) {
|
||||
printf(" not tailed with HTTP but with %s", token);
|
||||
LOG_ERRORD((" not tailed with HTTP but with %s", token));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -324,26 +388,26 @@ bool ConfigureSSLServerSocket(PRFileDesc* socket, server_info_t* si, string &cer
|
|||
AutoCert cert(PK11_FindCertFromNickname(
|
||||
certnick, NULL));
|
||||
if (!cert) {
|
||||
fprintf(stderr, "Failed to find cert %s\n", certnick);
|
||||
LOG_ERROR(("Failed to find cert %s\n", certnick));
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoKey privKey(PK11_FindKeyByAnyCert(cert, NULL));
|
||||
if (!privKey) {
|
||||
fprintf(stderr, "Failed to find private key\n");
|
||||
LOG_ERROR(("Failed to find private key\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
PRFileDesc* ssl_socket = SSL_ImportFD(NULL, socket);
|
||||
if (!ssl_socket) {
|
||||
fprintf(stderr, "Error importing SSL socket\n");
|
||||
LOG_ERROR(("Error importing SSL socket\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
SSLKEAType certKEA = NSS_FindCertKEAType(cert);
|
||||
if (SSL_ConfigSecureServer(ssl_socket, cert, privKey, certKEA)
|
||||
!= SECSuccess) {
|
||||
fprintf(stderr, "Error configuring SSL server socket\n");
|
||||
LOG_ERROR(("Error configuring SSL server socket\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -480,7 +544,7 @@ bool AdjustRequestURI(relayBuffer& buffer, string *host)
|
|||
// Cannot use strnchr so add a null char at the end. There is always some space left
|
||||
// because we preserve a margin.
|
||||
buffer.buffertail[1] = '\0';
|
||||
printf(" incoming request to adjust:\n%s\n", buffer.bufferhead);
|
||||
LOG_DEBUG((" incoming request to adjust:\n%s\n", buffer.bufferhead));
|
||||
|
||||
char *token, *path;
|
||||
path = strchr(buffer.bufferhead, ' ') + 1;
|
||||
|
@ -545,10 +609,10 @@ void HandleConnection(void* data)
|
|||
client_auth_option clientAuth;
|
||||
string fullHost;
|
||||
|
||||
printf("SSLTUNNEL(%p): incoming connection csock(0)=%p, ssock(1)=%p\n",
|
||||
LOG_DEBUG(("SSLTUNNEL(%p)): incoming connection csock(0)=%p, ssock(1)=%p\n",
|
||||
static_cast<void*>(data),
|
||||
static_cast<void*>(ci->client_sock),
|
||||
static_cast<void*>(other_sock));
|
||||
static_cast<void*>(other_sock)));
|
||||
if (other_sock)
|
||||
{
|
||||
PRInt32 numberOfSockets = 1;
|
||||
|
@ -577,17 +641,17 @@ void HandleConnection(void* data)
|
|||
{
|
||||
sockets[0].in_flags |= PR_POLL_EXCEPT;
|
||||
sockets[1].in_flags |= PR_POLL_EXCEPT;
|
||||
printf("SSLTUNNEL(%p): polling flags csock(0)=%c%c, ssock(1)=%c%c\n",
|
||||
static_cast<void*>(data),
|
||||
sockets[0].in_flags & PR_POLL_READ ? 'R' : '-',
|
||||
sockets[0].in_flags & PR_POLL_WRITE ? 'W' : '-',
|
||||
sockets[1].in_flags & PR_POLL_READ ? 'R' : '-',
|
||||
sockets[1].in_flags & PR_POLL_WRITE ? 'W' : '-');
|
||||
LOG_DEBUG(("SSLTUNNEL(%p)): polling flags csock(0)=%c%c, ssock(1)=%c%c\n",
|
||||
static_cast<void*>(data),
|
||||
sockets[0].in_flags & PR_POLL_READ ? 'R' : '-',
|
||||
sockets[0].in_flags & PR_POLL_WRITE ? 'W' : '-',
|
||||
sockets[1].in_flags & PR_POLL_READ ? 'R' : '-',
|
||||
sockets[1].in_flags & PR_POLL_WRITE ? 'W' : '-'));
|
||||
PRInt32 pollStatus = PR_Poll(sockets, numberOfSockets, PR_MillisecondsToInterval(1000));
|
||||
if (pollStatus < 0)
|
||||
{
|
||||
printf("SSLTUNNEL(%p): pollStatus=%d, exiting\n",
|
||||
static_cast<void*>(data), pollStatus);
|
||||
LOG_DEBUG(("SSLTUNNEL(%p)): pollStatus=%d, exiting\n",
|
||||
static_cast<void*>(data), pollStatus));
|
||||
client_error = true;
|
||||
break;
|
||||
}
|
||||
|
@ -595,8 +659,8 @@ void HandleConnection(void* data)
|
|||
if (pollStatus == 0)
|
||||
{
|
||||
// timeout
|
||||
printf("SSLTUNNEL(%p): poll timeout, looping\n",
|
||||
static_cast<void*>(data));
|
||||
LOG_DEBUG(("SSLTUNNEL(%p)): poll timeout, looping\n",
|
||||
static_cast<void*>(data)));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -608,15 +672,16 @@ void HandleConnection(void* data)
|
|||
PRInt16 &in_flags2 = sockets[s2].in_flags;
|
||||
sockets[s].out_flags = 0;
|
||||
|
||||
printf("SSLTUNNEL(%p): %csock(%d)=%p out_flags=%d",
|
||||
static_cast<void*>(data),
|
||||
s == 0 ? 'c' : 's',
|
||||
s,
|
||||
static_cast<void*>(sockets[s].fd),
|
||||
out_flags);
|
||||
LOG_BEGIN_BLOCK();
|
||||
LOG_DEBUG(("SSLTUNNEL(%p)): %csock(%d)=%p out_flags=%d",
|
||||
static_cast<void*>(data),
|
||||
s == 0 ? 'c' : 's',
|
||||
s,
|
||||
static_cast<void*>(sockets[s].fd),
|
||||
out_flags));
|
||||
if (out_flags & (PR_POLL_EXCEPT | PR_POLL_ERR | PR_POLL_HUP))
|
||||
{
|
||||
printf(" :exception\n");
|
||||
LOG_DEBUG((" :exception\n"));
|
||||
client_error = true;
|
||||
socketErrorState[s] = PR_TRUE;
|
||||
// We got a fatal error state on the socket. Clear the output buffer
|
||||
|
@ -628,19 +693,19 @@ void HandleConnection(void* data)
|
|||
|
||||
if (out_flags & PR_POLL_READ && !buffers[s].free())
|
||||
{
|
||||
printf(" no place in read buffer but got read flag, dropping it now!");
|
||||
LOG_DEBUG((" no place in read buffer but got read flag, dropping it now!"));
|
||||
in_flags &= ~PR_POLL_READ;
|
||||
}
|
||||
|
||||
if (out_flags & PR_POLL_READ && buffers[s].free())
|
||||
{
|
||||
printf(" :reading");
|
||||
LOG_DEBUG((" :reading"));
|
||||
PRInt32 bytesRead = PR_Recv(sockets[s].fd, buffers[s].buffertail,
|
||||
buffers[s].free(), 0, PR_INTERVAL_NO_TIMEOUT);
|
||||
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
printf(" socket gracefully closed");
|
||||
LOG_DEBUG((" socket gracefully closed"));
|
||||
client_done = true;
|
||||
in_flags &= ~PR_POLL_READ;
|
||||
}
|
||||
|
@ -648,7 +713,7 @@ void HandleConnection(void* data)
|
|||
{
|
||||
if (PR_GetError() != PR_WOULD_BLOCK_ERROR)
|
||||
{
|
||||
printf(" error=%d", PR_GetError());
|
||||
LOG_DEBUG((" error=%d", PR_GetError()));
|
||||
// We are in error state, indicate that the connection was
|
||||
// not closed gracefully
|
||||
client_error = true;
|
||||
|
@ -657,7 +722,7 @@ void HandleConnection(void* data)
|
|||
buffers[s2].bufferhead = buffers[s2].buffertail = buffers[s2].buffer;
|
||||
}
|
||||
else
|
||||
printf(" would block");
|
||||
LOG_DEBUG((" would block"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -665,12 +730,12 @@ void HandleConnection(void* data)
|
|||
// throw this data away and continue loop
|
||||
if (socketErrorState[s2])
|
||||
{
|
||||
printf(" have read but other socket is in error state\n");
|
||||
LOG_DEBUG((" have read but other socket is in error state\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
buffers[s].buffertail += bytesRead;
|
||||
printf(", read %d bytes", bytesRead);
|
||||
LOG_DEBUG((", read %d bytes", bytesRead));
|
||||
|
||||
// We have to accept and handle the initial CONNECT request here
|
||||
PRInt32 response;
|
||||
|
@ -706,7 +771,7 @@ void HandleConnection(void* data)
|
|||
// Store response to the oposite buffer
|
||||
if (response != 200)
|
||||
{
|
||||
printf(" could not read the connect request, closing connection with %d", response);
|
||||
LOG_ERRORD((" could not read the connect request, closing connection with %d", response));
|
||||
client_done = true;
|
||||
sprintf(buffers[s2].buffer, "HTTP/1.1 %d ERROR\r\nConnection: close\r\n\r\n", response);
|
||||
buffers[s2].buffertail = buffers[s2].buffer + strlen(buffers[s2].buffer);
|
||||
|
@ -716,7 +781,7 @@ void HandleConnection(void* data)
|
|||
strcpy(buffers[s2].buffer, "HTTP/1.1 200 Connected\r\nConnection: keep-alive\r\n\r\n");
|
||||
buffers[s2].buffertail = buffers[s2].buffer + strlen(buffers[s2].buffer);
|
||||
|
||||
printf(" accepted CONNECT request, connected to the server, sending OK to the client\n");
|
||||
LOG_DEBUG((" accepted CONNECT request, connected to the server, sending OK to the client\n"));
|
||||
// Send the response to the client socket
|
||||
break;
|
||||
} // end of CONNECT handling
|
||||
|
@ -724,7 +789,7 @@ void HandleConnection(void* data)
|
|||
if (!buffers[s].free())
|
||||
{
|
||||
// Do not poll for read when the buffer is full
|
||||
printf(" no place in our read buffer, stop reading");
|
||||
LOG_DEBUG((" no place in our read buffer, stop reading"));
|
||||
in_flags &= ~PR_POLL_READ;
|
||||
}
|
||||
|
||||
|
@ -747,11 +812,11 @@ void HandleConnection(void* data)
|
|||
addr = &websocket_server;
|
||||
if (!ConnectSocket(other_sock, addr, connect_timeout))
|
||||
{
|
||||
printf(" could not open connection to the real server\n");
|
||||
LOG_ERRORD((" could not open connection to the real server\n"));
|
||||
client_error = true;
|
||||
break;
|
||||
}
|
||||
printf("\n connected to remote server\n");
|
||||
LOG_DEBUG(("\n connected to remote server\n"));
|
||||
numberOfSockets = 2;
|
||||
}
|
||||
}
|
||||
|
@ -762,23 +827,23 @@ void HandleConnection(void* data)
|
|||
}
|
||||
|
||||
in_flags2 |= PR_POLL_WRITE;
|
||||
printf(" telling the other socket to write");
|
||||
LOG_DEBUG((" telling the other socket to write"));
|
||||
}
|
||||
else
|
||||
printf(" we have something for the other socket to write, but ssl has not been administered on it");
|
||||
LOG_DEBUG((" we have something for the other socket to write, but ssl has not been administered on it"));
|
||||
}
|
||||
} // PR_POLL_READ handling
|
||||
|
||||
if (out_flags & PR_POLL_WRITE)
|
||||
{
|
||||
printf(" :writing");
|
||||
LOG_DEBUG((" :writing"));
|
||||
PRInt32 bytesWrite = PR_Send(sockets[s].fd, buffers[s2].bufferhead,
|
||||
buffers[s2].present(), 0, PR_INTERVAL_NO_TIMEOUT);
|
||||
|
||||
if (bytesWrite < 0)
|
||||
{
|
||||
if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
|
||||
printf(" error=%d", PR_GetError());
|
||||
LOG_DEBUG((" error=%d", PR_GetError()));
|
||||
client_error = true;
|
||||
socketErrorState[s] = PR_TRUE;
|
||||
// We got a fatal error while writting the buffer. Clear it to break
|
||||
|
@ -786,56 +851,56 @@ void HandleConnection(void* data)
|
|||
buffers[s2].bufferhead = buffers[s2].buffertail = buffers[s2].buffer;
|
||||
}
|
||||
else
|
||||
printf(" would block");
|
||||
LOG_DEBUG((" would block"));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(", written %d bytes", bytesWrite);
|
||||
LOG_DEBUG((", written %d bytes", bytesWrite));
|
||||
buffers[s2].buffertail[1] = '\0';
|
||||
printf(" dump:\n%.*s\n", bytesWrite, buffers[s2].bufferhead);
|
||||
LOG_DEBUG((" dump:\n%.*s\n", bytesWrite, buffers[s2].bufferhead));
|
||||
|
||||
buffers[s2].bufferhead += bytesWrite;
|
||||
if (buffers[s2].present())
|
||||
{
|
||||
printf(" still have to write %d bytes", (int)buffers[s2].present());
|
||||
LOG_DEBUG((" still have to write %d bytes", (int)buffers[s2].present()));
|
||||
in_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ssl_updated)
|
||||
{
|
||||
printf(" proxy response sent to the client");
|
||||
LOG_DEBUG((" proxy response sent to the client"));
|
||||
// Proxy response has just been writen, update to ssl
|
||||
ssl_updated = true;
|
||||
if (!ci->http_proxy_only &&
|
||||
!ConfigureSSLServerSocket(ci->client_sock, ci->server_info, certificateToUse, clientAuth))
|
||||
{
|
||||
printf(" but failed to config server socket\n");
|
||||
LOG_ERRORD((" failed to config server socket\n"));
|
||||
client_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" client socket updated to SSL");
|
||||
LOG_DEBUG((" client socket updated to SSL"));
|
||||
} // sslUpdate
|
||||
|
||||
printf(" dropping our write flag and setting other socket read flag");
|
||||
LOG_DEBUG((" dropping our write flag and setting other socket read flag"));
|
||||
in_flags &= ~PR_POLL_WRITE;
|
||||
in_flags2 |= PR_POLL_READ;
|
||||
buffers[s2].compact();
|
||||
}
|
||||
}
|
||||
} // PR_POLL_WRITE handling
|
||||
printf("\n"); // end the log
|
||||
LOG_END_BLOCK(); // end the log
|
||||
} // for...
|
||||
} // while, poll
|
||||
}
|
||||
else
|
||||
client_error = true;
|
||||
|
||||
printf("SSLTUNNEL(%p): exiting root function for csock=%p, ssock=%p\n",
|
||||
static_cast<void*>(data),
|
||||
static_cast<void*>(ci->client_sock),
|
||||
static_cast<void*>(other_sock));
|
||||
LOG_DEBUG(("SSLTUNNEL(%p)): exiting root function for csock=%p, ssock=%p\n",
|
||||
static_cast<void*>(data),
|
||||
static_cast<void*>(ci->client_sock),
|
||||
static_cast<void*>(other_sock)));
|
||||
if (!client_error)
|
||||
PR_Shutdown(ci->client_sock, PR_SHUTDOWN_SEND);
|
||||
PR_Close(ci->client_sock);
|
||||
|
@ -856,7 +921,7 @@ void StartServer(void* data)
|
|||
//TODO: select ciphers?
|
||||
AutoFD listen_socket(PR_NewTCPSocket());
|
||||
if (!listen_socket) {
|
||||
fprintf(stderr, "failed to create socket\n");
|
||||
LOG_ERROR(("failed to create socket\n"));
|
||||
SignalShutdown();
|
||||
return;
|
||||
}
|
||||
|
@ -871,19 +936,19 @@ void StartServer(void* data)
|
|||
PRNetAddr server_addr;
|
||||
PR_InitializeNetAddr(PR_IpAddrAny, si->listen_port, &server_addr);
|
||||
if (PR_Bind(listen_socket, &server_addr) != PR_SUCCESS) {
|
||||
fprintf(stderr, "failed to bind socket\n");
|
||||
LOG_ERROR(("failed to bind socket\n"));
|
||||
SignalShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
if (PR_Listen(listen_socket, 1) != PR_SUCCESS) {
|
||||
fprintf(stderr, "failed to listen on socket\n");
|
||||
LOG_ERROR(("failed to listen on socket\n"));
|
||||
SignalShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Server listening on port %d with cert %s\n", si->listen_port,
|
||||
si->cert_nickname.c_str());
|
||||
LOG_INFO(("Server listening on port %d with cert %s\n", si->listen_port,
|
||||
si->cert_nickname.c_str()));
|
||||
|
||||
while (!shutdown_server) {
|
||||
connection_info_t* ci = new connection_info_t();
|
||||
|
@ -949,13 +1014,13 @@ int processConfigLine(char* configLine)
|
|||
{
|
||||
char* ipstring = strtok2(_caret, ":", &_caret);
|
||||
if (PR_StringToNetAddr(ipstring, &websocket_server) != PR_SUCCESS) {
|
||||
fprintf(stderr, "Invalid IP address in proxy config: %s\n", ipstring);
|
||||
LOG_ERROR(("Invalid IP address in proxy config: %s\n", ipstring));
|
||||
return 1;
|
||||
}
|
||||
char* remoteport = strtok2(_caret, ":", &_caret);
|
||||
int port = atoi(remoteport);
|
||||
if (port <= 0) {
|
||||
fprintf(stderr, "Invalid remote port in proxy config: %s\n", remoteport);
|
||||
LOG_ERROR(("Invalid remote port in proxy config: %s\n", remoteport));
|
||||
return 1;
|
||||
}
|
||||
websocket_server.inet.port = PR_htons(port);
|
||||
|
@ -967,13 +1032,13 @@ int processConfigLine(char* configLine)
|
|||
{
|
||||
char* ipstring = strtok2(_caret, ":", &_caret);
|
||||
if (PR_StringToNetAddr(ipstring, &remote_addr) != PR_SUCCESS) {
|
||||
fprintf(stderr, "Invalid remote IP address: %s\n", ipstring);
|
||||
LOG_ERROR(("Invalid remote IP address: %s\n", ipstring));
|
||||
return 1;
|
||||
}
|
||||
char* serverportstring = strtok2(_caret, ":", &_caret);
|
||||
int port = atoi(serverportstring);
|
||||
if (port <= 0) {
|
||||
fprintf(stderr, "Invalid remote port: %s\n", serverportstring);
|
||||
LOG_ERROR(("Invalid remote port: %s\n", serverportstring));
|
||||
return 1;
|
||||
}
|
||||
remote_addr.inet.port = PR_htons(port);
|
||||
|
@ -997,7 +1062,7 @@ int processConfigLine(char* configLine)
|
|||
|
||||
int port = atoi(serverportstring);
|
||||
if (port <= 0) {
|
||||
fprintf(stderr, "Invalid port specified: %s\n", serverportstring);
|
||||
LOG_ERROR(("Invalid port specified: %s\n", serverportstring));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1013,7 +1078,7 @@ int processConfigLine(char* configLine)
|
|||
|
||||
PLHashEntry* entry = PL_HashTableAdd(existingServer->host_cert_table, hostname_copy, certnick_copy);
|
||||
if (!entry) {
|
||||
fprintf(stderr, "Out of memory");
|
||||
LOG_ERROR(("Out of memory"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1025,13 +1090,13 @@ int processConfigLine(char* configLine)
|
|||
server.host_cert_table = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL);
|
||||
if (!server.host_cert_table)
|
||||
{
|
||||
fprintf(stderr, "Internal, could not create hash table\n");
|
||||
LOG_ERROR(("Internal, could not create hash table\n"));
|
||||
return 1;
|
||||
}
|
||||
server.host_clientauth_table = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, ClientAuthValueComparator, NULL, NULL);
|
||||
if (!server.host_clientauth_table)
|
||||
{
|
||||
fprintf(stderr, "Internal, could not create hash table\n");
|
||||
LOG_ERROR(("Internal, could not create hash table\n"));
|
||||
return 1;
|
||||
}
|
||||
servers.push_back(server);
|
||||
|
@ -1048,7 +1113,7 @@ int processConfigLine(char* configLine)
|
|||
|
||||
int port = atoi(serverportstring);
|
||||
if (port <= 0) {
|
||||
fprintf(stderr, "Invalid port specified: %s\n", serverportstring);
|
||||
LOG_ERROR(("Invalid port specified: %s\n", serverportstring));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1122,7 @@ int processConfigLine(char* configLine)
|
|||
char* authoptionstring = strtok2(_caret, ":", &_caret);
|
||||
client_auth_option* authoption = new client_auth_option;
|
||||
if (!authoption) {
|
||||
fprintf(stderr, "Out of memory");
|
||||
LOG_ERROR(("Out of memory"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1069,7 +1134,7 @@ int processConfigLine(char* configLine)
|
|||
*authoption = caNone;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Incorrect client auth option modifier for host '%s'", hostname);
|
||||
LOG_ERROR(("Incorrect client auth option modifier for host '%s'", hostname));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1077,7 +1142,7 @@ int processConfigLine(char* configLine)
|
|||
|
||||
char *hostname_copy = new char[strlen(hostname)+strlen(hostportstring)+2];
|
||||
if (!hostname_copy) {
|
||||
fprintf(stderr, "Out of memory");
|
||||
LOG_ERROR(("Out of memory"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1087,13 +1152,13 @@ int processConfigLine(char* configLine)
|
|||
|
||||
PLHashEntry* entry = PL_HashTableAdd(existingServer->host_clientauth_table, hostname_copy, authoption);
|
||||
if (!entry) {
|
||||
fprintf(stderr, "Out of memory");
|
||||
LOG_ERROR(("Out of memory"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Server on port %d for client authentication option is not defined, use 'listen' option first", port);
|
||||
LOG_ERROR(("Server on port %d for client authentication option is not defined, use 'listen' option first", port));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1107,7 +1172,7 @@ int processConfigLine(char* configLine)
|
|||
return 0;
|
||||
}
|
||||
|
||||
printf("Error: keyword \"%s\" unexpected\n", keyword);
|
||||
LOG_ERROR(("Error: keyword \"%s\" unexpected\n", keyword));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1141,13 +1206,13 @@ int parseConfigFile(const char* filePath)
|
|||
// Check mandatory items
|
||||
if (nssconfigdir.empty())
|
||||
{
|
||||
printf("Error: missing path to NSS certification database\n,use certdbdir:<path> in the config file\n");
|
||||
LOG_ERROR(("Error: missing path to NSS certification database\n,use certdbdir:<path> in the config file\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (any_host_spec_config && !do_http_proxy)
|
||||
{
|
||||
printf("Warning: any host-specific configurations are ignored, add httpproxy:1 to allow them\n");
|
||||
LOG_ERROR(("Warning: any host-specific configurations are ignored, add httpproxy:1 to allow them\n"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1170,6 +1235,10 @@ PRIntn freeClientAuthHashItems(PLHashEntry *he, PRIntn i, void *arg)
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* configFilePath;
|
||||
|
||||
const char* logLevelEnv = PR_GetEnv("SSLTUNNEL_LOG_LEVEL");
|
||||
gLogLevel = logLevelEnv ? (LogLevel)atoi(logLevelEnv) : LEVEL_INFO;
|
||||
|
||||
if (argc == 1)
|
||||
configFilePath = "ssltunnel.cfg";
|
||||
else
|
||||
|
@ -1178,7 +1247,7 @@ int main(int argc, char** argv)
|
|||
memset(&websocket_server, 0, sizeof(PRNetAddr));
|
||||
|
||||
if (parseConfigFile(configFilePath)) {
|
||||
fprintf(stderr, "Error: config file \"%s\" missing or formating incorrect\n"
|
||||
LOG_ERROR(("Error: config file \"%s\" missing or formating incorrect\n"
|
||||
"Specify path to the config file as parameter to ssltunnel or \n"
|
||||
"create ssltunnel.cfg in the working directory.\n\n"
|
||||
"Example format of the config file:\n\n"
|
||||
|
@ -1207,7 +1276,7 @@ int main(int argc, char** argv)
|
|||
" # Proxy WebSocket traffic to the server at 127.0.0.1:9999,\n"
|
||||
" # instead of the server specified in the 'forward' option.\n"
|
||||
" websocketserver:127.0.0.1:9999\n",
|
||||
configFilePath);
|
||||
configFilePath));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1216,19 +1285,19 @@ int main(int argc, char** argv)
|
|||
PR_MAX(MAX_THREADS, servers.size()*2),
|
||||
DEFAULT_STACKSIZE);
|
||||
if (!threads) {
|
||||
fprintf(stderr, "Failed to create thread pool\n");
|
||||
LOG_ERROR(("Failed to create thread pool\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
shutdown_lock = PR_NewLock();
|
||||
if (!shutdown_lock) {
|
||||
fprintf(stderr, "Failed to create lock\n");
|
||||
LOG_ERROR(("Failed to create lock\n"));
|
||||
PR_ShutdownThreadPool(threads);
|
||||
return 1;
|
||||
}
|
||||
shutdown_condvar = PR_NewCondVar(shutdown_lock);
|
||||
if (!shutdown_condvar) {
|
||||
fprintf(stderr, "Failed to create condvar\n");
|
||||
LOG_ERROR(("Failed to create condvar\n"));
|
||||
PR_ShutdownThreadPool(threads);
|
||||
PR_DestroyLock(shutdown_lock);
|
||||
return 1;
|
||||
|
@ -1241,7 +1310,7 @@ int main(int argc, char** argv)
|
|||
PRInt32 errorlen = PR_GetErrorTextLength();
|
||||
char* err = new char[errorlen+1];
|
||||
PR_GetErrorText(err);
|
||||
fprintf(stderr, "Failed to init NSS: %s", err);
|
||||
LOG_ERROR(("Failed to init NSS: %s", err));
|
||||
delete[] err;
|
||||
PR_ShutdownThreadPool(threads);
|
||||
PR_DestroyCondVar(shutdown_condvar);
|
||||
|
@ -1250,7 +1319,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
if (NSS_SetDomesticPolicy() != SECSuccess) {
|
||||
fprintf(stderr, "NSS_SetDomesticPolicy failed\n");
|
||||
LOG_ERROR(("NSS_SetDomesticPolicy failed\n"));
|
||||
PR_ShutdownThreadPool(threads);
|
||||
PR_DestroyCondVar(shutdown_condvar);
|
||||
PR_DestroyLock(shutdown_lock);
|
||||
|
@ -1260,7 +1329,7 @@ int main(int argc, char** argv)
|
|||
|
||||
// these values should make NSS use the defaults
|
||||
if (SSL_ConfigServerSessionIDCache(0, 0, 0, NULL) != SECSuccess) {
|
||||
fprintf(stderr, "SSL_ConfigServerSessionIDCache failed\n");
|
||||
LOG_ERROR(("SSL_ConfigServerSessionIDCache failed\n"));
|
||||
PR_ShutdownThreadPool(threads);
|
||||
PR_DestroyCondVar(shutdown_condvar);
|
||||
PR_DestroyLock(shutdown_lock);
|
||||
|
@ -1279,14 +1348,14 @@ int main(int argc, char** argv)
|
|||
PR_WaitCondVar(shutdown_condvar, PR_INTERVAL_NO_TIMEOUT);
|
||||
PR_Unlock(shutdown_lock);
|
||||
shutdown_server = true;
|
||||
printf("Shutting down...\n");
|
||||
LOG_INFO(("Shutting down...\n"));
|
||||
// cleanup
|
||||
PR_ShutdownThreadPool(threads);
|
||||
PR_JoinThreadPool(threads);
|
||||
PR_DestroyCondVar(shutdown_condvar);
|
||||
PR_DestroyLock(shutdown_lock);
|
||||
if (NSS_Shutdown() == SECFailure) {
|
||||
fprintf(stderr, "Leaked NSS objects!\n");
|
||||
LOG_DEBUG(("Leaked NSS objects!\n"));
|
||||
}
|
||||
|
||||
for (vector<server_info_t>::iterator it = servers.begin();
|
||||
|
|
Загрузка…
Ссылка в новой задаче