static int load_server_libs (const char *dir) { int rv = LDAPU_SUCCESS; PRDir* ds; int suffix_len = strlen(DLL_SUFFIX); if ((ds = PR_OpenDir(dir)) != NULL) { PRDirEntry *d; /* Dir exists */ while( (d = PR_ReadDir(ds, PR_SKIP_BOTH)) ) { PRLibrary *lib = 0; const char *libname = d->name; int len = strlen(libname); int is_lib; is_lib = (len > suffix_len && !strcmp(libname+len-suffix_len, DLL_SUFFIX)); if(is_lib) { char path[1024]; PR_snprintf(path, sizeof(path), "%s%c%s", dir, FILE_PATHSEP, libname); lib = PR_LoadLibrary(path); if (!lib) rv = LDAPU_ERR_UNABLE_TO_LOAD_PLUGIN; } } } else { /* It's ok if dir doesn't exists */ } return rv; }
std::string CommandEventHandler::ls(std::vector<std::string>& args) { std::string path(args.size() ? args[0] : ""); if (path.compare("") == 0) path = "."; std::ostringstream out; std::string ret = isDir(path); if (ret.compare("TRUE") != 0) { if (ret.compare("FALSE") == 0) return agentWarn("path is not a dir"); return ret; } PRDir *dir = PR_OpenDir(path.c_str()); PRDirEntry *entry = PR_ReadDir(dir, PR_SKIP_BOTH); while (entry) { out << std::string(entry->name) << ENDL; entry = PR_ReadDir(dir, PR_SKIP_BOTH); } if (PR_CloseDir(dir) != PR_SUCCESS) return agentWarn("could not close dir object"); std::string output = out.str(); if (output.size()) output.erase(output.size() - 1); // erase the extra newline return output; }
//---------------------------------------------------------------------------------------- nsDirectoryIterator::nsDirectoryIterator(const nsFileSpec& inDirectory, PRBool resolveSymlink) //---------------------------------------------------------------------------------------- : mCurrent(inDirectory) , mDir(nsnull) , mStarting(inDirectory) , mExists(PR_FALSE) , mResoveSymLinks(resolveSymlink) { mDir = PR_OpenDir(inDirectory); mCurrent += "dummy"; mStarting += "dummy"; ++(*this); } // nsDirectoryIterator::nsDirectoryIterator
static CURLcode nss_load_ca_certificates(struct connectdata *conn, int sockindex) { struct SessionHandle *data = conn->data; const char *cafile = data->set.ssl.CAfile; const char *capath = data->set.ssl.CApath; if(cafile) { CURLcode rv = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE); if(CURLE_OK != rv) return rv; } if(capath) { struct_stat st; if(stat(capath, &st) == -1) return CURLE_SSL_CACERT_BADFILE; if(S_ISDIR(st.st_mode)) { PRDirEntry *entry; PRDir *dir = PR_OpenDir(capath); if(!dir) return CURLE_SSL_CACERT_BADFILE; while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) { char *fullpath = aprintf("%s/%s", capath, entry->name); if(!fullpath) { PR_CloseDir(dir); return CURLE_OUT_OF_MEMORY; } if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE)) /* This is purposefully tolerant of errors so non-PEM files can * be in the same directory */ infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath); free(fullpath); } PR_CloseDir(dir); } else infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath); } infof(data, " CAfile: %s\n CApath: %s\n", cafile ? cafile : "none", capath ? capath : "none"); return CURLE_OK; }
SECStatus LoadCertificatesAndKeys(const char* basePath) { // The NSS cert DB path could have been specified as "sql:path". Trim off // the leading "sql:" if so. if (strncmp(basePath, "sql:", 4) == 0) { basePath = basePath + 4; } UniquePRDir fdDir(PR_OpenDir(basePath)); if (!fdDir) { PrintPRError("PR_OpenDir failed"); return SECFailure; } // On the B2G ICS emulator, operations taken in AddCertificateFromFile // appear to interact poorly with readdir (more specifically, something is // causing readdir to never return null - it indefinitely loops through every // file in the directory, which causes timeouts). Rather than waste more time // chasing this down, loading certificates and keys happens in two phases: // filename collection and then loading. (This is probably a good // idea anyway because readdir isn't reentrant. Something could change later // such that it gets called as a result of calling AddCertificateFromFile or // AddKeyFromFile.) std::vector<std::string> certificates; std::vector<std::string> keys; for (PRDirEntry* dirEntry = PR_ReadDir(fdDir.get(), PR_SKIP_BOTH); dirEntry; dirEntry = PR_ReadDir(fdDir.get(), PR_SKIP_BOTH)) { size_t nameLength = strlen(dirEntry->name); if (nameLength > 4) { if (strncmp(dirEntry->name + nameLength - 4, ".pem", 4) == 0) { certificates.push_back(dirEntry->name); } else if (strncmp(dirEntry->name + nameLength - 4, ".key", 4) == 0) { keys.push_back(dirEntry->name); } } } SECStatus rv; for (std::string& certificate : certificates) { rv = AddCertificateFromFile(basePath, certificate.c_str()); if (rv != SECSuccess) { return rv; } } for (std::string& key : keys) { rv = AddKeyFromFile(basePath, key.c_str()); if (rv != SECSuccess) { return rv; } } return SECSuccess; }
/* * R e m o v e A l l A r c * * Remove .arc directories that are lingering * from a previous run of signtool. * */ int RemoveAllArc(char *tree) { PRDir * dir; PRDirEntry * entry; char *archive = NULL; int retval = 0; dir = PR_OpenDir (tree); if (!dir) return - 1; for (entry = PR_ReadDir (dir, 0); entry; entry = PR_ReadDir (dir, 0)) { if (entry->name[0] == '.') { continue; } if (archive) PR_Free(archive); archive = PR_smprintf("%s/%s", tree, entry->name); if (PL_strcaserstr (entry->name, ".arc") == (entry->name + strlen(entry->name) - 4) ) { if (verbosity >= 0) { PR_fprintf(outputFD, "removing: %s\n", archive); } if (rm_dash_r(archive)) { PR_fprintf(errorFD, "Error removing %s\n", archive); errorCount++; retval = -1; goto finish; } } else if (is_dir(archive)) { if (RemoveAllArc(archive)) { retval = -1; goto finish; } } } finish: PR_CloseDir (dir); if (archive) PR_Free(archive); return retval; }
/* * r m _ d a s h _ r * * Remove a file, or a directory recursively. * */ int rm_dash_r(char *path) { PRDir *dir; PRDirEntry *entry; PRFileInfo fileinfo; char filename[FNSIZE]; if (PR_GetFileInfo(path, &fileinfo) != PR_SUCCESS) { /*fprintf(stderr, "Error: Unable to access %s\n", filename);*/ return -1; } if (fileinfo.type == PR_FILE_DIRECTORY) { dir = PR_OpenDir(path); if (!dir) { PR_fprintf(errorFD, "Error: Unable to open directory %s.\n", path); errorCount++; return -1; } /* Recursively delete all entries in the directory */ while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) { sprintf(filename, "%s/%s", path, entry->name); if (rm_dash_r(filename)) return -1; } if (PR_CloseDir(dir) != PR_SUCCESS) { PR_fprintf(errorFD, "Error: Could not close %s.\n", path); errorCount++; return -1; } /* Delete the directory itself */ if (PR_RmDir(path) != PR_SUCCESS) { PR_fprintf(errorFD, "Error: Unable to delete %s\n", path); errorCount++; return -1; } } else { if (PR_Delete(path) != PR_SUCCESS) { PR_fprintf(errorFD, "Error: Unable to delete %s\n", path); errorCount++; return -1; } } return 0; }
PRDir * CallPROpenDirUsingFileURL(char *fileURL) { PRDir* result = NULL; const char *path; char *escapedPath = unescapeURL(fileURL); path = convertFileURLToNSPRCopaceticPath(escapedPath); if (path != NULL) { result = PR_OpenDir(path); } if (escapedPath != NULL) freeMem(escapedPath); return result; }
void IPC_InitModuleReg(const char *exePath) { if (!(exePath && *exePath)) return; // // register plug-in modules // char *p = PL_strrchr(exePath, IPC_PATH_SEP_CHAR); if (p == NULL) { LOG(("unexpected exe path\n")); return; } int baseLen = p - exePath; int finalLen = baseLen + 1 + sizeof(IPC_MODULES_DIR); // build full path to ipc modules char *modulesDir = (char*) malloc(finalLen); memcpy(modulesDir, exePath, baseLen); modulesDir[baseLen] = IPC_PATH_SEP_CHAR; memcpy(modulesDir + baseLen + 1, IPC_MODULES_DIR, sizeof(IPC_MODULES_DIR)); LOG(("loading libraries in %s\n", modulesDir)); // // scan directory for IPC modules // PRDir *dir = PR_OpenDir(modulesDir); if (dir) { PRDirEntry *ent; while ((ent = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) { // // locate extension, and check if dynamic library // const char *p = strrchr(ent->name, '.'); if (p && PL_strcasecmp(p, MOZ_DLL_SUFFIX) == 0) InitModuleFromLib(modulesDir, ent->name); } PR_CloseDir(dir); } free(modulesDir); }
static void RunTests(const char *exePath) { if (!(exePath && *exePath)) return; // // load test modules // char *p = strrchr(exePath, kPathSep); if (p == NULL) { LOG(("unexpected exe path\n")); return; } int baseLen = p - exePath; int finalLen = baseLen + 1 + sizeof(kTestsDirectory); // build full path to ipc modules char *modulesDir = (char*) malloc(finalLen); memcpy(modulesDir, exePath, baseLen); modulesDir[baseLen] = kPathSep; memcpy(modulesDir + baseLen + 1, kTestsDirectory, sizeof(kTestsDirectory)); LOG(("loading libraries in %s\n", modulesDir)); // // scan directory for IPC modules // PRDir *dir = PR_OpenDir(modulesDir); if (dir) { PRDirEntry *ent; while ((ent = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) { // // locate extension, and check if dynamic library // char *p = strrchr(ent->name, '.'); if (p && PL_strcasecmp(p, MOZ_DLL_SUFFIX) == 0) ProcessModule(modulesDir, ent->name); } PR_CloseDir(dir); } free(modulesDir); }
/* * delete the given file/directory and its sub files/directories */ int ldbm_delete_dirs(char *path) { PRDir *dirhandle = NULL; PRDirEntry *direntry = NULL; char fullpath[MAXPATHLEN]; int rval = 0; PRFileInfo info; dirhandle = PR_OpenDir(path); if (! dirhandle) { PR_Delete(path); return 0; } while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) { if (! direntry->name) break; PR_snprintf(fullpath, MAXPATHLEN, "%s/%s", path, direntry->name); rval = PR_GetFileInfo(fullpath, &info); if (PR_SUCCESS == rval) { if (PR_FILE_DIRECTORY == info.type) rval += ldbm_delete_dirs(fullpath); } if (PR_FILE_DIRECTORY != info.type) PR_Delete(fullpath); } PR_CloseDir(dirhandle); /* remove the directory itself too */ rval += PR_RmDir(path); return rval; }
void CommandEventHandler::do_rmdr(std::string path, std::ostringstream &out) { std::string ret = isDir(path); const char *p = path.c_str(); // if it's a file, nothing special to do if (ret.compare("TRUE") != 0) { if (ret.compare("FALSE") == 0) { rm(path); return; } // if this does not exist, return out << ret; return; } // recurse for dir contents PRDir *dir = PR_OpenDir(p); PRDirEntry *entry = PR_ReadDir(dir, PR_SKIP_BOTH); while (entry) { do_rmdr(joinPaths(path, std::string(entry->name)), out); entry = PR_ReadDir(dir, PR_SKIP_BOTH); } if (PR_CloseDir(dir) != PR_SUCCESS) { out << "error: could not close dir object" << ENDL; // maybe return; } if (PR_RmDir(p) != PR_SUCCESS) out << std::string("error: could not remove " + path) << ENDL; }
static void SearchForSoname(const char* name, char** soname) { if (!(name && soname)) return; PRDir *fdDir = PR_OpenDir(DEFAULT_X11_PATH); if (!fdDir) return; int n = PL_strlen(name); PRDirEntry *dirEntry; while ((dirEntry = PR_ReadDir(fdDir, PR_SKIP_BOTH))) { if (!PL_strncmp(dirEntry->name, name, n)) { if (dirEntry->name[n] == '.' && dirEntry->name[n+1] && !dirEntry->name[n+2]) { // name.N, wild guess this is what we need char out[PLUGIN_MAX_LEN_OF_TMP_ARR] = DEFAULT_X11_PATH; PL_strcat(out, dirEntry->name); *soname = PL_strdup(out); break; } } } PR_CloseDir(fdDir); }
/********************************************************************* * * m a i n */ int main(int argc, char *argv[]) { PRBool readOnly; int retval = 0; outputFD = PR_STDOUT; errorFD = PR_STDERR; progName = argv[0]; if (argc < 2) { Usage(); } excludeDirs = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL); extensions = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL); if (parse_args(argc, argv)) { retval = -1; goto cleanup; } /* Parse the command file if one was given */ if (cmdFile) { if (ProcessCommandFile()) { retval = -1; goto cleanup; } } /* Set up output redirection */ if (outfile) { if (PR_Access(outfile, PR_ACCESS_EXISTS) == PR_SUCCESS) { /* delete the file if it is already present */ PR_fprintf(errorFD, "warning: %s already exists and will be overwritten.\n", outfile); warningCount++; if (PR_Delete(outfile) != PR_SUCCESS) { PR_fprintf(errorFD, "ERROR: unable to delete %s.\n", outfile); errorCount++; exit(ERRX); } } outputFD = PR_Open(outfile, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0777); if (!outputFD) { PR_fprintf(errorFD, "ERROR: Unable to create %s.\n", outfile); errorCount++; exit(ERRX); } errorFD = outputFD; } /* This seems to be a fairly common user error */ if (verify && list_certs > 0) { PR_fprintf(errorFD, "%s: Can't use -l and -v at the same time\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* -J assumes -Z now */ if (javascript && zipfile) { PR_fprintf(errorFD, "%s: Can't use -J and -Z at the same time\n", PROGRAM_NAME); PR_fprintf(errorFD, "%s: -J option will create the jar files for you\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* -X needs -Z */ if (xpi_arc && !zipfile) { PR_fprintf(errorFD, "%s: option XPI (-X) requires option jarfile (-Z)\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* Less common mixing of -L with various options */ if (list_certs > 0 && (tell_who || zipfile || javascript || scriptdir || extensionsGiven || exclusionsGiven || install_script)) { PR_fprintf(errorFD, "%s: Can't use -l or -L with that option\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } if (!cert_dir) cert_dir = get_default_cert_dir(); VerifyCertDir(cert_dir, keyName); if (compression_level < MIN_COMPRESSION_LEVEL || compression_level > MAX_COMPRESSION_LEVEL) { PR_fprintf(errorFD, "Compression level must be between %d and %d.\n", MIN_COMPRESSION_LEVEL, MAX_COMPRESSION_LEVEL); errorCount++; retval = -1; goto cleanup; } if (jartree && !keyName) { PR_fprintf(errorFD, "You must specify a key with which to sign.\n"); errorCount++; retval = -1; goto cleanup; } readOnly = (genkey == NULL); /* only key generation requires write */ if (InitCrypto(cert_dir, readOnly)) { PR_fprintf(errorFD, "ERROR: Cryptographic initialization failed.\n"); errorCount++; retval = -1; goto cleanup; } if (enableOCSP) { SECStatus rv = CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); if (rv != SECSuccess) { PR_fprintf(errorFD, "ERROR: Attempt to enable OCSP Checking failed.\n"); errorCount++; retval = -1; } } if (verify) { if (VerifyJar(verify)) { errorCount++; retval = -1; goto cleanup; } } else if (list_certs) { if (ListCerts(keyName, list_certs)) { errorCount++; retval = -1; goto cleanup; } } else if (list_modules) { JarListModules(); } else if (genkey) { if (GenerateCert(genkey, keySize, token)) { errorCount++; retval = -1; goto cleanup; } } else if (tell_who) { if (JarWho(tell_who)) { errorCount++; retval = -1; goto cleanup; } } else if (javascript && jartree) { /* make sure directory exists */ PRDir *dir; dir = PR_OpenDir(jartree); if (!dir) { PR_fprintf(errorFD, "ERROR: unable to open directory %s.\n", jartree); errorCount++; retval = -1; goto cleanup; } else { PR_CloseDir(dir); } /* undo junk from prior runs of signtool*/ if (RemoveAllArc(jartree)) { PR_fprintf(errorFD, "Error removing archive directories under %s\n", jartree); errorCount++; retval = -1; goto cleanup; } /* traverse all the htm|html files in the directory */ if (InlineJavaScript(jartree, !noRecurse)) { retval = -1; goto cleanup; } /* sign any resultant .arc directories created in above step */ if (SignAllArc(jartree, keyName, javascript, metafile, install_script, optimize, !noRecurse)) { retval = -1; goto cleanup; } if (!leaveArc) { RemoveAllArc(jartree); } if (errorCount > 0 || warningCount > 0) { PR_fprintf(outputFD, "%d error%s, %d warning%s.\n", errorCount, errorCount == 1 ? "" : "s", warningCount, warningCount == 1 ? "" : "s"); } else { PR_fprintf(outputFD, "Directory %s signed successfully.\n", jartree); } } else if (jartree) { SignArchive(jartree, keyName, zipfile, javascript, metafile, install_script, optimize, !noRecurse); } else Usage(); cleanup: if (extensions) { PL_HashTableDestroy(extensions); extensions = NULL; } if (excludeDirs) { PL_HashTableDestroy(excludeDirs); excludeDirs = NULL; } if (outputFD != PR_STDOUT) { PR_Close(outputFD); } rm_dash_r(TMP_OUTPUT); if (retval == 0) { if (NSS_Shutdown() != SECSuccess) { exit(1); } } return retval; }
int ldbm_instance_post_delete_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) { char *instance_name; struct ldbminfo *li = (struct ldbminfo *)arg; struct ldbm_instance *inst = NULL; parse_ldbm_instance_entry(entryBefore, &instance_name); inst = ldbm_instance_find_by_name(li, instance_name); if (inst == NULL) { LDAPDebug(LDAP_DEBUG_ANY, "ldbm: instance '%s' does not exist! (2)\n", instance_name, 0, 0); if (returntext) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "No ldbm instance exists with the name '%s' (2)\n", instance_name); } if (returncode) { *returncode = LDAP_UNWILLING_TO_PERFORM; } slapi_ch_free((void **)&instance_name); return SLAPI_DSE_CALLBACK_ERROR; } LDAPDebug(LDAP_DEBUG_ANY, "ldbm: removing '%s'.\n", instance_name, 0, 0); cache_destroy_please(&inst->inst_cache, CACHE_TYPE_ENTRY); if (entryrdn_get_switch()) { /* subtree-rename: on */ cache_destroy_please(&inst->inst_dncache, CACHE_TYPE_DN); } { struct ldbminfo *li = (struct ldbminfo *) inst->inst_be->be_database->plg_private; dblayer_private *priv = (dblayer_private*) li->li_dblayer_private; struct dblayer_private_env *pEnv = priv->dblayer_env; if(pEnv) { PRDir *dirhandle = NULL; char inst_dir[MAXPATHLEN*2]; char *inst_dirp = NULL; if (inst->inst_dir_name == NULL){ dblayer_get_instance_data_dir(inst->inst_be); } inst_dirp = dblayer_get_full_inst_dir(li, inst, inst_dir, MAXPATHLEN*2); if (NULL != inst_dirp) { dirhandle = PR_OpenDir(inst_dirp); /* the db dir instance may have been removed already */ if (dirhandle) { PRDirEntry *direntry = NULL; char *dbp = NULL; char *p = NULL; while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT|PR_SKIP_DOT_DOT))) { int rc; if (!direntry->name) break; dbp = PR_smprintf("%s/%s", inst_dirp, direntry->name); if (NULL == dbp) { LDAPDebug (LDAP_DEBUG_ANY, "ldbm_instance_post_delete_instance_entry_callback:" " failed to generate db path: %s/%s\n", inst_dirp, direntry->name, 0); break; } p = strstr(dbp, LDBM_FILENAME_SUFFIX); if (NULL != p && strlen(p) == strlen(LDBM_FILENAME_SUFFIX)) { rc = dblayer_db_remove(pEnv, dbp, 0); } else { rc = PR_Delete(dbp); } PR_ASSERT(rc == 0); PR_smprintf_free(dbp); } PR_CloseDir(dirhandle); } /* * When a backend was removed, the db instance directory * was removed as well (See also bz463774). * In case DB_RECOVER_FATAL is set in the DB open after * the removal (e.g., in restore), the logs in the transaction * logs are replayed and compared with the contents of the DB * files. At that time, if the db instance directory does not * exist, libdb returns FATAL error. To prevent the problem, * we have to leave the empty directory. (bz597375) * * PR_RmDir(inst_dirp); */ } /* non-null dirhandle */ if (inst_dirp != inst_dir) { slapi_ch_free_string(&inst_dirp); } } /* non-null pEnv */ } ldbm_instance_unregister_callbacks(inst); slapi_be_free(&inst->inst_be); ldbm_instance_destroy(inst); slapi_ch_free((void **)&instance_name); return SLAPI_DSE_CALLBACK_OK; }
/* * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCRL * DESCRIPTION: * * Create list of CRLs from *.crl files at directory specified in dirName, * Not recursive to sub-dirctory. Also assume the directory contents are * not changed dynamically. * * PARAMETERS * "colCertStoreContext" - Address of CollectionCertStoreContext * where the dirName is specified and where the return * CRLs are stored as a list. Must be non-NULL. * "plContext" - Platform-specific context pointer. * * THREAD SAFETY: * Not Thread Safe - A lock at top level is required. * * RETURNS: * Returns NULL if the function succeeds. * Returns a CollectionCertStoreContext Error if the function fails in * a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ static PKIX_Error * pkix_pl_CollectionCertStoreContext_PopulateCRL( PKIX_PL_CollectionCertStoreContext *colCertStoreContext, void *plContext) { PKIX_List *crlList = NULL; PKIX_PL_CRL *crlItem = NULL; char *dirName = NULL; char *pathName = NULL; PKIX_UInt32 dirNameLen = 0; PRErrorCode prError = 0; PRDir *dir = NULL; PRDirEntry *dirEntry = NULL; PKIX_ENTER(COLLECTIONCERTSTORECONTEXT, "pkix_pl_CollectionCertStoreContext_PopulateCRL"); PKIX_NULLCHECK_ONE(colCertStoreContext); /* convert directory to ascii */ PKIX_CHECK(PKIX_PL_String_GetEncoded (colCertStoreContext->storeDir, PKIX_ESCASCII, (void **)&dirName, &dirNameLen, plContext), PKIX_STRINGGETENCODEDFAILED); /* create CRL list, if no CRL file, should return an empty list */ PKIX_CHECK(PKIX_List_Create(&crlList, plContext), PKIX_LISTCREATEFAILED); /* open directory and read in .crl files */ PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n"); dir = PR_OpenDir(dirName); if (!dir) { PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG ("\t\t Directory Name:%s\n", dirName); PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY); } PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n"); dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH); if (!dirEntry) { PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Empty directory.\n"); PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Calling PR_GetError.\n"); prError = PR_GetError(); } PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n"); PR_SetError(0, 0); while (dirEntry != NULL && prError == 0) { if (PL_strrstr(dirEntry->name, ".crl") == dirEntry->name + PL_strlen(dirEntry->name) - 4) { PKIX_CHECK_ONLY_FATAL (PKIX_PL_Malloc (dirNameLen + PL_strlen(dirEntry->name) + 2, (void **)&pathName, plContext), PKIX_MALLOCFAILED); if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){ PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Calling PL_strcpy for dirName.\n"); PL_strcpy(pathName, dirName); PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Calling PL_strcat for dirName.\n"); PL_strcat(pathName, "/"); PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Calling PL_strcat for /.\n"); PL_strcat(pathName, dirEntry->name); PKIX_CHECK_ONLY_FATAL (pkix_pl_CollectionCertStoreContext_CreateCRL (pathName, &crlItem, plContext), PKIX_COLLECTIONCERTSTORECONTEXTCREATECRLFAILED); if (!PKIX_ERROR_RECEIVED){ PKIX_CHECK_ONLY_FATAL (PKIX_List_AppendItem (crlList, (PKIX_PL_Object *)crlItem, plContext), PKIX_LISTAPPENDITEMFAILED); } } PKIX_DECREF(crlItem); PKIX_FREE(pathName); } PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Calling PR_SetError.\n"); PR_SetError(0, 0); PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Calling PR_ReadDir.\n"); dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH); if (!dirEntry) { PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Calling PR_GetError.\n"); prError = PR_GetError(); } } if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) { PKIX_ERROR(PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED); } PKIX_CHECK(PKIX_List_SetImmutable(crlList, plContext), PKIX_LISTSETIMMUTABLEFAILED); PKIX_INCREF(crlList); colCertStoreContext->crlList = crlList; cleanup: if (dir) { PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG ("\t\t Calling PR_CloseDir.\n"); PR_CloseDir(dir); } PKIX_FREE(pathName); PKIX_FREE(dirName); if (PKIX_ERROR_RECEIVED){ PKIX_DECREF(crlList); } PKIX_DECREF(crlItem); PKIX_DECREF(crlList); PKIX_RETURN(COLLECTIONCERTSTORECONTEXT); }
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) { PRInt32 err; PRFileDesc *model = NULL; PRBool ssl2, ssl3, tlsv1; struct SessionHandle *data = conn->data; curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; SECStatus rv; char *certDir = NULL; int curlerr; const int *cipher_to_enable; curlerr = CURLE_SSL_CONNECT_ERROR; if (connssl->state == ssl_connection_complete) return CURLE_OK; connssl->data = data; #ifdef HAVE_PK11_CREATEGENERICOBJECT connssl->cacert[0] = NULL; connssl->cacert[1] = NULL; connssl->key = NULL; #endif /* FIXME. NSS doesn't support multiple databases open at the same time. */ PR_Lock(nss_initlock); if(!initialized) { struct_stat st; /* First we check if $SSL_DIR points to a valid dir */ certDir = getenv("SSL_DIR"); if(certDir) { if((stat(certDir, &st) != 0) || (!S_ISDIR(st.st_mode))) { certDir = NULL; } } /* Now we check if the default location is a valid dir */ if(!certDir) { if((stat(SSL_DIR, &st) == 0) && (S_ISDIR(st.st_mode))) { certDir = (char *)SSL_DIR; } } if (!NSS_IsInitialized()) { initialized = 1; infof(conn->data, "Initializing NSS with certpath: %s\n", certDir ? certDir : "none"); if(!certDir) { rv = NSS_NoDB_Init(NULL); } else { char *certpath = PR_smprintf("%s%s", NSS_VersionCheck("3.12.0") ? "sql:" : "", certDir); rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY); PR_smprintf_free(certpath); } if(rv != SECSuccess) { infof(conn->data, "Unable to initialize NSS database\n"); curlerr = CURLE_SSL_CACERT_BADFILE; initialized = 0; PR_Unlock(nss_initlock); goto error; } } if(num_enabled_ciphers() == 0) NSS_SetDomesticPolicy(); #ifdef HAVE_PK11_CREATEGENERICOBJECT if(!mod) { char *configstring = aprintf("library=%s name=PEM", pem_library); if(!configstring) { PR_Unlock(nss_initlock); goto error; } mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE); free(configstring); if(!mod || !mod->loaded) { if(mod) { SECMOD_DestroyModule(mod); mod = NULL; } infof(data, "WARNING: failed to load NSS PEM library %s. Using OpenSSL " "PEM certificates will not work.\n", pem_library); } } #endif PK11_SetPasswordFunc(nss_get_password); } PR_Unlock(nss_initlock); model = PR_NewTCPSocket(); if(!model) goto error; model = SSL_ImportFD(NULL, model); if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess) goto error; ssl2 = ssl3 = tlsv1 = PR_FALSE; switch (data->set.ssl.version) { default: case CURL_SSLVERSION_DEFAULT: ssl3 = tlsv1 = PR_TRUE; break; case CURL_SSLVERSION_TLSv1: tlsv1 = PR_TRUE; break; case CURL_SSLVERSION_SSLv2: ssl2 = PR_TRUE; break; case CURL_SSLVERSION_SSLv3: ssl3 = PR_TRUE; break; } if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess) goto error; /* enable all ciphers from enable_ciphers_by_default */ cipher_to_enable = enable_ciphers_by_default; while (SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) { if (SSL_CipherPrefSet(model, *cipher_to_enable, PR_TRUE) != SECSuccess) { curlerr = CURLE_SSL_CIPHER; goto error; } cipher_to_enable++; } if(data->set.ssl.cipher_list) { if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) { curlerr = CURLE_SSL_CIPHER; goto error; } } if(data->set.ssl.verifyhost == 1) infof(data, "warning: ignoring unsupported value (1) of ssl.verifyhost\n"); data->set.ssl.certverifyresult=0; /* not checked yet */ if(SSL_BadCertHook(model, (SSLBadCertHandler) BadCertHandler, conn) != SECSuccess) { goto error; } if(SSL_HandshakeCallback(model, (SSLHandshakeCallback) HandshakeCallback, NULL) != SECSuccess) goto error; if(!data->set.ssl.verifypeer) /* skip the verifying of the peer */ ; else if(data->set.ssl.CAfile) { int rc = nss_load_cert(&conn->ssl[sockindex], data->set.ssl.CAfile, PR_TRUE); if(!rc) { curlerr = CURLE_SSL_CACERT_BADFILE; goto error; } } else if(data->set.ssl.CApath) { struct_stat st; PRDir *dir; PRDirEntry *entry; if(stat(data->set.ssl.CApath, &st) == -1) { curlerr = CURLE_SSL_CACERT_BADFILE; goto error; } if(S_ISDIR(st.st_mode)) { int rc; dir = PR_OpenDir(data->set.ssl.CApath); do { entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN); if(entry) { char fullpath[PATH_MAX]; snprintf(fullpath, sizeof(fullpath), "%s/%s", data->set.ssl.CApath, entry->name); rc = nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE); /* FIXME: check this return value! */ } /* This is purposefully tolerant of errors so non-PEM files * can be in the same directory */ } while(entry != NULL); PR_CloseDir(dir); } } infof(data, " CAfile: %s\n" " CApath: %s\n", data->set.ssl.CAfile ? data->set.ssl.CAfile : "none", data->set.ssl.CApath ? data->set.ssl.CApath : "none"); if (data->set.ssl.CRLfile) { int rc = nss_load_crl(data->set.ssl.CRLfile, PR_FALSE); if (!rc) { curlerr = CURLE_SSL_CRL_BADFILE; goto error; } infof(data, " CRLfile: %s\n", data->set.ssl.CRLfile ? data->set.ssl.CRLfile : "none"); } if(data->set.str[STRING_CERT]) { bool nickname_alloc = FALSE; char *nickname = fmt_nickname(data->set.str[STRING_CERT], &nickname_alloc); if(!nickname) return CURLE_OUT_OF_MEMORY; if(!cert_stuff(conn, sockindex, data->set.str[STRING_CERT], data->set.str[STRING_KEY])) { /* failf() is already done in cert_stuff() */ if(nickname_alloc) free(nickname); return CURLE_SSL_CERTPROBLEM; } /* this "takes over" the pointer to the allocated name or makes a dup of it */ connssl->client_nickname = nickname_alloc?nickname:strdup(nickname); if(!connssl->client_nickname) return CURLE_OUT_OF_MEMORY; } else connssl->client_nickname = NULL; if(SSL_GetClientAuthDataHook(model, SelectClientCert, (void *)connssl) != SECSuccess) { curlerr = CURLE_SSL_CERTPROBLEM; goto error; } /* Import our model socket onto the existing file descriptor */ connssl->handle = PR_ImportTCPSocket(sockfd); connssl->handle = SSL_ImportFD(model, connssl->handle); if(!connssl->handle) goto error; PR_Close(model); /* We don't need this any more */ /* This is the password associated with the cert that we're using */ if (data->set.str[STRING_KEY_PASSWD]) { SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]); } /* Force handshake on next I/O */ SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE); SSL_SetURL(connssl->handle, conn->host.name); /* Force the handshake now */ if(SSL_ForceHandshakeWithTimeout(connssl->handle, PR_SecondsToInterval(HANDSHAKE_TIMEOUT)) != SECSuccess) { if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN) curlerr = CURLE_PEER_FAILED_VERIFICATION; else if(conn->data->set.ssl.certverifyresult!=0) curlerr = CURLE_SSL_CACERT; goto error; } connssl->state = ssl_connection_complete; display_conn_info(conn, connssl->handle); if (data->set.str[STRING_SSL_ISSUERCERT]) { SECStatus ret; bool nickname_alloc = FALSE; char *nickname = fmt_nickname(data->set.str[STRING_SSL_ISSUERCERT], &nickname_alloc); if(!nickname) return CURLE_OUT_OF_MEMORY; ret = check_issuer_cert(connssl->handle, nickname); if(nickname_alloc) free(nickname); if(SECFailure == ret) { infof(data,"SSL certificate issuer check failed\n"); curlerr = CURLE_SSL_ISSUER_ERROR; goto error; } else { infof(data, "SSL certificate issuer check ok\n"); } } return CURLE_OK; error: err = PR_GetError(); infof(data, "NSS error %d\n", err); if(model) PR_Close(model); return curlerr; }
static int dbverify_ext( ldbm_instance *inst, int verbose ) { char dbdir[MAXPATHLEN]; char *filep = NULL; PRDir *dirhandle = NULL; PRDirEntry *direntry = NULL; DB *dbp = NULL; size_t tmplen = 0; size_t filelen = 0; int rval = 1; int rval_main = 0; struct ldbminfo *li = inst->inst_li; dblayer_private *priv = (dblayer_private*)li->li_dblayer_private; struct dblayer_private_env *pEnv = priv->dblayer_env; dbdir[sizeof(dbdir)-1] = '\0'; PR_snprintf(dbdir, sizeof(dbdir), "%s/%s", inst->inst_parent_dir_name, inst->inst_dir_name); if ('\0' != dbdir[sizeof(dbdir)-1]) /* overflown */ { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "db path too long: %s/%s\n", inst->inst_parent_dir_name, inst->inst_dir_name); return 1; } tmplen = strlen(dbdir); filep = dbdir + tmplen; filelen = sizeof(dbdir) - tmplen; /* run dbverify on each each db file */ dirhandle = PR_OpenDir(dbdir); if (! dirhandle) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "PR_OpenDir (%s) failed (%d): %s\n", dbdir, PR_GetError(),slapd_pr_strerror(PR_GetError())); return 1; } while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) { /* struct attrinfo *ai = NULL; */ dbp = NULL; if (!direntry->name) { break; } if (!strstr(direntry->name, LDBM_FILENAME_SUFFIX)) /* non db file */ { continue; } if (sizeof(direntry->name) + 2 > filelen) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "db path too long: %s/%s\n", dbdir, direntry->name); continue; } PR_snprintf(filep, filelen, "/%s", direntry->name); rval = db_create(&dbp, pEnv->dblayer_DB_ENV, 0); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to create id2entry db file %d\n", rval); return rval; } #define VLVPREFIX "vlv#" if (0 != strncmp(direntry->name, ID2ENTRY, strlen(ID2ENTRY))) { struct attrinfo *ai = NULL; char *p = NULL; p = strstr(filep, LDBM_FILENAME_SUFFIX); /* since already checked, it must have it */ if(p) *p = '\0'; ainfo_get( inst->inst_be, filep+1, &ai ); if(p) *p = '.'; if (ai->ai_key_cmp_fn) { dbp->app_private = (void *)ai->ai_key_cmp_fn; dbp->set_bt_compare(dbp, dblayer_bt_compare); } if (idl_get_idl_new()) { rval = dbp->set_pagesize(dbp, (priv->dblayer_index_page_size == 0) ? DBLAYER_INDEX_PAGESIZE : priv->dblayer_index_page_size); } else { rval = dbp->set_pagesize(dbp, (priv->dblayer_page_size == 0) ? DBLAYER_PAGESIZE : priv->dblayer_page_size); } if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "DB verify", "Unable to set pagesize flags to db (%d)\n", rval); return rval; } if (0 == strncmp(direntry->name, VLVPREFIX, strlen(VLVPREFIX))) { rval = dbp->set_flags(dbp, DB_RECNUM); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set RECNUM flag to vlv index (%d)\n", rval); return rval; } } else if (idl_get_idl_new()) { rval = dbp->set_flags(dbp, DB_DUP | DB_DUPSORT); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set DUP flags to db (%d)\n", rval); return rval; } if (ai->ai_dup_cmp_fn) { /* If set, use the special dup compare callback */ rval = dbp->set_dup_compare(dbp, ai->ai_dup_cmp_fn); } else { rval = dbp->set_dup_compare(dbp, idl_new_compare_dups); } if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set dup_compare to db (%d)\n", rval); return rval; } } } #undef VLVPREFIX rval = dbp->verify(dbp, dbdir, NULL, NULL, 0); if (0 == rval) { if (verbose) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "%s: ok\n", dbdir); } } else { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "verify failed(%d): %s\n", rval, dbdir); } rval_main |= rval; *filep = '\0'; } PR_CloseDir(dirhandle); return rval_main; }
int main(int argc, char **argv) #endif { PRUintn pdkey; PRStatus status; char *path = NULL; PRDir *dir = NULL; PRLock *ml = NULL; PRCondVar *cv = NULL; PRThread *thread = NULL; PRIntervalTime interval = 0; PRFileDesc *file, *udp, *tcp, *pair[2]; PRIntn test; if ( argc < 2) { test = 0; } else test = atoi(argv[1]); switch (test) { case 0: ml = PR_NewLock(); break; case 1: interval = PR_SecondsToInterval(1); break; case 2: thread = PR_CreateThread( PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); break; case 3: file = PR_Open("/usr/tmp/", PR_RDONLY, 0); break; case 4: udp = PR_NewUDPSocket(); break; case 5: tcp = PR_NewTCPSocket(); break; case 6: dir = PR_OpenDir("/usr/tmp/"); break; case 7: (void)PR_NewThreadPrivateIndex(&pdkey, NULL); break; case 8: path = PR_GetEnv("PATH"); break; case 9: status = PR_NewTCPSocketPair(pair); break; case 10: PR_SetConcurrency(2); break; default: printf( "lazyinit: unrecognized command line argument: %s\n", argv[1] ); printf( "FAIL\n" ); exit( 1 ); break; } /* switch() */ return 0; } /* Lazy */
CURLcode Curl_nss_connect(struct connectdata * conn, int sockindex) { PRInt32 err; PRFileDesc *model = NULL; PRBool ssl2, ssl3, tlsv1; struct SessionHandle *data = conn->data; curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; SECStatus rv; #ifdef HAVE_PK11_CREATEGENERICOBJECT char *configstring = NULL; #endif char *certDir = NULL; int curlerr; curlerr = CURLE_SSL_CONNECT_ERROR; /* FIXME. NSS doesn't support multiple databases open at the same time. */ if(!initialized) { initialized = 1; certDir = getenv("SSL_DIR"); /* Look in $SSL_DIR */ if (!certDir) { struct stat st; if (stat(SSL_DIR, &st) == 0) if (S_ISDIR(st.st_mode)) { certDir = (char *)SSL_DIR; } } if(!certDir) { rv = NSS_NoDB_Init(NULL); } else { rv = NSS_Initialize(certDir, NULL, NULL, "secmod.db", NSS_INIT_READONLY); } if(rv != SECSuccess) { infof(conn->data, "Unable to initialize NSS database\n"); curlerr = CURLE_SSL_CACERT_BADFILE; goto error; } NSS_SetDomesticPolicy(); #ifdef HAVE_PK11_CREATEGENERICOBJECT configstring = (char *)malloc(PATH_MAX); PR_snprintf(configstring, PATH_MAX, "library=%s name=PEM", pem_library); mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE); free(configstring); if (!mod || !mod->loaded) { if (mod) { SECMOD_DestroyModule(mod); mod = NULL; } infof(data, "WARNING: failed to load NSS PEM library %s. Using OpenSSL " "PEM certificates will not work.\n", pem_library); } #endif } model = PR_NewTCPSocket(); if(!model) goto error; model = SSL_ImportFD(NULL, model); if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess) goto error; ssl2 = ssl3 = tlsv1 = PR_FALSE; switch (data->set.ssl.version) { default: case CURL_SSLVERSION_DEFAULT: ssl2 = ssl3 = tlsv1 = PR_TRUE; break; case CURL_SSLVERSION_TLSv1: tlsv1 = PR_TRUE; break; case CURL_SSLVERSION_SSLv2: ssl2 = PR_TRUE; break; case CURL_SSLVERSION_SSLv3: ssl3 = PR_TRUE; break; } if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess) goto error; if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess) goto error; if(data->set.ssl.cipher_list) { if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) { curlerr = CURLE_SSL_CIPHER; goto error; } } data->set.ssl.certverifyresult=0; /* not checked yet */ if(SSL_BadCertHook(model, (SSLBadCertHandler) BadCertHandler, conn) != SECSuccess) { goto error; } if(SSL_HandshakeCallback(model, (SSLHandshakeCallback) HandshakeCallback, NULL) != SECSuccess) goto error; if(!data->set.ssl.verifypeer) /* skip the verifying of the peer */ ; else if (data->set.ssl.CAfile) { int rc = nss_load_cert(data->set.ssl.CAfile, PR_TRUE); if (!rc) { curlerr = CURLE_SSL_CACERT_BADFILE; goto error; } } else if (data->set.ssl.CApath) { struct stat st; PRDir *dir; PRDirEntry *entry; if (stat(data->set.ssl.CApath, &st) == -1) { curlerr = CURLE_SSL_CACERT_BADFILE; goto error; } if (S_ISDIR(st.st_mode)) { int rc; dir = PR_OpenDir(data->set.ssl.CApath); do { entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN); if (entry) { char fullpath[PATH_MAX]; snprintf(fullpath, sizeof(fullpath), "%s/%s", data->set.ssl.CApath, entry->name); rc = nss_load_cert(fullpath, PR_TRUE); /* FIXME: check this return value! */ } /* This is purposefully tolerant of errors so non-PEM files * can be in the same directory */ } while (entry != NULL); PR_CloseDir(dir); } } infof(data, " CAfile: %s\n" " CApath: %s\n", data->set.ssl.CAfile ? data->set.ssl.CAfile : "none", data->set.ssl.CApath ? data->set.ssl.CApath : "none"); if(data->set.str[STRING_CERT]) { char *n; char *nickname; nickname = (char *)malloc(PATH_MAX); if(is_file(data->set.str[STRING_CERT])) { n = strrchr(data->set.str[STRING_CERT], '/'); if (n) { n++; /* skip last slash */ snprintf(nickname, PATH_MAX, "PEM Token #%ld:%s", 1, n); } } else { strncpy(nickname, data->set.str[STRING_CERT], PATH_MAX); } if(nss_Init_Tokens(conn) != SECSuccess) { free(nickname); goto error; } if (!cert_stuff(conn, data->set.str[STRING_CERT], data->set.str[STRING_KEY])) { /* failf() is already done in cert_stuff() */ free(nickname); return CURLE_SSL_CERTPROBLEM; } connssl->client_nickname = strdup(nickname); if(SSL_GetClientAuthDataHook(model, (SSLGetClientAuthData) SelectClientCert, (void *)connssl->client_nickname) != SECSuccess) { curlerr = CURLE_SSL_CERTPROBLEM; goto error; } free(nickname); PK11_SetPasswordFunc(nss_no_password); } else connssl->client_nickname = NULL; /* Import our model socket onto the existing file descriptor */ connssl->handle = PR_ImportTCPSocket(sockfd); connssl->handle = SSL_ImportFD(model, connssl->handle); if(!connssl->handle) goto error; PR_Close(model); /* We don't need this any more */ /* Force handshake on next I/O */ SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE); SSL_SetURL(connssl->handle, conn->host.name); /* Force the handshake now */ if (SSL_ForceHandshakeWithTimeout(connssl->handle, PR_SecondsToInterval(HANDSHAKE_TIMEOUT)) != SECSuccess) { if (conn->data->set.ssl.certverifyresult!=0) curlerr = CURLE_SSL_CACERT; goto error; } display_conn_info(conn, connssl->handle); return CURLE_OK; error: err = PR_GetError(); infof(data, "NSS error %d\n", err); if(model) PR_Close(model); return curlerr; }