Exemplo n.º 1
0
/*
/////////////////////////////////////////////////////////////////////////
// actually run the installation, copying files to and fro
*/
static Pk11Install_Error
DoInstall(JAR *jar, const char *installDir, const char *tempDir,
          Pk11Install_Platform *platform, PRFileDesc *feedback, PRBool noverify)
{
    Pk11Install_File *file;
    Pk11Install_Error ret;
    char *reldir;
    char *dest;
    char *modDest;
    char *cp;
    int i;
    int status;
    char *tempname, *temp;
    StringList executables;
    StringNode *execNode;
    PRProcessAttr *attr;
    PRProcess *proc;
    char *argv[2];
    char *envp[1];
    int errcode;

    ret = PK11_INSTALL_UNSPECIFIED;
    reldir = NULL;
    dest = NULL;
    modDest = NULL;
    tempname = NULL;

    StringList_new(&executables);
    /*
    // Create Temporary directory
    */
    tempname = PR_smprintf("%s/%s", tempDir, TEMPORARY_DIRECTORY_NAME);
    if (PR_Access(tempname, PR_ACCESS_EXISTS) == PR_SUCCESS) {
        /* Left over from previous run?  Delete it. */
        rm_dash_r(tempname);
    }
    if (PR_MkDir(tempname, 0700) != PR_SUCCESS) {
        error(PK11_INSTALL_CREATE_DIR, tempname);
        ret = PK11_INSTALL_CREATE_DIR;
        goto loser;
    }

    /*
    // Install all the files
    */
    for (i = 0; i < platform->numFiles; i++) {
        file = &platform->files[i];

        if (file->relativePath) {
            PRBool foundMarker = PR_FALSE;
            reldir = PR_Strdup(file->relativePath);

            /* Replace all the markers with the directories for which they stand */
            while (1) {
                if ((cp = PL_strcasestr(reldir, ROOT_MARKER))) {
                    /* Has a %root% marker  */
                    *cp = '\0';
                    temp = PR_smprintf("%s%s%s", reldir, installDir,
                                       cp + strlen(ROOT_MARKER));
                    PR_Free(reldir);
                    reldir = temp;
                    foundMarker = PR_TRUE;
                } else if ((cp = PL_strcasestr(reldir, TEMP_MARKER))) {
                    /* Has a %temp% marker */
                    *cp = '\0';
                    temp = PR_smprintf("%s%s%s", reldir, tempname,
                                       cp + strlen(TEMP_MARKER));
                    PR_Free(reldir);
                    reldir = temp;
                    foundMarker = PR_TRUE;
                } else {
                    break;
                }
            }
            if (!foundMarker) {
                /* Has no markers...this isn't really a relative directory */
                error(PK11_INSTALL_BOGUS_REL_DIR, file->relativePath);
                ret = PK11_INSTALL_BOGUS_REL_DIR;
                goto loser;
            }
            dest = reldir;
            reldir = NULL;
        } else if (file->absolutePath) {
            dest = PR_Strdup(file->absolutePath);
        }

        /* Remember if this is the module file, we'll need to add it later */
        if (i == platform->modFile) {
            modDest = PR_Strdup(dest);
        }

        /* Remember is this is an executable, we'll need to run it later */
        if (file->executable) {
            StringList_Append(&executables, dest);
            /*executables.Append(dest);*/
        }

        /* Make sure the directory we are targetting exists */
        if (make_dirs(dest, file->permissions)) {
            ret = PK11_INSTALL_CREATE_DIR;
            goto loser;
        }

        /* Actually extract the file onto the filesystem */
        if (noverify) {
            status = JAR_extract(jar, (char *)file->jarPath, dest);
        } else {
            status = JAR_verified_extract(jar, (char *)file->jarPath, dest);
        }
        if (status) {
            if (status >= JAR_BASE && status <= JAR_BASE_END) {
                error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
                      JAR_get_error(status));
            } else {
                error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
                      mySECU_ErrorString(PORT_GetError()));
            }
            ret = PK11_INSTALL_JAR_EXTRACT;
            goto loser;
        }
        if (feedback) {
            PR_fprintf(feedback, msgStrings[INSTALLED_FILE_MSG],
                       file->jarPath, dest);
        }

