Ejemplo n.º 1
0
/**
 * Throws NSPRException upon NSPR error
 */
PRFileDesc *Connection::createSocket(const PRNetAddr& address, bool useSSL,
				     const std::string &certDBPasswd,
				     const std::string &certNickName,
				     bool alwaysTrustServerCert) 
{
    PRFileDesc *rawSocket = PR_NewTCPSocket();
    
    if (tcp_nodelay_is_enabled) {
	   // set the TCP_NODELAY option to disable Nagle algorithm
	   PRSocketOptionData socket_opt;
	   socket_opt.option = PR_SockOpt_NoDelay;
	   socket_opt.value.no_delay = PR_TRUE;
	   PRStatus prStatus = PR_SetSocketOption(rawSocket, &socket_opt);
	   if (PR_SUCCESS != prStatus) {
	       throw NSPRException("Connection::Connection", "PR_SetSocketOption");
	   }
    }
    
    PRFileDesc *sslSocket;
    if (certDBPasswd.size() > 0) {
        certdbpasswd = strdup(certDBPasswd.c_str());
     }

    if (static_cast<PRFileDesc *>(NULL) != rawSocket) {
	if (useSSL) {
		sslSocket = secureSocket(certDBPasswd, certNickName, alwaysTrustServerCert, rawSocket);
	} else {
	    sslSocket = rawSocket;
	}
    } else {
	throw NSPRException("Connection::createSocket", "PR_NewTCPSocket");
    }

    return sslSocket;
}
Ejemplo n.º 2
0
/**
 * Throws NSPRException upon NSPR error
 */
Connection::Connection(const ServerInfo& server,
		       const std::string &certDBPasswd,
		       const std::string &certNickName,
		       bool alwaysTrustServerCert) 
    : socket(NULL), certdbpasswd(NULL), certnickname(NULL)
{
    char      buffer[PR_NETDB_BUF_SIZE];
    PRNetAddr address;
    PRHostEnt hostEntry;
    PRIntn    hostIndex;
    PRStatus	prStatus;
    SECStatus	secStatus;

    prStatus = PR_GetHostByName(server.getHost().c_str(), buffer,
				sizeof(buffer), &hostEntry);
    if (PR_SUCCESS != prStatus) {
        throw NSPRException("Connection::Connection", "PR_GetHostByName");
    }

    hostIndex = PR_EnumerateHostEnt(0, &hostEntry, server.getPort(), &address);
    if (hostIndex < 0) {
        throw NSPRException("Connection::Connection", "PR_EnumerateHostEnt");
    }

    socket = createSocket(address, server.useSSL(),
			  certDBPasswd,
			  certNickName,
			  alwaysTrustServerCert);

    if (server.useSSL()) {
	secStatus = SSL_SetURL(socket, server.getHost().c_str());
	if (SECSuccess != secStatus) {
	    PRErrorCode error = PR_GetError();

	    PR_Shutdown(socket, PR_SHUTDOWN_BOTH);
	    PR_Close(socket);
	    Log::log(Log::ALL_MODULES, Log::LOG_ERROR,
		     "SSL_SetURL() returned error: %s",
		     PR_ErrorToString(error, PR_LANGUAGE_I_DEFAULT));
	    throw NSPRException("Connection::Connection",
				"SSL_SetURL", error);
	}
    }

    prStatus = PR_Connect(socket, &address, connect_timeout);

    if (prStatus != PR_SUCCESS) {
	PRErrorCode error = PR_GetError();

	PR_Shutdown(socket, PR_SHUTDOWN_BOTH);
	PR_Close(socket);
	throw NSPRException("Connection::Connection PR_Connect", "PR_Connect", error);
    }
}
Ejemplo n.º 3
0
am_status_t Connection::read(char *buffer, std::size_t& bufferLen)
{
    am_status_t status = AM_SUCCESS;
    PRInt32 bytesRead;
    PRInt32 bytesToRead;

    if (bufferLen > static_cast<std::size_t>(MAX_READ_WRITE_LEN)) {
	bytesToRead = MAX_READ_WRITE_LEN;
    } else {
	bytesToRead = static_cast<PRInt32>(bufferLen);
    }

    bytesRead = PR_Recv(socket, buffer, bytesToRead, 0, receive_timeout);
    if (bytesRead < 0) {
	status = AM_NSPR_ERROR;
	PRErrorCode error = PR_GetError();
	Log::log(Log::ALL_MODULES, Log::LOG_ERROR,
		 "Connection::read(): NSPR Error while reading data:%d", 
		 PR_GetError());
	if (error == PR_IO_TIMEOUT_ERROR || error == PR_CONNECT_RESET_ERROR ||
	    error == PR_CONNECT_REFUSED_ERROR ||
            error == PR_NETWORK_DOWN_ERROR ||
            error == PR_NETWORK_UNREACHABLE_ERROR || 
            error == PR_HOST_UNREACHABLE_ERROR) {
                throw NSPRException("Connection::read()", "PR_Recv");
	}
    } else {
	bufferLen = static_cast<std::size_t>(bytesRead);
    }

    return status;
}
Ejemplo n.º 4
0
/**
 * Throws: 
 *	std::bad_alloc if no memory. 
 *	NSPRException if NSPR error. 
 *	ParseException upon parse error.
 */
