void disableAllSSLCiphers(void) { const PRUint16 *cipherSuites = SSL_GetImplementedCiphers(); int i = SSL_GetNumImplementedCiphers(); SECStatus rv; /* disable all the SSL3 cipher suites */ while (--i >= 0) { PRUint16 suite = cipherSuites[i]; rv = SSL_CipherPrefSetDefault(suite, PR_FALSE); if (rv != SECSuccess) { printf("SSL_CipherPrefSetDefault didn't like value 0x%04x (i = %d)\n", suite, i); errWarn("SSL_CipherPrefSetDefault"); exit(2); } } }
int __pmSecureServerInit(void) { const PRUint16 *cipher; SECStatus secsts; int pathSpecified; int sts = 0; PM_INIT_LOCKS(); PM_LOCK(secureserver_lock); /* Only attempt this once. */ if (secure_server.initialized) goto done; secure_server.initialized = 1; if (PR_Initialized() != PR_TRUE) PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); /* Configure optional (cmdline) password file in case DB locked */ PK11_SetPasswordFunc(certificate_database_password); /* * Configure location of the NSS database with a sane default. * For servers, we default to the shared (sql) system-wide database. * If command line db specified, pass it directly through - allowing * any old database format, at the users discretion. */ if (!secure_server.database_path[0]) { const char *path; pathSpecified = 0; path = serverdb(secure_server.database_path, MAXPATHLEN, "sql:"); /* this is the default case on some platforms, so no log spam */ if (access(path, R_OK|X_OK) < 0) { if (pmDebugOptions.context) pmNotifyErr(LOG_INFO, "Cannot access system security database: %s", secure_server.database_path); sts = -EOPNOTSUPP; /* not fatal - just no secure connections */ secure_server.init_failed = 1; goto done; } } else pathSpecified = 1; /* * pmproxy acts as both a client and server. Since the * server init path happens first, the db previously * got opened readonly. Instead try to open RW. * Fallback if there is an error. */ secsts = NSS_InitReadWrite(secure_server.database_path); if( secsts != SECSuccess ) secsts = NSS_Init(secure_server.database_path); if (secsts != SECSuccess && !pathSpecified) { /* fallback, older versions of NSS do not support sql: */ serverdb(secure_server.database_path, MAXPATHLEN, ""); secsts = NSS_Init(secure_server.database_path); } if (secsts != SECSuccess) { pmNotifyErr(LOG_ERR, "Cannot setup certificate DB (%s): %s", secure_server.database_path, pmErrStr(__pmSecureSocketsError(PR_GetError()))); sts = -EOPNOTSUPP; /* not fatal - just no secure connections */ secure_server.init_failed = 1; goto done; } /* Some NSS versions don't do this correctly in NSS_SetDomesticPolicy. */ for (cipher = SSL_GetImplementedCiphers(); *cipher != 0; ++cipher) SSL_CipherPolicySet(*cipher, SSL_ALLOWED); /* Configure SSL session cache for multi-process server, using defaults */ secsts = SSL_ConfigMPServerSIDCache(1, 0, 0, NULL); if (secsts != SECSuccess) { pmNotifyErr(LOG_ERR, "Unable to configure SSL session ID cache: %s", pmErrStr(__pmSecureSocketsError(PR_GetError()))); sts = -EOPNOTSUPP; /* not fatal - just no secure connections */ secure_server.init_failed = 1; goto done; } else { secure_server.ssl_session_cache_setup = 1; } /* * Iterate over any/all PCP Collector nickname certificates, * seeking one valid certificate. No-such-nickname is not an * error (not configured by admin at all) but anything else is. */ CERTCertList *certlist; CERTCertDBHandle *nssdb = CERT_GetDefaultCertDB(); CERTCertificate *dbcert = PK11_FindCertFromNickname(secure_server.cert_nickname, NULL); if (dbcert) { PRTime now = PR_Now(); SECItem *name = &dbcert->derSubject; CERTCertListNode *node; certlist = CERT_CreateSubjectCertList(NULL, nssdb, name, now, PR_FALSE); if (certlist) { for (node = CERT_LIST_HEAD(certlist); !CERT_LIST_END(node, certlist); node = CERT_LIST_NEXT (node)) { if (pmDebugOptions.context) __pmDumpCertificate(stderr, secure_server.cert_nickname, node->cert); if (!__pmValidCertificate(nssdb, node->cert, now)) continue; secure_server.certificate_verified = 1; break; } CERT_DestroyCertList(certlist); } if (secure_server.certificate_verified) { secure_server.certificate_KEA = NSS_FindCertKEAType(dbcert); secure_server.private_key = PK11_FindKeyByAnyCert(dbcert, NULL); if (!secure_server.private_key) { pmNotifyErr(LOG_ERR, "Unable to extract %s private key", secure_server.cert_nickname); CERT_DestroyCertificate(dbcert); secure_server.certificate_verified = 0; sts = -EOPNOTSUPP; /* not fatal - just no secure connections */ secure_server.init_failed = 1; goto done; } } else { pmNotifyErr(LOG_ERR, "Unable to find a valid %s", secure_server.cert_nickname); CERT_DestroyCertificate(dbcert); sts = -EOPNOTSUPP; /* not fatal - just no secure connections */ secure_server.init_failed = 1; goto done; } } if (! secure_server.certificate_verified) { if (pmDebugOptions.context) { pmNotifyErr(LOG_INFO, "No valid %s in security database: %s", secure_server.cert_nickname, secure_server.database_path); } sts = -EOPNOTSUPP; /* not fatal - just no secure connections */ secure_server.init_failed = 1; goto done; } secure_server.certificate = dbcert; secure_server.init_failed = 0; sts = 0; done: PM_UNLOCK(secureserver_lock); return sts; }