/* no NSPR command to change permissions? */
#ifdef XP_UNIX
        chmod(dest, file->permissions);
#endif

        /* Memory clean-up tasks */
        if (reldir) {
            PR_Free(reldir);
            reldir = NULL;
        }
        if (dest) {
            PR_Free(dest);
            dest = NULL;
        }
    }
    /* Make sure we found the module file */
    if (!modDest) {
        /* Internal problem here, since every platform is supposed to have
           a module file */
        error(PK11_INSTALL_NO_MOD_FILE, platform->moduleName);
        ret = PK11_INSTALL_NO_MOD_FILE;
        goto loser;
    }

    /*
    // Execute any executable files
    */
    {
        argv[1] = NULL;
        envp[0] = NULL;
        for (execNode = executables.head; execNode; execNode = execNode->next) {
            attr = PR_NewProcessAttr();
            argv[0] = PR_Strdup(execNode->str);

            /* Announce our intentions */
            if (feedback) {
                PR_fprintf(feedback, msgStrings[EXEC_FILE_MSG], execNode->str);
            }

            /* start the process */
            if (!(proc = PR_CreateProcess(execNode->str, argv, envp, attr))) {
                PR_Free(argv[0]);
                PR_DestroyProcessAttr(attr);
                error(PK11_INSTALL_EXEC_FILE, execNode->str);
                ret = PK11_INSTALL_EXEC_FILE;
                goto loser;
            }

            /* wait for it to finish */
            if (PR_WaitProcess(proc, &errcode) != PR_SUCCESS) {
                PR_Free(argv[0]);
                PR_DestroyProcessAttr(attr);
                error(PK11_INSTALL_WAIT_PROCESS, execNode->str);
                ret = PK11_INSTALL_WAIT_PROCESS;
                goto loser;
            }

            /* What happened? */
            if (errcode) {
                /* process returned an error */
                error(PK11_INSTALL_PROC_ERROR, execNode->str, errcode);
            } else if (feedback) {
                /* process ran successfully */
                PR_fprintf(feedback, msgStrings[EXEC_SUCCESS], execNode->str);
            }

            PR_Free(argv[0]);
            PR_DestroyProcessAttr(attr);
        }
    }

    /*
    // Add the module
    */
    status = Pk11Install_AddNewModule((char *)platform->moduleName,
                                      (char *)modDest, platform->mechFlags, platform->cipherFlags);

    if (status != SECSuccess) {
        error(PK11_INSTALL_ADD_MODULE, platform->moduleName);
        ret = PK11_INSTALL_ADD_MODULE;
        goto loser;
    }
    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLED_MODULE_MSG],
                   platform->moduleName);
    }

    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLATION_COMPLETE_MSG]);
    }

    ret = PK11_INSTALL_SUCCESS;

loser:
    if (reldir) {
        PR_Free(reldir);
    }
    if (dest) {
        PR_Free(dest);
    }
    if (modDest) {
        PR_Free(modDest);
    }
    if (tempname) {
        PRFileInfo info;
        if (PR_GetFileInfo(tempname, &info) == PR_SUCCESS) {
            if (info.type == PR_FILE_DIRECTORY) {
                /* Recursively remove temporary directory */
                if (rm_dash_r(tempname)) {
                    error(PK11_INSTALL_REMOVE_DIR,
                          tempname);
                    ret = PK11_INSTALL_REMOVE_DIR;
                }
            }
        }
        PR_Free(tempname);
    }
    StringList_delete(&executables);
    return ret;
}
Exemplo n.º 2
0
/***************************************************************************
 *
 * v e r i f y _ g l o b a l
 */