Http::Response::Response(Log::ModuleId logModule, Connection& conn)
    : httpStatus(INVALID), cookieList(), extraHdrs(), bodyPtr(NULL), bodyLen(0)
{
    am_status_t status;

    status = readAndParse(logModule, conn);

    if (AM_SUCCESS != status) {
	if (AM_NO_MEMORY == status) {
	    throw std::bad_alloc();
	} else if (AM_NSPR_ERROR == status) {
	    throw NSPRException("Http::Response()", "Connection::receiveData");
	} else {
	    throw ParseException(status);
	}
    }
}
Ejemplo n.º 5
0
/**
 * Performs SSL handshake on a TCP socket.
 */
PRFileDesc *Connection::secureSocket(const std::string &certDBPasswd,
	const std::string &certNickName,
	bool alwaysTrustServerCert,
	PRFileDesc *rawSocket) {
	bool upgradeExisting = false;
	// Use object's socket if none passed
	if (rawSocket == static_cast<PRFileDesc *>(NULL)) {
		rawSocket = socket;
		upgradeExisting = true;
	}
	PRFileDesc *sslSocket = SSL_ImportFD(NULL, rawSocket);
	if (static_cast<PRFileDesc *>(NULL) != sslSocket) {
	    SECStatus secStatus = SECSuccess;
	    const char *sslMethodName;
	
	    // In case there was any communication on the socket
	    // before the upgrade we should call a reset
	    if (upgradeExisting) {
                sslMethodName = "SSL_ResetHandshake";
                secStatus = SSL_ResetHandshake(sslSocket, false);
	    }

	    if (SECSuccess == secStatus) {
                sslMethodName = "SSL_OptionSet";
                secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE);
	    }

	    if (SECSuccess == secStatus) {
                secStatus = SSL_OptionSet(sslSocket,
                                      SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
                if (SECSuccess == secStatus && alwaysTrustServerCert) {
                    sslMethodName = "SSL_AuthCertificateHook";
                    secStatus = SSL_AuthCertificateHook(sslSocket, acceptAnyCert,
                                                    NULL);
                }

                if (SECSuccess == secStatus && certDBPasswd.size() > 0) {
                    sslMethodName = "SSL_SetPKCS11PinArg";
                    secStatus = SSL_SetPKCS11PinArg(sslSocket, certdbpasswd);
                }

                if (SECSuccess == secStatus) {
		    if (certNickName.size() > 0) {
                        certnickname = strdup(certNickName.c_str());
                    }
                    sslMethodName = "SSL_GetClientAuthDataHook";
                    secStatus = SSL_GetClientAuthDataHook(sslSocket,
                                                   NSS_GetClientAuthData,
                                                   static_cast<void *>(certnickname));
                }

                if (SECSuccess == secStatus) {
                    sslMethodName = "SSL_HandshakeCallback";
                    secStatus = SSL_HandshakeCallback(sslSocket,
                                (SSLHandshakeCallback)finishedHandshakeHandler,
                                 NULL);
		}
	    }

	    if (SECSuccess != secStatus) {
		PRErrorCode error = PR_GetError();

		PR_Close(sslSocket);
		throw NSPRException("Connection::secureSocket",
				sslMethodName, error);
	    }
	} else {
	    PRErrorCode error = PR_GetError();

	    PR_Close(rawSocket);
	    throw NSPRException("Connection::secureSocket", "SSL_ImportFD",
				error);
	}

	socket = sslSocket;
	return sslSocket;
}