#include #include "dns.h" // NSPR include files #include #include #include #include #include // NSS include files #include #include #include #include #include #include // Qt-dependent Include Files, should come after NSPR / NSS #include "ui.h" #include "irc.h" NSSInitContext *nssContext; SECMODModule *builtInRootsMod; // PK11 Password Function typedef typedef char *(*PK11PasswordFunc)( PK11SlotInfo *slot, PRBool retry, void *arg); void init() { // NSPR Init PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); // NSS Init nssContext = NSS_InitContext("sql:/etc/pki/nssdb", "", "", "", NULL, NSS_INIT_READONLY | NSS_INIT_PK11RELOAD); if (nssContext == NULL) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "NSSInitContext failed: Error code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } // Ciphers to enable static const PRUint16 goodCiphers[] = { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_NULL_WITH_NULL_NULL // Sentinel value }; PRBool foundGoodCipher = PR_FALSE; for (const PRUint16 *p = goodCiphers; *p != SSL_NULL_WITH_NULL_NULL; ++p) { PRInt32 policy; if (SSL_CipherPolicyGet(*p, &policy) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error: Policy for cipher %u: error %d: %s\n", (unsigned) *p, err, PR_ErrorToName(err)); exit(1); } if (policy == SSL_ALLOWED) { // Policy allowed this cipher choice // fprintf(stderr, "Info: found cipher %x\n", (unsigned) *p); foundGoodCipher = PR_TRUE; break; } } if (!foundGoodCipher) { if (NSS_SetDomesticPolicy() != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error: NSS_SetDomesticPolicy: error %d: %s\n", err, PR_ErrorToName(err)); exit(1); } } // Initialize trusted certificate store char module_name[] = "library=libnssckbi.so name=\"Root Certs\""; builtInRootsMod = SECMOD_LoadUserModule(module_name, NULL, PR_FALSE); if (builtInRootsMod == NULL || !builtInRootsMod->loaded) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error: Loading built in roots module failed, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } } void runIrc(void* args) { irc* ircInst = (irc *) args; ircInst->run(); } int main(int argc, char *argv[]) { init(); PRNetAddr theAddr; LookupName((char *) "buyvm.theoks.net", &theAddr); char ipString[80]; PRStatus status = PR_NetAddrToString(&theAddr, ipString, 75); if (status == PR_FAILURE) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error: Converting PRNetAddr to string %d: %s\n", err, PR_ErrorToName(err)); exit(1); } PRFileDesc *tcpSocket = PR_OpenTCPSocket(PR_AF_INET6); PRFileDesc *model = PR_NewTCPSocket(); theAddr.ipv6.port = PR_htons(6697); theAddr.raw.family = PR_AF_INET6; PRFileDesc *nssSocket; PRFileDesc *sslModel = SSL_ImportFD(NULL, model); // Set SSL options if(SSL_OptionSet(sslModel, SSL_ENABLE_SSL2, PR_FALSE) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error disabling SSLv2, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if(SSL_OptionSet(sslModel, SSL_V2_COMPATIBLE_HELLO, PR_FALSE) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error disabling SSLv2 compatible hello, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if(SSL_OptionSet(sslModel, SSL_ENABLE_SSL3, PR_FALSE) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error disabling SSLv3, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if(SSL_OptionSet(sslModel, SSL_ENABLE_TLS, PR_TRUE) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error enabling TLS, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } // Open base TCP connection if(PR_Connect(tcpSocket, &theAddr, PR_INTERVAL_NO_TIMEOUT) != PR_SUCCESS) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error opening TCP connection, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } // Wrap TCP connection with SSL layer nssSocket = SSL_ImportFD(sslModel, tcpSocket); if(nssSocket == nullptr) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error importing TCP Socket to NSS, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } PR_Close(model); // Do the handshake if(SSL_ResetHandshake(nssSocket, PR_FALSE) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Failed resetting handshake, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if(SSL_SetURL(nssSocket, "buyvm.theoks.net") != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error setting domain for connection, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } if(SSL_ForceHandshake(nssSocket) != SECSuccess) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error forcing handshake, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } ui *uiInstance = new ui(argc, argv); char netBuf[8192]; irc *ircInst = new irc(nssSocket, "OKSnet", uiInstance); PRThread* ircThread = PR_CreateThread(PR_SYSTEM_THREAD, runIrc, ircInst, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); // TEMP: Retreiving test file from HTTP daemon w/ TLS // Send the request snprintf(netBuf, sizeof(netBuf), "GET /junk/testfile.txt HTTP/1.0\r\nHost: buyvm.theoks.net\r\nUser-Agent: oksirc-testing\r\n\r\n"); PRInt32 ret = PR_Write(nssSocket, netBuf, strlen(netBuf)); if(ret < 0) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error writing data to socket, code %d: %s\n", err, PR_ErrorToName(err)); uiInstance->mainLog->appendPlainText("Error writing data to socket, see stderr."); } // Get the response ret = PR_Read(nssSocket, netBuf, sizeof(netBuf)); if(ret < 0) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error reading data from socket, code %d: %s\n", err, PR_ErrorToName(err)); uiInstance->mainLog->appendPlainText("Error writing data from socket, see stderr."); } else { printf("%s\n", netBuf); uiInstance->mainLog->appendPlainText(netBuf); } if(PR_Shutdown(nssSocket, PR_SHUTDOWN_BOTH) != PR_SUCCESS) { const PRErrorCode err = PR_GetError(); fprintf(stderr, "Error shutting down socket, code %d: %s\n", err, PR_ErrorToName(err)); exit(1); } PR_Close(nssSocket); char messageBuf[1024]; sprintf(messageBuf, "Found IP Address: %s", ipString); uiInstance->mainLog->appendPlainText(messageBuf); fprintf(stderr, "argc = %d, strlen(argv[0]) = %d\n", argc, (int)strlen(argv[0])); int qAppRetCode = uiInstance->exec(); // Shutdown of NSS SECMOD_DestroyModule(builtInRootsMod); NSS_ShutdownContext(nssContext); return qAppRetCode; }