static int
verify_global(JAR *jar)
{
    FILE *fp;
    JAR_Context *ctx;
    JAR_Item *it;
    JAR_Digest *globaldig;
    char *ext;
    unsigned char *md5_digest, *sha1_digest;
    unsigned int sha1_length, md5_length;
    int retval = 0;
    char buf[BUFSIZ];

    ctx = JAR_find(jar, "*", jarTypePhy);

    while (JAR_find_next(ctx, &it) >= 0) {
        if (!PORT_Strncmp(it->pathname, "META-INF", 8)) {
            for (ext = it->pathname; *ext; ext++)
                ;
            while (ext > it->pathname && *ext != '.')
                ext--;

            if (verbosity >= 0) {
                if (!PORT_Strcasecmp(ext, ".rsa")) {
                    PR_fprintf(outputFD, "found a RSA signature file: %s\n",
                               it->pathname);
                }

                if (!PORT_Strcasecmp(ext, ".dsa")) {
                    PR_fprintf(outputFD, "found a DSA signature file: %s\n",
                               it->pathname);
                }

                if (!PORT_Strcasecmp(ext, ".mf")) {
                    PR_fprintf(outputFD,
                               "found a MF master manifest file: %s\n",
                               it->pathname);
                }
            }

            if (!PORT_Strcasecmp(ext, ".sf")) {
                if (verbosity >= 0) {
                    PR_fprintf(outputFD,
                               "found a SF signature manifest file: %s\n",
                               it->pathname);
                }

                rm_dash_r(TMP_OUTPUT);
                if (JAR_extract(jar, it->pathname, TMP_OUTPUT) < 0) {
                    PR_fprintf(errorFD, "%s: error extracting %s\n",
                               PROGRAM_NAME, it->pathname);
                    errorCount++;
                    retval = -1;
                    continue;
                }

                md5_digest = NULL;
                sha1_digest = NULL;

                if ((fp = fopen(TMP_OUTPUT, "rb")) != NULL) {
                    while (fgets(buf, BUFSIZ, fp)) {
                        char *s;

                        if (*buf == 0 || *buf == '\n' || *buf == '\r')
                            break;

                        for (s = buf; *s && *s != '\n' && *s != '\r'; s++)
                            ;
                        *s = 0;

                        if (!PORT_Strncmp(buf, "MD5-Digest: ", 12)) {
                            md5_digest =
                                ATOB_AsciiToData(buf + 12, &md5_length);
                        }
                        if (!PORT_Strncmp(buf, "SHA1-Digest: ", 13)) {
                            sha1_digest =
                                ATOB_AsciiToData(buf + 13, &sha1_length);
                        }
                        if (!PORT_Strncmp(buf, "SHA-Digest: ", 12)) {
                            sha1_digest =
                                ATOB_AsciiToData(buf + 12, &sha1_length);
                        }
                    }

                    globaldig = jar->globalmeta;

                    if (globaldig && md5_digest && verbosity >= 0) {
                        PR_fprintf(outputFD,
                                   "  md5 digest on global metainfo: %s\n",
                                   PORT_Memcmp(md5_digest, globaldig->md5, MD5_LENGTH)
                                       ? "no match"
                                       : "match");
                    }

                    if (globaldig && sha1_digest && verbosity >= 0) {
                        PR_fprintf(outputFD,
                                   "  sha digest on global metainfo: %s\n",
                                   PORT_Memcmp(sha1_digest, globaldig->sha1, SHA1_LENGTH)
                                       ? "no match"
                                       : "match");
                    }

                    if (globaldig == NULL && verbosity >= 0) {
                        PR_fprintf(outputFD,
                                   "global metadigest is not available, strange.\n");
                    }

                    PORT_Free(md5_digest);
                    PORT_Free(sha1_digest);
                    fclose(fp);
                }
            }
        }
    }

    JAR_find_end(ctx);

    return retval;
}
Exemplo n.º 3
0
/*************************************************************************
 *
 * P k 1 1 I n s t a l l _ D o I n s t a l l
 *
 * jarFile is the path of a JAR in the PKCS #11 module JAR format.
 * installDir is the directory relative to which files will be
 *   installed.
 */
