home *** CD-ROM | disk | FTP | other *** search
- /*
- # $Id: fortify.c,v 1.16 1998/04/10 10:27:56 fbm Exp fbm $
- # Copyright (C) 1997,1998 Farrell McKay
- # All rights reserved.
- #
- # This file is part of the Fortify distribution, a toolkit for
- # upgrading the cryptographic strength of the Netscape Navigator
- # web browser, authored by Farrell McKay.
- #
- # This toolkit is provided to the recipient under the
- # following terms and conditions:-
- # 1. This copyright notice must not be removed or modified.
- # 2. This toolkit may not be reproduced or included in any commercial
- # media distribution, or commercial publication (for example CD-ROM,
- # disk, book, magazine, journal) without first obtaining the author's
- # express permission.
- # 3. This toolkit, or any component of this toolkit, may not be
- # commercially resold, redeveloped, rewritten, enhanced or otherwise
- # used as the basis for commercial venture, without first obtaining
- # the author's express permission.
- # 4. Subject to the above conditions being observed (1-3), this toolkit
- # may be freely reproduced or redistributed.
- # 5. This software is provided "as-is", without express or implied
- # warranty. In no event shall the author be liable for any direct,
- # indirect or consequential damages however caused.
- # 6. Subject to the above conditions being observed (1-5),
- # this toolkit may be used at no cost to the recipient.
- #
- # Farrell McKay
- # Wayfarer Systems Pty Ltd contact@fortify.net
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include "misc.h"
- #include "index.h"
- #include "morpher.h"
- #include "os2lx.h"
- #include "trace.h"
-
- #if defined(GNU_WIN32)
- #define PATH_DELIM ';'
- #define NS_PROG "netscape.exe"
- #define EXAMPLE_PATH "C:\\Program Files\\Netscape\\Program\\netscape.exe"
- #elif defined(OS2)
- #define PATH_DELIM ';'
- #define NS_PROG "netscape.exe"
- #define EXAMPLE_PATH "C:\\Netscape\\netscape.exe"
- #else
- #define PATH_DELIM ':'
- #define NS_PROG "netscape"
- #define EXAMPLE_PATH "/usr/local/bin/netscape"
- #endif
-
- /* Unfortunately not all unistd.h headers contain this constant. */
- #ifndef W_OK
- #define W_OK 2
- #endif
-
- #ifndef MAXPATHLEN
- #define MAXPATHLEN 1024
- #endif
-
- static char *ffy_vern = "";
- static char *ffy_ident = "@(#) morpher 1.12";
-
- typedef struct {
- int n;
- char **paths;
- } dirlist_t;
-
- static void
- search_dir(char *dir, dirlist_t *dirlist)
- {
- int n = dirlist->n;
- char **p = dirlist->paths;
- char path[MAXPATHLEN+1];
- struct stat st;
-
- sprintf(path, "%s/%s", dir, NS_PROG);
- if (*dir && stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
- p = (char **) _realloc((void *) p, sizeof(char **) * ++n);
- p[n - 2] = _strdup(path);
- p[n - 1] = NULL;
- dirlist->n = n;
- dirlist->paths = p;
- }
- }
-
- static void
- search_path(dirlist_t *dirlist)
- {
- char *dir, *p;
-
- dirlist->n = 1;
- dirlist->paths = (char **) _calloc(1, sizeof(char **));
-
- if ((dir = getenv("MOZILLA_HOME")) != NULL)
- search_dir(dir, dirlist);
-
- if ((dir = getenv("PATH")) != NULL) {
- while ((p = strchr(dir, PATH_DELIM)) != NULL) {
- *p = '\0';
- search_dir(dir, dirlist);
- *p++ = PATH_DELIM;
- dir = p;
- }
- search_dir(dir, dirlist);
- }
- }
-
- static char *
- get_path(int i)
- {
- static char target[1024];
- int len;
-
- target[0] = '\0';
- for (;;) {
- printf("Enter the path name of your %s program, 'h' for help, or press <Rtn> to quit: ",
- NS_PROG);
- fgets(target, sizeof(target), stdin);
- len = strlen(target);
- if (len > 0 && target[len-1] == '\n')
- target[len-1] = '\0';
- if (strcmp(target, "h") != 0)
- break;
-
- printf("\n");
- printf("Enter the full path name of the file that you wish to fortify, for example:\n");
- printf(" %s\n", EXAMPLE_PATH);
- printf("\n");
- printf("Note that you must not be running that copy of Netscape at the moment,\n");
- printf("and you must have write permission on that file.\n");
- printf("\n");
- }
- return target;
- }
-
- static char *
- get_target(int n, dirlist_t *dirlist)
- {
- static char ans[1024];
- int i, len;
-
- printf("\n");
-
- if (dirlist->n <= 1)
- return get_path(n);
-
- for (i = 1; i < dirlist->n; i++)
- printf(" %d = fortify \"%s\"\n", i, dirlist->paths[i-1]);
-
- printf(" e = enter some other full path name\n");
- printf("<Rtn> = quit\n");
-
- ans[0] = '\0';
- for (;;) {
- if (dirlist->n < 3)
- printf("\nPlease make a selection [1,e,<Rtn>]: ");
- else
- printf("\nPlease make a selection [1-%d,e,<Rtn>]: ", dirlist->n - 1);
-
- fgets(ans, sizeof(ans), stdin);
- len = strlen(ans);
- if (len > 0 && ans[len-1] == '\n')
- ans[--len] = '\0';
-
- if (len == 0)
- break;
- if (*ans == 'e' || *ans == 'E')
- return get_path(n);
- if (isnumeric(ans) && atoi(ans) > 0 && atoi(ans) < dirlist->n)
- return dirlist->paths[atoi(ans) - 1];
- }
- return ans;
- }
-
- static int
- confirm(char *action, char *tgt, int noprompts)
- {
- char buf[8];
-
- printf("\n");
-
- for (;;) {
- printf("Do you wish to %s \"%s\" [yes|no|quit] ? ", action, tgt);
- if (noprompts) {
- printf("yes\n");
- buf[0] = 'y';
- }
- else {
- fgets(buf, sizeof(buf), stdin);
- }
- if (buf[0] == 'q' || buf[0] == 'Q')
- exit(0);
- if (buf[0] == 'n' || buf[0] == 'N')
- return 0;
- if (buf[0] == 'y' || buf[0] == 'Y')
- return 1;
- }
- }
-
- static int
- perform_fortify(char *tgt, int noprompts)
- {
- char buf[32];
-
- printf("\n");
-
- for (;;) {
- printf("Please select an action [fortify|de-fortify|help|quit] : ");
- if (noprompts) {
- printf("fortify\n");
- buf[0] = 'f';
- }
- else {
- fgets(buf, sizeof(buf), stdin);
- }
- if (buf[0] == 'q' || buf[0] == 'Q')
- exit(0);
- if (buf[0] == 'f' || buf[0] == 'F')
- return 1;
- if (buf[0] == 'd' || buf[0] == 'D')
- return 0;
- if (buf[0] == 'h' || buf[0] == 'H') {
- printf("\n");
- printf("Your Netscape browser currently has fortified-SSL capabilities only.\n");
- printf("At this point, you can choose to either de-fortify your web browser,\n");
- printf("or install all the additional strong encryption features that are provided in this\n");
- printf("version of Fortify (for example, strong e-mail encryption and 1024-bit RSA keys).\n");
- printf("\n");
- }
- }
- }
-
- static void
- cp(char *from, char *to)
- {
- int ifd = 0;
- int ofd = 0;
- int nb, nr, nw;
- int dot_ival = 512 * 1024;
- char *p, buf[16*1024];
-
- printf("Writing backup copy to \"%s\" ", to);
-
- if ((ifd = open(from, OPENFL(O_RDONLY), 0666)) == -1) {
- fprintf(stderr, "Cannot open \"%s\": ", from);
- perror("");
- goto done;
- }
-
- if ((ofd = open(to, OPENFL(O_WRONLY|O_CREAT|O_TRUNC), 0666)) == -1) {
- fprintf(stderr, "Cannot open \"%s\": ", to);
- perror("");
- goto done;
- }
-
- for (nb = 0; (nr = read(ifd, buf, sizeof(buf))) > 0;) {
- for (p = buf; nr > 0;) {
- nw = write(ofd, p, nr);
- if (nw <= 0) {
- putchar('\n');
- fprintf(stderr, "Error while writing to \"%s\": ", to);
- perror("");
- unlink(to);
- goto done;
- }
- p += nw;
- nr -= nw;
- if ((nb + nw) / dot_ival > nb / dot_ival) {
- putchar('.');
- fflush(stdout);
- }
- nb += nw;
- }
- }
- if (nr == 0)
- printf(" done\n");
- else {
- putchar('\n');
- fprintf(stderr, "Error while reading from \"%s\": ", from);
- perror("");
- unlink(to);
- }
- done:
- close(ifd);
- close(ofd);
- }
-
- static void
- dobackup(char *tgt, int noprompts)
- {
- char *bak, buf[8];
- int len;
-
- for (;;) {
- printf("Do you wish to keep a backup copy of \"%s\" [yes|no|quit] ? ", tgt);
- if (noprompts) {
- printf("yes\n");
- buf[0] = 'y';
- }
- else {
- fgets(buf, sizeof(buf), stdin);
- }
- if (buf[0] == 'q' || buf[0] == 'Q')
- exit(0);
- if (buf[0] == 'n' || buf[0] == 'N')
- return;
- if (buf[0] == 'y' || buf[0] == 'Y')
- break;
- }
-
- /*
- * I didn't want to do things this way. MS-Windows made me do it.
- */
-
- len = strlen(tgt);
- bak = _malloc(len + 8);
- sprintf(bak, "%s.sav", tgt);
-
- if (len > 4 && strncmp(tgt + len - 4, ".exe", 4) == 0)
- strcpy(bak + strlen(bak) - 8, ".sav");
-
- cp(tgt, bak);
- free(bak);
- }
-
- static int
- morph(char *tgt, char *morphs, int noprompts, int nowrite, int verbose)
- {
- int err, access_mode;
- int new_grade;
- char dflt_morphs[1024];
- char *prod;
- char *action;
- index_entry_t *ent;
-
- access_mode = nowrite? R_OK: W_OK;
- if (access(tgt, access_mode) == -1) {
- if (errno == ENOENT)
- printf("Woops: \"%s\" does not exist\n", tgt);
- else
- printf("Woops: you do not have %s permission on \"%s\"\n",
- nowrite? "read": "write", tgt);
- return 1;
- }
-
- printf("\n\"%s\" is .... ", tgt);
- fflush(stdout);
-
- ent = index_lookup(tgt, &err);
- if (ent == NULL) {
- if (err == ERR_OPEN) {
- printf("not recognisable.\n");
- printf("Cannot open \"%s\": ", tgt);
- perror("");
- }
- else if (err == ERR_LXCOMPR) {
- printf("an OS/2 executable file in compressed (EXEPACK:2) format.\n");
- printf("Please re-run Fortify after decompressing this file.\n");
- printf("The command:\n");
- printf(" repack.exe /exepack:0 %s\n", tgt);
- printf("can be used to decompress the file. Please refer to\n");
- printf("the Fortify README documentation for further details.\n");
- }
- else if (err == ERR_ISSCRIPT) {
- printf("not recognisable.\n");
- printf("It appears to be a shell script or batch file - rather than\n");
- printf("a Netscape executable program. It may be a shell script that\n");
- printf("calls your Netscape browser indirectly. Please re-run Fortify,\n");
- printf("specifying the location of your Netscape executable program.\n");
- }
- else {
- printf("not recognisable.\n");
- printf("It is either not a copy of Netscape, or it is a version\n");
- printf("of Netscape that is not listed in the Index file.\n");
- }
- return 1;
- }
-
- if (strcmp(ent->flds[IDX_PROD], "nav") == 0)
- prod = "Navigator";
- else if (strcmp(ent->flds[IDX_PROD], "gold") == 0)
- prod = "Navigator Gold";
- else if (strcmp(ent->flds[IDX_PROD], "comm") == 0)
- prod = "Communicator";
- else if (strcmp(ent->flds[IDX_PROD], "pro") == 0)
- prod = "Communicator Pro/Complete";
- else {
- printf("not a known Netscape product (\"%s\").\n", ent->flds[IDX_PROD]);
- printf("Please check the Index file for correct formatting.\n");
- return 1;
- }
-
- printf("\n.... Netscape %s %s for %s (%s) %s\n",
- prod, ent->flds[IDX_VERN], ent->flds[IDX_ARCH],
- ent->flds[IDX_GRADE], ent->flds[IDX_COMMENTS]);
-
- if (morphs == NULL && !have_morphs(ent)) {
- printf("Sorry. Fortify-%s does not support that version of Netscape\n",
- ffy_vern);
- return 1;
- }
-
- if (ent->grade == ent->max_grade) {
- if (!nowrite && confirm("de-fortify", tgt, noprompts) == 0) {
- printf("As you wish. \"%s\" not modified.\n", tgt);
- return 0;
- }
- new_grade = 0;
- action = "de-fortified";
- }
- else if (ent->grade == 0) {
- if (!nowrite && confirm("fortify", tgt, noprompts) == 0) {
- printf("As you wish. \"%s\" not modified.\n", tgt);
- return 0;
- }
- new_grade = ent->max_grade;
- action = "fortified";
- }
- else {
- if (!perform_fortify(tgt, noprompts)) {
- new_grade = 0;
- action = "de-fortified";
- } else {
- new_grade = ent->max_grade;
- action = "upgraded";
- }
- }
-
- if (!nowrite)
- dobackup(tgt, noprompts);
-
- if (morphs != NULL) {
- printf("Applying override morph file \"%s\"\n", morphs);
- } else {
- sprintf(dflt_morphs, "%s/%s-%s/%s",
- ent->flds[IDX_ARCH], ent->flds[IDX_PROD],
- ent->flds[IDX_VERN], ent->flds[IDX_MORPHS]);
- morphs = dflt_morphs;
- }
- err = morpher(tgt, morphs, ent, nowrite, ent->grade, new_grade, verbose);
- if (!err) {
- printf("%s. \"%s\" %ssuccessfully %s.\n",
- (!nowrite && (new_grade > ent->grade))? "Congratulations": "Done",
- tgt, nowrite? "can be ": "has been ", action);
- #if defined(OS2)
- if (!nowrite) {
- printf("\n");
- printf("Note: If you have used repack.exe to de-compress this file, don't forget\n");
- printf("to update your Netscape desktop icon so that it now refers to\n");
- printf("\"%s\"\n", tgt);
- }
- #endif
- }
-
- printf("\n");
- return err;
- }
-
- static void
- usage(char *prog_name)
- {
- fprintf(stderr, "Usage: %s [-f] [-i index] [-m morphs] [-n] [-t N] [-v] [-V] [target ...]\n", prog_name);
- fprintf(stderr, "\t-f force execution; no user prompts are performed\n");
- fprintf(stderr, "\t-i override the default index file \"./Index\"\n");
- fprintf(stderr, "\t-m override the default morphs file\n");
- fprintf(stderr, "\t-n no writes; check morphs integrity only\n");
- fprintf(stderr, "\t-t additional trace diagnostics (level N >= 2)\n");
- fprintf(stderr, "\t-v verbose mode\n");
- fprintf(stderr, "\t-V print this program's version and exit\n");
- exit(1);
- }
-
- int
- main(int argc, char *argv[])
- {
- int i, level;
- int rtn = 0;
- int noprompts = 0;
- int nowrite = 0;
- int verbose = 0;
- char *prog_name = argv[0];
- char *index = "./Index";
- char *morphs = NULL;
- char *tgt;
-
- traceinit(0);
-
- argc--, argv++;
- while (argc > 0 && argv[0][0] == '-') {
- if (argv[0][1] == '-')
- ;
- else if (argv[0][1] == 'f') {
- noprompts = 1;
- }
- else if (argv[0][1] == 'n')
- nowrite = 1;
- else if (argv[0][1] == 'i') {
- argc--, argv++;
- if (argc < 1)
- usage(prog_name);
- index = *argv;
- }
- else if (argv[0][1] == 'm') {
- argc--, argv++;
- if (argc < 1)
- usage(prog_name);
- morphs = *argv;
- }
- else if (argv[0][1] == 't') {
- argc--, argv++;
- if (argc < 1)
- usage(prog_name);
- level = atoi(*argv);
- if (level < 2)
- usage(prog_name);
- traceinit(level);
- verbose = 1;
- }
- else if (argv[0][1] == 'v')
- verbose = 1;
- else if (argv[0][1] == 'V') {
- printf("%s\n", ffy_ident);
- return 0;
- }
- else
- usage(prog_name);
- argc--, argv++;
- }
-
- if (build_index(index, (char **) &ffy_vern) == -1) {
- usage(prog_name);
- exit(1);
- }
-
- printf("==== Fortify %s; Copyright (C) 1997,1998 Farrell McKay ====\n", ffy_vern);
-
- if (nowrite)
- printf("\n*** 'nowrite' mode enabled - no modifications will be made.\n");
-
- if (argc > 0) {
- for (i = 0; i < argc; i++) {
- rtn |= morph(argv[i], morphs, noprompts, nowrite, verbose);
- }
- }
- else {
- dirlist_t d;
-
- search_path(&d);
- for (i = 0; *(tgt = get_target(i, &d)) != '\0'; i++) {
- rtn |= morph(tgt, morphs, noprompts, nowrite, verbose);
- }
- }
- return rtn;
- }
-