Re: Verity/Search'97 Security Problems

From: Jay Soffian (jayat_private)
Date: Thu Jul 16 1998 - 14:04:19 PDT

  • Next message: Anonymous: "EMERGENCY: new remote root exploit in UW imapd"

    --Multipart_Thu_Jul_16_17:04:19_1998-1
    Content-Type: text/plain; charset=US-ASCII
    
    
    Here is a wrapper I just wrote to clean up ResultTemplate. It's
    working for us. YMMV.
    
    j.
    --
    Jay Soffian <jayat_private>                       UNIX Systems Administrator
    404.572.1941                                             Cox Interactive Media
    
    
    /*
     * Author: Jay Soffian <jayat_private>
     *
     * Idea: s97_cgi doesn't check ResultTemplate for a valid path, so it
     * is possible to read arbitrary files using something like
     * ResultTemplate=../../../../../../etc/passwd
     * This script decodes the input (from either a GET or a POST),
     * cleans up ResultTemplate, then execs s97_cgi
     *
     * usage: copy s97_cgi, s97r_cgi, etc to s97_cgi.orig
     * compile this program and install it as s97_cgi, s97r_cgi, etc
     * in the same directory as s97_cgi.orig
     *
     * 16 July 98
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <ctype.h>
    
    #define verity_path_pre  "/path/to/directory/with/s97_cgi"
    #define verity_path_post ".orig"
    
    int num_params = 0;
    
    typedef struct
    {
      char *name;
      char *val;
    } param;
    
    char method;
    
    #define MAX_PARAMS 1000
    #define GET 'G'
    #define POST 'P'
    
    param params[MAX_PARAMS];
    
    void die(char *logmsg, char *usermsg) {
      if (!usermsg) usermsg = "internal error";
      printf("Content-type: text/html\n\n");
      printf("<HTML><HEAD>\n"
             "<TITLE>Error</TITLE>\n"
             "</HEAD><BODY>\n"
             "<H1>Error</H1>\n"
             "Error: %s<P>\n"
             "Please try your request again.<P>\n"
             "</BODY></HTML>\n", usermsg);
      fprintf(stderr,logmsg);
      exit(0);
    }
    
    char * escape(char *s) {
      register unsigned char *a, *b;
      char *buffer;
    
      b = s;
      a = buffer = (char *)malloc((strlen(s)*3)+1);
      if (!buffer) die ("Internal error", "Out of memory while processing request");
      while (*b) {
        if (*b <= '\x20' || *b >= '\x7f' || strchr("\"#%;<>?{}|\\^~`[]&", *b)) {
          *a++ = '%';
          sprintf(a,"%0X",*b);
          a+=2;
          b++;
        } else {
          *a++ = *b++;
        }
      }
      *a = '\0';
      return buffer;
    }
    
    
    void unescape(char *s)
    {
      register unsigned char *a, *b;
      if (!*s) return;
      for ((a = b = s);(*a = *b); ++a, ++b) {
        switch (*b) {
        case '%':
          if (*(b+1) && *(b+2)) {
            *b = toupper(*b);
            b++; *a =  *b >= 'A' ? (((*b & 0xdf) - 'A') +10) : *b - '0';
            *a *= 16;
            b++; *a += *b >= 'A' ? (((*b & 0xdf) - 'A') +10) : *b - '0';
          }
          break;
        case '+':
          *a = ' ';
          break;
        }
      }
    }
    
    void cgiinit(void)
    {
      int
        content_length = 0,
        i = 0;
      char
        *query = NULL,
        *cp = NULL,
        *request_method = getenv("REQUEST_METHOD");
    
      if (!request_method) die("No REQUEST_METHOD", NULL);
    
      if (!strcmp(request_method,"POST")) {
        method = POST;
        if(getenv("CONTENT_TYPE") &&
           strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded"))
          die("CONTENT_TYPE not application/x-www-form-urlencoded",
              "CONTENT_TYPE must be 'application/x-www-form-urlencoded'.");
    
        if (getenv("CONTENT_LENGTH")) content_length = atoi(getenv("CONTENT_LENGTH"));
        else die("No CONTENT_LENGTH", NULL);
    
        query = (char *)malloc(sizeof(char) * content_length + 1);
        if (query == NULL) die ("malloc() failed",NULL);
    
        if (fread(query,sizeof(char),content_length,stdin) != content_length)
          die("Ran out of input while processing request", NULL);
    
        query[content_length] = '\0';
      } else if (!strcmp(request_method,"GET")) {
        method = GET;
        if (getenv("QUERY_STRING")) query = strdup(getenv("QUERY_STRING"));
        else die("No QUERY_STRING",NULL);
        if (!query) die ("malloc() failed",NULL);
      } else {
        die ("Method not GET nor POST", "Method must be 'GET' or 'POST'.");
      }
    
      /* input is in query. let's parse it. */
      if (strchr(query,'=')) {
        params[i].name = strtok(query, "&");
        while ((++i < MAX_PARAMS) && (params[i].name = strtok(NULL, "&"))); /* tokenize */
        num_params = i;
        for(i=0; i < num_params; i++) {
          if ((cp = strchr(params[i].name, '='))) {
            *cp = '\0';
            params[i].val = cp+1;
          } else {
            params[i].val = "";
          }
          unescape(params[i].name);
          unescape(params[i].val);
        }
      } else {
        unescape(query);
        params[0].name = "keywords";
        params[0].val = query;
        num_params = 1;
      }
    }
    
    void fixpath (register char * a)
    {
      register char *b = a;
    
      if (!*a) return;
      if (*a == '/') b++;
      while (*b)
        if (*b == '.' && *(b+1) == '.' && *(b+2) == '/') b+=3;
        else *a++ = *b++;
      *a = '\0';
    }
    
    char * makequery(void)
    {
      char * buf, *cp, *name, *val;
      int i, tot_len = 0, len, size = 1024;
      cp = buf = (char *)malloc(size);
      if (!buf) die ("malloc() failed", NULL);
      for (i=0; i<num_params; i++) {
        name = escape(params[i].name);
        val  = escape(params[i].val);
        tot_len += len = strlen(name) + strlen(val) + 2;
        if (tot_len > size) {
          size *=2;
          buf = realloc(buf, size);
          if (!buf) die ("realloc() failed", NULL);
        }
        sprintf(cp,"%s=%s&",name,val);
        cp+=len; tot_len +=len;
        free(name); free(val);
      }
      *(cp-1) = '\0';
      return buf;
    }
    
    int main (int argc, char **argv)
    {
      int size, i, fd[2], pid;
      char *query, *path, ssize[128], *buf;
    
      path = strrchr(argv[0],'/');
      if (!path) path = argv[0];
      else path++;
      buf = malloc(sizeof(verity_path_pre)  +
                   sizeof(verity_path_post) + strlen(path) + 1);
      if (!buf) die("malloc() failed", NULL);
      sprintf(buf,"%s%s%s",verity_path_pre, path, verity_path_post);
      path = buf;
    
      cgiinit();
      for (i=0; i<num_params; i++)
        if (!strcasecmp(params[i].name, "ResultTemplate"))
          fixpath(params[i].val);
      query = makequery();
      size = strlen(query);
      if (method == GET) {
        buf = (char*) malloc(sizeof("QUERY_STRING=") + size + 1);
        if (!buf) die("malloc() failed", NULL);
        sprintf(buf,"QUERY_STRING=%s",query);
        if (putenv(buf)) die ("putenv() failed", NULL);
        execv(path, argv);
        die("execv() failed", NULL);
      } else if (method == POST) {
        sprintf(ssize,"CONTENT_LENGTH=%d",size);
        if (putenv(ssize)) die("putenv() failed", NULL);
        if ( pipe(fd) ) die("pipe() failed", NULL);
        if ((pid = fork()) < 0) die("fork() failed", NULL);
        if (!pid) { /* child */
          close(fd[1]);
          dup2(fd[0],0);
          close(fd[0]);
          execv(path, argv);
          die("execv() failed", NULL);
        } else { /* parent */
          close(fd[0]);
          dup2(fd[1],1);
          close(fd[1]);
          fwrite(query,sizeof(char),size,stdout);
          exit(0);
        }
      } else {
        die ("Method not GET nor POST", "Method must be 'GET' or 'POST'.");
      }
      exit(0);
    }
    
    
    --Multipart_Thu_Jul_16_17:04:19_1998-1
    Content-Type: application/octet-stream
    Content-Disposition: attachment; filename="veritywrap.c"
    Content-Transfer-Encoding: base64
    
    LyoKICogQXV0aG9yOiBKYXkgU29mZmlhbiA8amF5QGNpbWVkaWEuY29tPgogKgogKiBJZGVh
    OiBzOTdfY2dpIGRvZXNuJ3QgY2hlY2sgUmVzdWx0VGVtcGxhdGUgZm9yIGEgdmFsaWQgcGF0
    aCwgc28gaXQKICogaXMgcG9zc2libGUgdG8gcmVhZCBhcmJpdHJhcnkgZmlsZXMgdXNpbmcg
    c29tZXRoaW5nIGxpa2UKICogUmVzdWx0VGVtcGxhdGU9Li4vLi4vLi4vLi4vLi4vLi4vZXRj
    L3Bhc3N3ZAogKiBUaGlzIHNjcmlwdCBkZWNvZGVzIHRoZSBpbnB1dCAoZnJvbSBlaXRoZXIg
    YSBHRVQgb3IgYSBQT1NUKSwKICogY2xlYW5zIHVwIFJlc3VsdFRlbXBsYXRlLCB0aGVuIGV4
    ZWNzIHM5N19jZ2kKICoKICogdXNhZ2U6IGNvcHkgczk3X2NnaSwgczk3cl9jZ2ksIGV0YyB0
    byBzOTdfY2dpLm9yaWcKICogY29tcGlsZSB0aGlzIHByb2dyYW0gYW5kIGluc3RhbGwgaXQg
    YXMgczk3X2NnaSwgczk3cl9jZ2ksIGV0YwogKiBpbiB0aGUgc2FtZSBkaXJlY3RvcnkgYXMg
    czk3X2NnaS5vcmlnCiAqCiAqIDE2IEp1bHkgOTgKICovCgojaW5jbHVkZSA8c3RkaW8uaD4K
    I2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlz
    dGQuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CgojZGVmaW5lIHZlcml0eV9wYXRoX3ByZSAgIi9w
    YXRoL3RvL2RpcmVjdG9yeS93aXRoL3M5N19jZ2kiCiNkZWZpbmUgdmVyaXR5X3BhdGhfcG9z
    dCAiLm9yaWciCgppbnQgbnVtX3BhcmFtcyA9IDA7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgY2hh
    ciAqbmFtZTsKICBjaGFyICp2YWw7Cn0gcGFyYW07CgpjaGFyIG1ldGhvZDsKCiNkZWZpbmUg
    TUFYX1BBUkFNUyAxMDAwCiNkZWZpbmUgR0VUICdHJwojZGVmaW5lIFBPU1QgJ1AnCgpwYXJh
    bSBwYXJhbXNbTUFYX1BBUkFNU107Cgp2b2lkIGRpZShjaGFyICpsb2dtc2csIGNoYXIgKnVz
    ZXJtc2cpIHsKICBpZiAoIXVzZXJtc2cpIHVzZXJtc2cgPSAiaW50ZXJuYWwgZXJyb3IiOwog
    IHByaW50ZigiQ29udGVudC10eXBlOiB0ZXh0L2h0bWxcblxuIik7CiAgcHJpbnRmKCI8SFRN
    TD48SEVBRD5cbiIKCSAiPFRJVExFPkVycm9yPC9USVRMRT5cbiIKCSAiPC9IRUFEPjxCT0RZ
    PlxuIgoJICI8SDE+RXJyb3I8L0gxPlxuIgoJICJFcnJvcjogJXM8UD5cbiIKCSAiUGxlYXNl
    IHRyeSB5b3VyIHJlcXVlc3QgYWdhaW4uPFA+XG4iCgkgIjwvQk9EWT48L0hUTUw+XG4iLCB1
    c2VybXNnKTsKICBmcHJpbnRmKHN0ZGVycixsb2dtc2cpOwogIGV4aXQoMCk7Cn0KCmNoYXIg
    KiBlc2NhcGUoY2hhciAqcykgewogIHJlZ2lzdGVyIHVuc2lnbmVkIGNoYXIgKmEsICpiOwog
    IGNoYXIgKmJ1ZmZlcjsKICAKICBiID0gczsKICBhID0gYnVmZmVyID0gKGNoYXIgKiltYWxs
    b2MoKHN0cmxlbihzKSozKSsxKTsKICBpZiAoIWJ1ZmZlcikgZGllICgiSW50ZXJuYWwgZXJy
    b3IiLCAiT3V0IG9mIG1lbW9yeSB3aGlsZSBwcm9jZXNzaW5nIHJlcXVlc3QiKTsKICB3aGls
    ZSAoKmIpIHsKICAgIGlmICgqYiA8PSAnXHgyMCcgfHwgKmIgPj0gJ1x4N2YnIHx8IHN0cmNo
    cigiXCIjJTs8Pj97fXxcXF5+YFtdJiIsICpiKSkgewogICAgICAqYSsrID0gJyUnOwogICAg
    ICBzcHJpbnRmKGEsIiUwWCIsKmIpOwogICAgICBhKz0yOwogICAgICBiKys7CiAgICB9IGVs
    c2UgewogICAgICAqYSsrID0gKmIrKzsKICAgIH0KICB9CiAgKmEgPSAnXDAnOwogIHJldHVy
    biBidWZmZXI7Cn0KCgp2b2lkIHVuZXNjYXBlKGNoYXIgKnMpCnsKICByZWdpc3RlciB1bnNp
    Z25lZCBjaGFyICphLCAqYjsKICBpZiAoISpzKSByZXR1cm47CiAgZm9yICgoYSA9IGIgPSBz
    KTsoKmEgPSAqYik7ICsrYSwgKytiKSB7CiAgICBzd2l0Y2ggKCpiKSB7CiAgICBjYXNlICcl
    JzogCiAgICAgIGlmICgqKGIrMSkgJiYgKihiKzIpKSB7CgkqYiA9IHRvdXBwZXIoKmIpOwoJ
    YisrOyAqYSA9ICAqYiA+PSAnQScgPyAoKCgqYiAmIDB4ZGYpIC0gJ0EnKSArMTApIDogKmIg
    LSAnMCc7CgkqYSAqPSAxNjsgIAoJYisrOyAqYSArPSAqYiA+PSAnQScgPyAoKCgqYiAmIDB4
    ZGYpIC0gJ0EnKSArMTApIDogKmIgLSAnMCc7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBj
    YXNlICcrJzoKICAgICAgKmEgPSAnICc7CiAgICAgIGJyZWFrOwogICAgfQogIH0KfQoKdm9p
    ZCBjZ2lpbml0KHZvaWQpCnsKICBpbnQgCiAgICBjb250ZW50X2xlbmd0aCA9IDAsIAogICAg
    aSA9IDA7CiAgY2hhciAKICAgICpxdWVyeSA9IE5VTEwsIAogICAgKmNwID0gTlVMTCwgCiAg
    ICAqcmVxdWVzdF9tZXRob2QgPSBnZXRlbnYoIlJFUVVFU1RfTUVUSE9EIik7CiAgCiAgaWYg
    KCFyZXF1ZXN0X21ldGhvZCkgZGllKCJObyBSRVFVRVNUX01FVEhPRCIsIE5VTEwpOwoKICBp
    ZiAoIXN0cmNtcChyZXF1ZXN0X21ldGhvZCwiUE9TVCIpKSB7CiAgICBtZXRob2QgPSBQT1NU
    OwogICAgaWYoZ2V0ZW52KCJDT05URU5UX1RZUEUiKSAmJiAKICAgICAgIHN0cmNtcChnZXRl
    bnYoIkNPTlRFTlRfVFlQRSIpLCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQi
    KSkgCiAgICAgIGRpZSgiQ09OVEVOVF9UWVBFIG5vdCBhcHBsaWNhdGlvbi94LXd3dy1mb3Jt
    LXVybGVuY29kZWQiLAoJICAiQ09OVEVOVF9UWVBFIG11c3QgYmUgJ2FwcGxpY2F0aW9uL3gt
    d3d3LWZvcm0tdXJsZW5jb2RlZCcuIik7CiAgICAKICAgIGlmIChnZXRlbnYoIkNPTlRFTlRf
    TEVOR1RIIikpIGNvbnRlbnRfbGVuZ3RoID0gYXRvaShnZXRlbnYoIkNPTlRFTlRfTEVOR1RI
    IikpOwogICAgZWxzZSBkaWUoIk5vIENPTlRFTlRfTEVOR1RIIiwgTlVMTCk7CgkKICAgIHF1
    ZXJ5ID0gKGNoYXIgKiltYWxsb2Moc2l6ZW9mKGNoYXIpICogY29udGVudF9sZW5ndGggKyAx
    KTsKICAgIGlmIChxdWVyeSA9PSBOVUxMKSBkaWUgKCJtYWxsb2MoKSBmYWlsZWQiLE5VTEwp
    OwogICAgICAKICAgIGlmIChmcmVhZChxdWVyeSxzaXplb2YoY2hhciksY29udGVudF9sZW5n
    dGgsc3RkaW4pICE9IGNvbnRlbnRfbGVuZ3RoKQogICAgICBkaWUoIlJhbiBvdXQgb2YgaW5w
    dXQgd2hpbGUgcHJvY2Vzc2luZyByZXF1ZXN0IiwgTlVMTCk7CgkgIAogICAgcXVlcnlbY29u
    dGVudF9sZW5ndGhdID0gJ1wwJzsKICB9IGVsc2UgaWYgKCFzdHJjbXAocmVxdWVzdF9tZXRo
    b2QsIkdFVCIpKSB7CiAgICBtZXRob2QgPSBHRVQ7CiAgICBpZiAoZ2V0ZW52KCJRVUVSWV9T
    VFJJTkciKSkgcXVlcnkgPSBzdHJkdXAoZ2V0ZW52KCJRVUVSWV9TVFJJTkciKSk7CiAgICBl
    bHNlIGRpZSgiTm8gUVVFUllfU1RSSU5HIixOVUxMKTsKICAgIGlmICghcXVlcnkpIGRpZSAo
    Im1hbGxvYygpIGZhaWxlZCIsTlVMTCk7CiAgfSBlbHNlIHsKICAgIGRpZSAoIk1ldGhvZCBu
    b3QgR0VUIG5vciBQT1NUIiwgIk1ldGhvZCBtdXN0IGJlICdHRVQnIG9yICdQT1NUJy4iKTsK
    ICB9CgogIC8qIGlucHV0IGlzIGluIHF1ZXJ5LiBsZXQncyBwYXJzZSBpdC4gKi8KICBpZiAo
    c3RyY2hyKHF1ZXJ5LCc9JykpIHsKICAgIHBhcmFtc1tpXS5uYW1lID0gc3RydG9rKHF1ZXJ5
    LCAiJiIpOwogICAgd2hpbGUgKCgrK2kgPCBNQVhfUEFSQU1TKSAmJiAocGFyYW1zW2ldLm5h
    bWUgPSBzdHJ0b2soTlVMTCwgIiYiKSkpOyAvKiB0b2tlbml6ZSAqLwogICAgbnVtX3BhcmFt
    cyA9IGk7CiAgICBmb3IoaT0wOyBpIDwgbnVtX3BhcmFtczsgaSsrKSB7CiAgICAgIGlmICgo
    Y3AgPSBzdHJjaHIocGFyYW1zW2ldLm5hbWUsICc9JykpKSB7CgkqY3AgPSAnXDAnOwoJcGFy
    YW1zW2ldLnZhbCA9IGNwKzE7CiAgICAgIH0gZWxzZSB7CglwYXJhbXNbaV0udmFsID0gIiI7
    CiAgICAgIH0KICAgICAgdW5lc2NhcGUocGFyYW1zW2ldLm5hbWUpOwogICAgICB1bmVzY2Fw
    ZShwYXJhbXNbaV0udmFsKTsKICAgIH0KICB9IGVsc2UgewogICAgdW5lc2NhcGUocXVlcnkp
    OwogICAgcGFyYW1zWzBdLm5hbWUgPSAia2V5d29yZHMiOwogICAgcGFyYW1zWzBdLnZhbCA9
    IHF1ZXJ5OwogICAgbnVtX3BhcmFtcyA9IDE7CiAgfQp9Cgp2b2lkIGZpeHBhdGggKHJlZ2lz
    dGVyIGNoYXIgKiBhKSAKewogIHJlZ2lzdGVyIGNoYXIgKmIgPSBhOwoKICBpZiAoISphKSBy
    ZXR1cm47CiAgaWYgKCphID09ICcvJykgYisrOwogIHdoaWxlICgqYikgCiAgICBpZiAoKmIg
    PT0gJy4nICYmICooYisxKSA9PSAnLicgJiYgKihiKzIpID09ICcvJykgYis9MzsKICAgIGVs
    c2UgKmErKyA9ICpiKys7CiAgKmEgPSAnXDAnOwp9CgpjaGFyICogbWFrZXF1ZXJ5KHZvaWQp
    IAp7CiAgY2hhciAqIGJ1ZiwgKmNwLCAqbmFtZSwgKnZhbDsKICBpbnQgaSwgdG90X2xlbiA9
    IDAsIGxlbiwgc2l6ZSA9IDEwMjQ7CiAgY3AgPSBidWYgPSAoY2hhciAqKW1hbGxvYyhzaXpl
    KTsKICBpZiAoIWJ1ZikgZGllICgibWFsbG9jKCkgZmFpbGVkIiwgTlVMTCk7CiAgZm9yIChp
    PTA7IGk8bnVtX3BhcmFtczsgaSsrKSB7CiAgICBuYW1lID0gZXNjYXBlKHBhcmFtc1tpXS5u
    YW1lKTsKICAgIHZhbCAgPSBlc2NhcGUocGFyYW1zW2ldLnZhbCk7IAogICAgdG90X2xlbiAr
    PSBsZW4gPSBzdHJsZW4obmFtZSkgKyBzdHJsZW4odmFsKSArIDI7CiAgICBpZiAodG90X2xl
    biA+IHNpemUpIHsKICAgICAgc2l6ZSAqPTI7CiAgICAgIGJ1ZiA9IHJlYWxsb2MoYnVmLCBz
    aXplKTsKICAgICAgaWYgKCFidWYpIGRpZSAoInJlYWxsb2MoKSBmYWlsZWQiLCBOVUxMKTsK
    ICAgIH0KICAgIHNwcmludGYoY3AsIiVzPSVzJiIsbmFtZSx2YWwpOwogICAgY3ArPWxlbjsg
    dG90X2xlbiArPWxlbjsKICAgIGZyZWUobmFtZSk7IGZyZWUodmFsKTsKICB9CiAgKihjcC0x
    KSA9ICdcMCc7CiAgcmV0dXJuIGJ1ZjsKfQoKaW50IG1haW4gKGludCBhcmdjLCBjaGFyICoq
    YXJndikKewogIGludCBzaXplLCBpLCBmZFsyXSwgcGlkOwogIGNoYXIgKnF1ZXJ5LCAqcGF0
    aCwgc3NpemVbMTI4XSwgKmJ1ZjsKCiAgcGF0aCA9IHN0cnJjaHIoYXJndlswXSwnLycpOwog
    IGlmICghcGF0aCkgcGF0aCA9IGFyZ3ZbMF07CiAgZWxzZSBwYXRoKys7CiAgYnVmID0gbWFs
    bG9jKHNpemVvZih2ZXJpdHlfcGF0aF9wcmUpICArIAoJICAgICAgIHNpemVvZih2ZXJpdHlf
    cGF0aF9wb3N0KSArIHN0cmxlbihwYXRoKSArIDEpOwogIGlmICghYnVmKSBkaWUoIm1hbGxv
    YygpIGZhaWxlZCIsIE5VTEwpOwogIHNwcmludGYoYnVmLCIlcyVzJXMiLHZlcml0eV9wYXRo
    X3ByZSwgcGF0aCwgdmVyaXR5X3BhdGhfcG9zdCk7CiAgcGF0aCA9IGJ1ZjsKCiAgY2dpaW5p
    dCgpOwogIGZvciAoaT0wOyBpPG51bV9wYXJhbXM7IGkrKykgCiAgICBpZiAoIXN0cmNhc2Vj
    bXAocGFyYW1zW2ldLm5hbWUsICJSZXN1bHRUZW1wbGF0ZSIpKSAKICAgICAgZml4cGF0aChw
    YXJhbXNbaV0udmFsKTsKICBxdWVyeSA9IG1ha2VxdWVyeSgpOwogIHNpemUgPSBzdHJsZW4o
    cXVlcnkpOwogIGlmIChtZXRob2QgPT0gR0VUKSB7CiAgICBidWYgPSAoY2hhciopIG1hbGxv
    YyhzaXplb2YoIlFVRVJZX1NUUklORz0iKSArIHNpemUgKyAxKTsKICAgIGlmICghYnVmKSBk
    aWUoIm1hbGxvYygpIGZhaWxlZCIsIE5VTEwpOwogICAgc3ByaW50ZihidWYsIlFVRVJZX1NU
    UklORz0lcyIscXVlcnkpOwogICAgaWYgKHB1dGVudihidWYpKSBkaWUgKCJwdXRlbnYoKSBm
    YWlsZWQiLCBOVUxMKTsKICAgIGV4ZWN2KHBhdGgsIGFyZ3YpOwogICAgZGllKCJleGVjdigp
    IGZhaWxlZCIsIE5VTEwpOwogIH0gZWxzZSBpZiAobWV0aG9kID09IFBPU1QpIHsKICAgIHNw
    cmludGYoc3NpemUsIkNPTlRFTlRfTEVOR1RIPSVkIixzaXplKTsKICAgIGlmIChwdXRlbnYo
    c3NpemUpKSBkaWUoInB1dGVudigpIGZhaWxlZCIsIE5VTEwpOwogICAgaWYgKCBwaXBlKGZk
    KSApIGRpZSgicGlwZSgpIGZhaWxlZCIsIE5VTEwpOwogICAgaWYgKChwaWQgPSBmb3JrKCkp
    IDwgMCkgZGllKCJmb3JrKCkgZmFpbGVkIiwgTlVMTCk7CiAgICBpZiAoIXBpZCkgeyAvKiBj
    aGlsZCAqLwogICAgICBjbG9zZShmZFsxXSk7CiAgICAgIGR1cDIoZmRbMF0sMCk7CiAgICAg
    IGNsb3NlKGZkWzBdKTsKICAgICAgZXhlY3YocGF0aCwgYXJndik7CiAgICAgIGRpZSgiZXhl
    Y3YoKSBmYWlsZWQiLCBOVUxMKTsKICAgIH0gZWxzZSB7IC8qIHBhcmVudCAqLwogICAgICBj
    bG9zZShmZFswXSk7CiAgICAgIGR1cDIoZmRbMV0sMSk7CiAgICAgIGNsb3NlKGZkWzFdKTsK
    ICAgICAgZndyaXRlKHF1ZXJ5LHNpemVvZihjaGFyKSxzaXplLHN0ZG91dCk7CiAgICAgIGV4
    aXQoMCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGRpZSAoIk1ldGhvZCBub3QgR0VUIG5vciBQ
    T1NUIiwgIk1ldGhvZCBtdXN0IGJlICdHRVQnIG9yICdQT1NUJy4iKTsKICB9CiAgZXhpdCgw
    KTsKfQo=
    
    --Multipart_Thu_Jul_16_17:04:19_1998-1--
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:05:26 PDT