Pk11Install_Error
Pk11Install_DoInstall(char *jarFile, const char *installDir,
                      const char *tempDir, PRFileDesc *feedback, short force, PRBool noverify)
{
    JAR *jar;
    char *installer;
    unsigned long installer_len;
    int status;
    Pk11Install_Error ret;
    PRBool made_temp_file;
    Pk11Install_Info installInfo;
    Pk11Install_Platform *platform;
    char *errMsg;
    char sysname[SYS_INFO_BUFFER_LENGTH], release[SYS_INFO_BUFFER_LENGTH],
        arch[SYS_INFO_BUFFER_LENGTH];
    char *myPlatform;

    jar = NULL;
    ret = PK11_INSTALL_UNSPECIFIED;
    made_temp_file = PR_FALSE;
    errMsg = NULL;
    Pk11Install_Info_init(&installInfo);

    /*
    printf("Inside DoInstall, jarFile=%s, installDir=%s, tempDir=%s\n",
        jarFile, installDir, tempDir);
    */

    /*
     * Check out jarFile and installDir for validity
     */
    if (PR_Access(installDir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
        error(PK11_INSTALL_DIR_DOESNT_EXIST, installDir);
        return PK11_INSTALL_DIR_DOESNT_EXIST;
    }
    if (!tempDir) {
        tempDir = ".";
    }
    if (PR_Access(tempDir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
        error(PK11_INSTALL_DIR_DOESNT_EXIST, tempDir);
        return PK11_INSTALL_DIR_DOESNT_EXIST;
    }
    if (PR_Access(tempDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
        error(PK11_INSTALL_DIR_NOT_WRITEABLE, tempDir);
        return PK11_INSTALL_DIR_NOT_WRITEABLE;
    }
    if ((PR_Access(jarFile, PR_ACCESS_EXISTS) != PR_SUCCESS)) {
        error(PK11_INSTALL_FILE_DOESNT_EXIST, jarFile);
        return PK11_INSTALL_FILE_DOESNT_EXIST;
    }
    if (PR_Access(jarFile, PR_ACCESS_READ_OK) != PR_SUCCESS) {
        error(PK11_INSTALL_FILE_NOT_READABLE, jarFile);
        return PK11_INSTALL_FILE_NOT_READABLE;
    }

    /*
     * Extract the JAR file
     */
    jar = JAR_new();
    JAR_set_callback(JAR_CB_SIGNAL, jar, jar_callback);

    if (noverify) {
        status = JAR_pass_archive_unverified(jar, jarArchGuess, jarFile, "url");
    } else {
        status = JAR_pass_archive(jar, jarArchGuess, jarFile, "url");
    }
    if ((status < 0) || (jar->valid < 0)) {
        if (status >= JAR_BASE && status <= JAR_BASE_END) {
            error(PK11_INSTALL_JAR_ERROR, jarFile, JAR_get_error(status));
        } else {
            error(PK11_INSTALL_JAR_ERROR, jarFile,
                  mySECU_ErrorString(PORT_GetError()));
        }
        ret = PK11_INSTALL_JAR_ERROR;
        goto loser;
    }
    /*printf("passed the archive\n");*/

    /*
     * Show the user security information, allow them to abort or continue
     */
    if (Pk11Install_UserVerifyJar(jar, PR_STDOUT,
                                  force ?
                                        PR_FALSE
                                        :
                                        PR_TRUE) &&
        !force) {
        if (feedback) {
            PR_fprintf(feedback, msgStrings[USER_ABORT]);
        }
        ret = PK11_INSTALL_USER_ABORT;
        goto loser;
    }

    /*
     * Get the name of the installation file
     */
    if (JAR_get_metainfo(jar, NULL, INSTALL_METAINFO_TAG, (void **)&installer,
                         (unsigned long *)&installer_len)) {
        error(PK11_INSTALL_NO_INSTALLER_SCRIPT);
        ret = PK11_INSTALL_NO_INSTALLER_SCRIPT;
        goto loser;
    }
    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLER_SCRIPT_NAME], installer);
    }

    /*
     * Extract the installation file
     */
    if (PR_Access(SCRIPT_TEMP_FILE, PR_ACCESS_EXISTS) == PR_SUCCESS) {
        if (PR_Delete(SCRIPT_TEMP_FILE) != PR_SUCCESS) {
            error(PK11_INSTALL_DELETE_TEMP_FILE, SCRIPT_TEMP_FILE);
            ret = PK11_INSTALL_DELETE_TEMP_FILE;
            goto loser;
        }
    }
    if (noverify) {
        status = JAR_extract(jar, installer, SCRIPT_TEMP_FILE);
    } else {
        status = JAR_verified_extract(jar, installer, SCRIPT_TEMP_FILE);
    }
    if (status) {
        if (status >= JAR_BASE && status <= JAR_BASE_END) {
            error(PK11_INSTALL_JAR_EXTRACT, installer, JAR_get_error(status));
        } else {
            error(PK11_INSTALL_JAR_EXTRACT, installer,
                  mySECU_ErrorString(PORT_GetError()));
        }
        ret = PK11_INSTALL_JAR_EXTRACT;
        goto loser;
    } else {
        made_temp_file = PR_TRUE;
    }

    /*
     * Parse the installation file into a syntax tree
     */
    Pk11Install_FD = PR_Open(SCRIPT_TEMP_FILE, PR_RDONLY, 0);
    if (!Pk11Install_FD) {
        error(PK11_INSTALL_OPEN_SCRIPT_FILE, SCRIPT_TEMP_FILE);
        ret = PK11_INSTALL_OPEN_SCRIPT_FILE;
        goto loser;
    }
    if (Pk11Install_yyparse()) {
        error(PK11_INSTALL_SCRIPT_PARSE, installer,
              Pk11Install_yyerrstr ? Pk11Install_yyerrstr : "");
        ret = PK11_INSTALL_SCRIPT_PARSE;
        goto loser;
    }

#if 0
    /* for debugging */
    Pk11Install_valueList->Print(0);
#endif

    /*
     * From the syntax tree, build a semantic structure
     */
    errMsg = Pk11Install_Info_Generate(&installInfo, Pk11Install_valueList);
    if (errMsg) {
        error(PK11_INSTALL_SEMANTIC, errMsg);
        ret = PK11_INSTALL_SEMANTIC;
        goto loser;
    }
#if 0
    installInfo.Print(0);
#endif

    if (feedback) {
        PR_fprintf(feedback, msgStrings[PARSED_INSTALL_SCRIPT]);
    }

    /*
     * Figure out which platform to use
     */
    {
        sysname[0] = release[0] = arch[0] = '\0';

        if ((PR_GetSystemInfo(PR_SI_SYSNAME, sysname, SYS_INFO_BUFFER_LENGTH) !=
             PR_SUCCESS) ||
            (PR_GetSystemInfo(PR_SI_RELEASE, release, SYS_INFO_BUFFER_LENGTH) !=
             PR_SUCCESS) ||
            (PR_GetSystemInfo(PR_SI_ARCHITECTURE, arch, SYS_INFO_BUFFER_LENGTH) !=
             PR_SUCCESS)) {
            error(PK11_INSTALL_SYSINFO);
            ret = PK11_INSTALL_SYSINFO;
            goto loser;
        }
        myPlatform = PR_smprintf("%s:%s:%s", sysname, release, arch);
        platform = Pk11Install_Info_GetBestPlatform(&installInfo, myPlatform);
        if (!platform) {
            error(PK11_INSTALL_NO_PLATFORM, myPlatform);
            PR_smprintf_free(myPlatform);
            ret = PK11_INSTALL_NO_PLATFORM;
            goto loser;
        }
        if (feedback) {
            PR_fprintf(feedback, msgStrings[MY_PLATFORM_IS], myPlatform);
            PR_fprintf(feedback, msgStrings[USING_PLATFORM],
                       Pk11Install_PlatformName_GetString(&platform->name));
        }
        PR_smprintf_free(myPlatform);
    }

    /* Run the install for that platform */
    ret = DoInstall(jar, installDir, tempDir, platform, feedback, noverify);
    if (ret) {
        goto loser;
    }

    ret = PK11_INSTALL_SUCCESS;
loser:
    if (Pk11Install_valueList) {
        Pk11Install_ValueList_delete(Pk11Install_valueList);
        PR_Free(Pk11Install_valueList);
        Pk11Install_valueList = NULL;
    }
    if (jar) {
        JAR_destroy(jar);
    }
    if (made_temp_file) {
        PR_Delete(SCRIPT_TEMP_FILE);
    }
    if (errMsg) {
        PR_smprintf_free(errMsg);
    }
    return ret;
}