home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 December / PCO_1298.ISO / filesbbs / os2 / fn128os2.arj / FN128OS2.ZIP / fn128os2 / src / fortify.c next >
Encoding:
C/C++ Source or Header  |  1998-10-02  |  13.9 KB  |  566 lines

  1. /*
  2.  # $Id: fortify.c,v 1.16 1998/04/10 10:27:56 fbm Exp fbm $
  3.  # Copyright (C) 1997,1998 Farrell McKay
  4.  # All rights reserved.
  5.  #
  6.  # This file is part of the Fortify distribution, a toolkit for
  7.  # upgrading the cryptographic strength of the Netscape Navigator
  8.  # web browser, authored by Farrell McKay.
  9.  #
  10.  # This toolkit is provided to the recipient under the
  11.  # following terms and conditions:-
  12.  #   1.  This copyright notice must not be removed or modified.
  13.  #   2.  This toolkit may not be reproduced or included in any commercial
  14.  #       media distribution, or commercial publication (for example CD-ROM,
  15.  #       disk, book, magazine, journal) without first obtaining the author's
  16.  #       express permission.
  17.  #   3.  This toolkit, or any component of this toolkit, may not be
  18.  #       commercially resold, redeveloped, rewritten, enhanced or otherwise
  19.  #       used as the basis for commercial venture, without first obtaining
  20.  #       the author's express permission.
  21.  #   4.  Subject to the above conditions being observed (1-3), this toolkit
  22.  #       may be freely reproduced or redistributed.
  23.  #   5.  This software is provided "as-is", without express or implied
  24.  #       warranty.  In no event shall the author be liable for any direct,
  25.  #       indirect or consequential damages however caused.
  26.  #   6.  Subject to the above conditions being observed (1-5),
  27.  #       this toolkit may be used at no cost to the recipient.
  28.  #
  29.  # Farrell McKay
  30.  # Wayfarer Systems Pty Ltd        contact@fortify.net
  31.  */
  32.  
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <fcntl.h>
  37. #include <unistd.h>
  38. #include <errno.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41.  
  42. #include "misc.h"
  43. #include "index.h"
  44. #include "morpher.h"
  45. #include "os2lx.h"
  46. #include "trace.h"
  47.  
  48. #if defined(GNU_WIN32)
  49. #define PATH_DELIM    ';'
  50. #define NS_PROG        "netscape.exe"
  51. #define EXAMPLE_PATH    "C:\\Program Files\\Netscape\\Program\\netscape.exe"
  52. #elif defined(OS2)
  53. #define PATH_DELIM    ';'
  54. #define NS_PROG        "netscape.exe"
  55. #define EXAMPLE_PATH    "C:\\Netscape\\netscape.exe"
  56. #else
  57. #define PATH_DELIM    ':'
  58. #define NS_PROG        "netscape"
  59. #define EXAMPLE_PATH    "/usr/local/bin/netscape"
  60. #endif
  61.  
  62. /* Unfortunately not all unistd.h headers contain this constant. */
  63. #ifndef    W_OK
  64. #define    W_OK        2
  65. #endif
  66.  
  67. #ifndef    MAXPATHLEN
  68. #define MAXPATHLEN    1024
  69. #endif
  70.  
  71. static char        *ffy_vern  = "";
  72. static char        *ffy_ident = "@(#) morpher 1.12";
  73.  
  74. typedef struct {
  75.     int    n;
  76.     char    **paths;
  77. } dirlist_t;
  78.  
  79. static void
  80. search_dir(char *dir, dirlist_t *dirlist)
  81. {
  82.     int        n = dirlist->n;
  83.     char        **p = dirlist->paths;
  84.         char        path[MAXPATHLEN+1];
  85.     struct stat    st;
  86.  
  87.         sprintf(path, "%s/%s", dir, NS_PROG);
  88.         if (*dir && stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
  89.         p = (char **) _realloc((void *) p, sizeof(char **) * ++n);
  90.         p[n - 2] = _strdup(path);
  91.         p[n - 1] = NULL;
  92.         dirlist->n = n;
  93.         dirlist->paths = p;
  94.     }
  95. }
  96.  
  97. static void
  98. search_path(dirlist_t *dirlist)
  99. {
  100.     char    *dir, *p;
  101.  
  102.     dirlist->n = 1;
  103.     dirlist->paths = (char **) _calloc(1, sizeof(char **));
  104.  
  105.     if ((dir = getenv("MOZILLA_HOME")) != NULL)
  106.         search_dir(dir, dirlist);
  107.  
  108.     if ((dir = getenv("PATH")) != NULL) {
  109.         while ((p = strchr(dir, PATH_DELIM)) != NULL) {
  110.             *p = '\0';
  111.             search_dir(dir, dirlist);
  112.             *p++ = PATH_DELIM;
  113.             dir = p;
  114.         }
  115.         search_dir(dir, dirlist);
  116.     }
  117. }
  118.  
  119. static char *
  120. get_path(int i)
  121. {
  122.     static char    target[1024];
  123.     int        len;
  124.  
  125.     target[0] = '\0';
  126.     for (;;) {
  127.         printf("Enter the path name of your %s program, 'h' for help, or press <Rtn> to quit: ",
  128.             NS_PROG);
  129.         fgets(target, sizeof(target), stdin);
  130.         len = strlen(target);
  131.         if (len > 0 && target[len-1] == '\n')
  132.             target[len-1] = '\0';
  133.         if (strcmp(target, "h") != 0)
  134.             break;
  135.  
  136.         printf("\n");
  137.         printf("Enter the full path name of the file that you wish to fortify, for example:\n");
  138.         printf("    %s\n", EXAMPLE_PATH);
  139.         printf("\n");
  140.         printf("Note that you must not be running that copy of Netscape at the moment,\n");
  141.         printf("and you must have write permission on that file.\n");
  142.         printf("\n");
  143.     }
  144.     return target;
  145. }
  146.  
  147. static char *
  148. get_target(int n, dirlist_t *dirlist)
  149. {
  150.     static char    ans[1024];
  151.     int        i, len;
  152.  
  153.     printf("\n");
  154.  
  155.     if (dirlist->n <= 1)
  156.         return get_path(n);
  157.  
  158.     for (i = 1; i < dirlist->n; i++)
  159.         printf("    %d = fortify \"%s\"\n", i, dirlist->paths[i-1]);
  160.  
  161.     printf("    e = enter some other full path name\n");
  162.     printf("<Rtn> = quit\n");
  163.  
  164.     ans[0] = '\0';
  165.     for (;;) {
  166.         if (dirlist->n < 3)
  167.             printf("\nPlease make a selection [1,e,<Rtn>]: ");
  168.         else
  169.             printf("\nPlease make a selection [1-%d,e,<Rtn>]: ", dirlist->n - 1);
  170.  
  171.         fgets(ans, sizeof(ans), stdin);
  172.         len = strlen(ans);
  173.         if (len > 0 && ans[len-1] == '\n')
  174.             ans[--len] = '\0';
  175.  
  176.         if (len == 0)
  177.             break;
  178.         if (*ans == 'e' || *ans == 'E')
  179.             return get_path(n);
  180.         if (isnumeric(ans) && atoi(ans) > 0 && atoi(ans) < dirlist->n)
  181.             return dirlist->paths[atoi(ans) - 1];
  182.     }
  183.     return ans;
  184. }
  185.  
  186. static int
  187. confirm(char *action, char *tgt, int noprompts)
  188. {
  189.         char    buf[8];
  190.  
  191.         printf("\n");
  192.  
  193.         for (;;) {
  194.                 printf("Do you wish to %s \"%s\" [yes|no|quit] ? ", action, tgt);
  195.         if (noprompts) {
  196.             printf("yes\n");
  197.             buf[0] = 'y';
  198.         }
  199.         else {
  200.             fgets(buf, sizeof(buf), stdin);
  201.         }
  202.                 if (buf[0] == 'q' || buf[0] == 'Q')
  203.                         exit(0);
  204.                 if (buf[0] == 'n' || buf[0] == 'N')
  205.                         return 0;
  206.                 if (buf[0] == 'y' || buf[0] == 'Y')
  207.                         return 1;
  208.         }
  209. }
  210.  
  211. static int
  212. perform_fortify(char *tgt, int noprompts)
  213. {
  214.     char    buf[32];
  215.  
  216.     printf("\n");
  217.  
  218.     for (;;) {
  219.         printf("Please select an action [fortify|de-fortify|help|quit] : ");
  220.         if (noprompts) {
  221.             printf("fortify\n");
  222.             buf[0] = 'f';
  223.         }
  224.         else {
  225.             fgets(buf, sizeof(buf), stdin);
  226.         }
  227.         if (buf[0] == 'q' || buf[0] == 'Q')
  228.             exit(0);
  229.         if (buf[0] == 'f' || buf[0] == 'F')
  230.             return 1;
  231.         if (buf[0] == 'd' || buf[0] == 'D')
  232.             return 0;
  233.         if (buf[0] == 'h' || buf[0] == 'H') {
  234.             printf("\n");
  235.             printf("Your Netscape browser currently has fortified-SSL capabilities only.\n");
  236.             printf("At this point, you can choose to either de-fortify your web browser,\n");
  237.             printf("or install all the additional strong encryption features that are provided in this\n");
  238.             printf("version of Fortify (for example, strong e-mail encryption and 1024-bit RSA keys).\n");
  239.             printf("\n");
  240.         }
  241.     }
  242. }
  243.  
  244. static void
  245. cp(char *from, char *to)
  246. {
  247.     int        ifd = 0;
  248.     int        ofd = 0;
  249.     int        nb, nr, nw;
  250.     int        dot_ival = 512 * 1024;
  251.     char        *p, buf[16*1024];
  252.  
  253.     printf("Writing backup copy to \"%s\" ", to);
  254.  
  255.     if ((ifd = open(from, OPENFL(O_RDONLY), 0666)) == -1) {
  256.         fprintf(stderr, "Cannot open \"%s\": ", from);
  257.         perror("");
  258.         goto done;
  259.     }
  260.  
  261.     if ((ofd = open(to, OPENFL(O_WRONLY|O_CREAT|O_TRUNC), 0666)) == -1) {
  262.         fprintf(stderr, "Cannot open \"%s\": ", to);
  263.         perror("");
  264.         goto done;
  265.     }
  266.  
  267.     for (nb = 0; (nr = read(ifd, buf, sizeof(buf))) > 0;) {
  268.         for (p = buf; nr > 0;) {
  269.             nw = write(ofd, p, nr);
  270.             if (nw <= 0) {
  271.                 putchar('\n');
  272.                 fprintf(stderr, "Error while writing to \"%s\": ", to);
  273.                 perror("");
  274.                 unlink(to);
  275.                 goto done;
  276.             }
  277.             p += nw;
  278.             nr -= nw;
  279.             if ((nb + nw) / dot_ival > nb / dot_ival) {
  280.                 putchar('.');
  281.                 fflush(stdout);
  282.             }
  283.             nb += nw;
  284.         }
  285.     }
  286.     if (nr == 0)
  287.         printf(" done\n");
  288.     else {
  289.         putchar('\n');
  290.         fprintf(stderr, "Error while reading from \"%s\": ", from);
  291.         perror("");
  292.         unlink(to);
  293.     }
  294. done:
  295.     close(ifd);
  296.     close(ofd);
  297. }
  298.  
  299. static void
  300. dobackup(char *tgt, int noprompts)
  301. {
  302.     char    *bak, buf[8];
  303.     int    len;
  304.  
  305.     for (;;) {
  306.         printf("Do you wish to keep a backup copy of \"%s\" [yes|no|quit] ? ", tgt);
  307.         if (noprompts) {
  308.             printf("yes\n");
  309.             buf[0] = 'y';
  310.         }
  311.         else {
  312.             fgets(buf, sizeof(buf), stdin);
  313.         }
  314.         if (buf[0] == 'q' || buf[0] == 'Q')
  315.             exit(0);
  316.         if (buf[0] == 'n' || buf[0] == 'N')
  317.             return;
  318.         if (buf[0] == 'y' || buf[0] == 'Y')
  319.             break;
  320.     }
  321.  
  322.     /*
  323.      * I didn't want to do things this way.  MS-Windows made me do it.
  324.      */
  325.  
  326.     len = strlen(tgt);
  327.     bak = _malloc(len + 8);
  328.     sprintf(bak, "%s.sav", tgt);
  329.  
  330.     if (len > 4 && strncmp(tgt + len - 4, ".exe", 4) == 0)
  331.         strcpy(bak + strlen(bak) - 8, ".sav");
  332.  
  333.     cp(tgt, bak);
  334.     free(bak);
  335. }
  336.  
  337. static int
  338. morph(char *tgt, char *morphs, int noprompts, int nowrite, int verbose)
  339. {
  340.     int        err, access_mode;
  341.     int        new_grade;
  342.     char        dflt_morphs[1024];
  343.     char        *prod;
  344.     char        *action;
  345.     index_entry_t    *ent;
  346.  
  347.     access_mode = nowrite? R_OK: W_OK;
  348.     if (access(tgt, access_mode) == -1) {
  349.         if (errno == ENOENT)
  350.             printf("Woops: \"%s\" does not exist\n", tgt);
  351.         else
  352.             printf("Woops: you do not have %s permission on \"%s\"\n",
  353.                 nowrite? "read": "write", tgt);
  354.         return 1;
  355.     }
  356.  
  357.     printf("\n\"%s\" is .... ", tgt);
  358.     fflush(stdout);
  359.  
  360.     ent = index_lookup(tgt, &err);
  361.     if (ent == NULL) {
  362.         if (err == ERR_OPEN) {
  363.             printf("not recognisable.\n");
  364.             printf("Cannot open \"%s\": ", tgt);
  365.             perror("");
  366.         }
  367.         else if (err == ERR_LXCOMPR) {
  368.             printf("an OS/2 executable file in compressed (EXEPACK:2) format.\n");
  369.             printf("Please re-run Fortify after decompressing this file.\n");
  370.             printf("The command:\n");
  371.             printf("        repack.exe /exepack:0 %s\n", tgt);
  372.             printf("can be used to decompress the file.  Please refer to\n");
  373.             printf("the Fortify README documentation for further details.\n");
  374.         }
  375.         else if (err == ERR_ISSCRIPT) {
  376.             printf("not recognisable.\n");
  377.             printf("It appears to be a shell script or batch file - rather than\n");
  378.             printf("a Netscape executable program.  It may be a shell script that\n");
  379.             printf("calls your Netscape browser indirectly.  Please re-run Fortify,\n");
  380.             printf("specifying the location of your Netscape executable program.\n");
  381.         }
  382.         else {
  383.             printf("not recognisable.\n");
  384.             printf("It is either not a copy of Netscape, or it is a version\n");
  385.             printf("of Netscape that is not listed in the Index file.\n");
  386.         }
  387.         return 1;
  388.     }
  389.  
  390.     if (strcmp(ent->flds[IDX_PROD], "nav") == 0)
  391.         prod = "Navigator";
  392.     else if (strcmp(ent->flds[IDX_PROD], "gold") == 0)
  393.         prod = "Navigator Gold";
  394.     else if (strcmp(ent->flds[IDX_PROD], "comm") == 0)
  395.         prod = "Communicator";
  396.     else if (strcmp(ent->flds[IDX_PROD], "pro") == 0)
  397.         prod = "Communicator Pro/Complete";
  398.     else {
  399.         printf("not a known Netscape product (\"%s\").\n", ent->flds[IDX_PROD]);
  400.         printf("Please check the Index file for correct formatting.\n");
  401.         return 1;
  402.     }
  403.  
  404.     printf("\n.... Netscape %s %s for %s (%s) %s\n",
  405.         prod, ent->flds[IDX_VERN], ent->flds[IDX_ARCH],
  406.         ent->flds[IDX_GRADE], ent->flds[IDX_COMMENTS]);
  407.  
  408.     if (morphs == NULL && !have_morphs(ent)) {
  409.         printf("Sorry.  Fortify-%s does not support that version of Netscape\n",
  410.             ffy_vern);
  411.         return 1;
  412.     }
  413.  
  414.     if (ent->grade == ent->max_grade) {
  415.         if (!nowrite && confirm("de-fortify", tgt, noprompts) == 0) {
  416.             printf("As you wish.  \"%s\" not modified.\n", tgt);
  417.             return 0;
  418.         }
  419.         new_grade = 0;
  420.         action = "de-fortified";
  421.     }
  422.     else if (ent->grade == 0) {
  423.         if (!nowrite && confirm("fortify", tgt, noprompts) == 0) {
  424.             printf("As you wish.  \"%s\" not modified.\n", tgt);
  425.             return 0;
  426.         }
  427.         new_grade = ent->max_grade;
  428.         action = "fortified";
  429.     }
  430.     else {
  431.         if (!perform_fortify(tgt, noprompts)) {
  432.             new_grade = 0;
  433.             action = "de-fortified";
  434.         } else {
  435.             new_grade = ent->max_grade;
  436.             action = "upgraded";
  437.         }
  438.     }
  439.  
  440.     if (!nowrite)
  441.         dobackup(tgt, noprompts);
  442.  
  443.     if (morphs != NULL) {
  444.         printf("Applying override morph file \"%s\"\n", morphs);
  445.     } else {
  446.         sprintf(dflt_morphs, "%s/%s-%s/%s",
  447.             ent->flds[IDX_ARCH], ent->flds[IDX_PROD],
  448.             ent->flds[IDX_VERN], ent->flds[IDX_MORPHS]);
  449.         morphs = dflt_morphs;
  450.     }
  451.     err = morpher(tgt, morphs, ent, nowrite, ent->grade, new_grade, verbose);
  452.     if (!err) {
  453.         printf("%s. \"%s\" %ssuccessfully %s.\n",
  454.             (!nowrite && (new_grade > ent->grade))? "Congratulations": "Done",
  455.             tgt, nowrite? "can be ": "has been ", action);
  456. #if defined(OS2)
  457.         if (!nowrite) {
  458.             printf("\n");
  459.             printf("Note: If you have used repack.exe to de-compress this file, don't forget\n");
  460.             printf("to update your Netscape desktop icon so that it now refers to\n");
  461.             printf("\"%s\"\n", tgt);
  462.         }
  463. #endif
  464.     }
  465.  
  466.     printf("\n");
  467.     return err;
  468. }
  469.  
  470. static void
  471. usage(char *prog_name)
  472. {
  473.     fprintf(stderr, "Usage: %s [-f] [-i index] [-m morphs] [-n] [-t N] [-v] [-V] [target ...]\n", prog_name);
  474.     fprintf(stderr, "\t-f  force execution; no user prompts are performed\n");
  475.     fprintf(stderr, "\t-i  override the default index file \"./Index\"\n");
  476.     fprintf(stderr, "\t-m  override the default morphs file\n");
  477.     fprintf(stderr, "\t-n  no writes; check morphs integrity only\n");
  478.     fprintf(stderr, "\t-t  additional trace diagnostics (level N >= 2)\n");
  479.     fprintf(stderr, "\t-v  verbose mode\n");
  480.     fprintf(stderr, "\t-V  print this program's version and exit\n");
  481.     exit(1);
  482. }
  483.  
  484. int
  485. main(int argc, char *argv[])
  486. {
  487.     int        i, level;
  488.     int        rtn = 0;
  489.     int        noprompts = 0;
  490.     int        nowrite = 0;
  491.     int        verbose = 0;
  492.     char        *prog_name = argv[0];
  493.     char        *index = "./Index";
  494.     char        *morphs = NULL;
  495.     char        *tgt;
  496.  
  497.     traceinit(0);
  498.  
  499.     argc--, argv++;
  500.     while (argc > 0 && argv[0][0] == '-') {
  501.         if (argv[0][1] == '-')
  502.             ;
  503.         else if (argv[0][1] == 'f') {
  504.             noprompts = 1;
  505.         }
  506.         else if (argv[0][1] == 'n')
  507.             nowrite = 1;
  508.         else if (argv[0][1] == 'i') {
  509.             argc--, argv++;
  510.             if (argc < 1)
  511.                 usage(prog_name);
  512.             index = *argv;
  513.         }
  514.         else if (argv[0][1] == 'm') {
  515.             argc--, argv++;
  516.             if (argc < 1)
  517.                 usage(prog_name);
  518.             morphs = *argv;
  519.         }
  520.         else if (argv[0][1] == 't') {
  521.             argc--, argv++;
  522.             if (argc < 1)
  523.                 usage(prog_name);
  524.             level = atoi(*argv);
  525.             if (level < 2)
  526.                 usage(prog_name);
  527.             traceinit(level);
  528.             verbose = 1;
  529.         }
  530.         else if (argv[0][1] == 'v')
  531.             verbose = 1;
  532.         else if (argv[0][1] == 'V') {
  533.             printf("%s\n", ffy_ident);
  534.             return 0;
  535.         }
  536.         else
  537.             usage(prog_name);
  538.         argc--, argv++;
  539.     }
  540.  
  541.     if (build_index(index, (char **) &ffy_vern) == -1) {
  542.         usage(prog_name);
  543.         exit(1);
  544.     }
  545.  
  546.     printf("====   Fortify %s; Copyright (C) 1997,1998 Farrell McKay   ====\n", ffy_vern);
  547.  
  548.     if (nowrite)
  549.         printf("\n*** 'nowrite' mode enabled - no modifications will be made.\n");
  550.  
  551.     if (argc > 0) {
  552.         for (i = 0; i < argc; i++) {
  553.             rtn |= morph(argv[i], morphs, noprompts, nowrite, verbose);
  554.         }
  555.     }
  556.     else {
  557.         dirlist_t    d;
  558.  
  559.         search_path(&d);
  560.         for (i = 0; *(tgt = get_target(i, &d)) != '\0'; i++) {
  561.             rtn |= morph(tgt, morphs, noprompts, nowrite, verbose);
  562.         }
  563.     }
  564.     return rtn;
  565. }
  566.