Bugtraq mailing list archives

Re: Verity/Search'97 Security Problems


From: jay () CIMEDIA COM (Jay Soffian)
Date: Thu, 16 Jul 1998 17:04:19 -0400


--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 <jay () cimedia com>                       UNIX Systems Administrator
404.572.1941                                             Cox Interactive Media


/*
 * Author: Jay Soffian <jay () cimedia com>
 *
 * 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--



Current thread: