OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
Bugtraq archives for 3rd quarter (Jul-Sep) 1998: Verity/Search'97 Security Problems

Verity/Search'97 Security Problems

Jay Soffian (jayCIMEDIA.COM)
Fri, 17 Jul 1998 01:03:47 -0400

--Multipart_Fri_Jul_17_01:03:47_1998-1
Content-Type: text/plain; charset=US-ASCII


Sorry about the extra traffic. I probably fired off the veritywrap.c
sooner than I should have. There was a bug or two in it that I've
squashed. This is the last version I'll send. We spoke with Verity
today and they are supposed to have patched binaries out RSN.

j.
--
Jay Soffian <jaycimedia.com>                       UNIX Systems Administrator
404.572.1941                                             Cox Interactive Media

/*
 * Author: Jay Soffian <jaycimedia.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
 *
 * History: o fixed bug with cp not being correct after realloc in
 *            makequery()
 *          o fixed handling of isindex queries
 *
 * 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
 * DON"T FORGET TO RESTRICT ACCESS TO THE *.orig BINARIES, OR THIS
 * WRAPPER DOESN"T DO MUCH GOOD. Use <Files> (apache) or equiv.
 *
 * 16 July 98
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>

#define verity_path_pre  "/path/to/dir/with/verity/s97_cgi/" /* notice trailing slash */
#define verity_path_post ".orig"

int num_params = 0;

typedef struct
{
  char *name;
  char *val;
} param;
char * keywords = NULL;

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 ("malloc() failed", NULL);
  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,'=')) { /* name = value pairs */
    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 { /* isindex */
    unescape(query);
    keywords = query;
  }
}

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, offset,  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) {
      while (tot_len > size) size *=2;
      offset = cp - buf;
      buf = realloc(buf, size);
      if (!buf) die ("realloc() failed", NULL);
      cp = buf + offset;
    }
    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);
  if (num_params) query = makequery();
  else query = escape(keywords);
  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_Fri_Jul_17_01:03:47_1998-1
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="veritywrap.c"
Content-Transfer-Encoding: base64

LyoKICogQXV0aG9yOiBKYXkgU29mZmlhbiA8amF5QGNpbWVkaWEuY29tPgogKgogKiBJZGVh
OiBzOTdfY2dpIGRvZXNuJ3QgY2hlY2sgUmVzdWx0VGVtcGxhdGUgZm9yIGEgdmFsaWQgcGF0
aCwgc28gaXQKICogaXMgcG9zc2libGUgdG8gcmVhZCBhcmJpdHJhcnkgZmlsZXMgdXNpbmcg
c29tZXRoaW5nIGxpa2UKICogUmVzdWx0VGVtcGxhdGU9Li4vLi4vLi4vLi4vLi4vLi4vZXRj
L3Bhc3N3ZAogKiBUaGlzIHNjcmlwdCBkZWNvZGVzIHRoZSBpbnB1dCAoZnJvbSBlaXRoZXIg
YSBHRVQgb3IgYSBQT1NUKSwKICogY2xlYW5zIHVwIFJlc3VsdFRlbXBsYXRlLCB0aGVuIGV4
ZWNzIHM5N19jZ2kKICoKICogSGlzdG9yeTogbyBmaXhlZCBidWcgd2l0aCBjcCBub3QgYmVp
bmcgY29ycmVjdCBhZnRlciByZWFsbG9jIGluCiAqICAgICAgICAgICAgbWFrZXF1ZXJ5KCkK
ICogICAgICAgICAgbyBmaXhlZCBoYW5kbGluZyBvZiBpc2luZGV4IHF1ZXJpZXMKICoKICog
dXNhZ2U6IGNvcHkgczk3X2NnaSwgczk3cl9jZ2ksIGV0YyB0byBzOTdfY2dpLm9yaWcKICog
Y29tcGlsZSB0aGlzIHByb2dyYW0gYW5kIGluc3RhbGwgaXQgYXMgczk3X2NnaSwgczk3cl9j
Z2ksIGV0YwogKiBpbiB0aGUgc2FtZSBkaXJlY3RvcnkgYXMgczk3X2NnaS5vcmlnCiAqIERP
TiJUIEZPUkdFVCBUTyBSRVNUUklDVCBBQ0NFU1MgVE8gVEhFICoub3JpZyBCSU5BUklFUywg
T1IgVEhJUwogKiBXUkFQUEVSIERPRVNOIlQgRE8gTVVDSCBHT09ELiBVc2UgPEZpbGVzPiAo
YXBhY2hlKSBvciBlcXVpdi4KICoKICogMTYgSnVseSA5OAogKi8KCiNpbmNsdWRlIDxzdGRp
by5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUg
PHVuaXN0ZC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCiNkZWZpbmUgdmVyaXR5X3BhdGhfcHJl
ICAiL3BhdGgvdG8vZGlyL3dpdGgvdmVyaXR5L3M5N19jZ2kvIiAvKiBub3RpY2UgdHJhaWxp
bmcgc2xhc2ggKi8KI2RlZmluZSB2ZXJpdHlfcGF0aF9wb3N0ICIub3JpZyIKCmludCBudW1f
cGFyYW1zID0gMDsKCnR5cGVkZWYgc3RydWN0CnsKICBjaGFyICpuYW1lOwogIGNoYXIgKnZh
bDsKfSBwYXJhbTsKY2hhciAqIGtleXdvcmRzID0gTlVMTDsKCmNoYXIgbWV0aG9kOwoKI2Rl
ZmluZSBNQVhfUEFSQU1TIDEwMDAKI2RlZmluZSBHRVQgJ0cnCiNkZWZpbmUgUE9TVCAnUCcK
CnBhcmFtIHBhcmFtc1tNQVhfUEFSQU1TXTsKCnZvaWQgZGllKGNoYXIgKmxvZ21zZywgY2hh
ciAqdXNlcm1zZykgewogIGlmICghdXNlcm1zZykgdXNlcm1zZyA9ICJpbnRlcm5hbCBlcnJv
ciI7CiAgcHJpbnRmKCJDb250ZW50LXR5cGU6IHRleHQvaHRtbFxuXG4iKTsKICBwcmludGYo
IjxIVE1MPjxIRUFEPlxuIgoJICI8VElUTEU+RXJyb3I8L1RJVExFPlxuIgoJICI8L0hFQUQ+
PEJPRFk+XG4iCgkgIjxIMT5FcnJvcjwvSDE+XG4iCgkgIkVycm9yOiAlczxQPlxuIgoJICJQ
bGVhc2UgdHJ5IHlvdXIgcmVxdWVzdCBhZ2Fpbi48UD5cbiIKCSAiPC9CT0RZPjwvSFRNTD5c
biIsIHVzZXJtc2cpOwogIGZwcmludGYoc3RkZXJyLGxvZ21zZyk7CiAgZXhpdCgwKTsKfQoK
Y2hhciAqIGVzY2FwZShjaGFyICpzKSB7CiAgcmVnaXN0ZXIgdW5zaWduZWQgY2hhciAqYSwg
KmI7CiAgY2hhciAqYnVmZmVyOwogIAogIGIgPSBzOwogIGEgPSBidWZmZXIgPSAoY2hhciAq
KW1hbGxvYygoc3RybGVuKHMpKjMpKzEpOwogIGlmICghYnVmZmVyKSBkaWUgKCJtYWxsb2Mo
KSBmYWlsZWQiLCBOVUxMKTsKICB3aGlsZSAoKmIpIHsKICAgIGlmICgqYiA8PSAnXHgyMCcg
fHwgKmIgPj0gJ1x4N2YnIHx8IHN0cmNocigiXCIjJTs8Pj97fXxcXF5+YFtdJiIsICpiKSkg
ewogICAgICAqYSsrID0gJyUnOwogICAgICBzcHJpbnRmKGEsIiUwWCIsKmIpOwogICAgICBh
Kz0yOwogICAgICBiKys7CiAgICB9IGVsc2UgewogICAgICAqYSsrID0gKmIrKzsKICAgIH0K
ICB9CiAgKmEgPSAnXDAnOwogIHJldHVybiBidWZmZXI7Cn0KCgp2b2lkIHVuZXNjYXBlKGNo
YXIgKnMpCnsKICByZWdpc3RlciB1bnNpZ25lZCBjaGFyICphLCAqYjsKICBpZiAoISpzKSBy
ZXR1cm47CiAgZm9yICgoYSA9IGIgPSBzKTsoKmEgPSAqYik7ICsrYSwgKytiKSB7CiAgICBz
d2l0Y2ggKCpiKSB7CiAgICBjYXNlICclJzogCiAgICAgIGlmICgqKGIrMSkgJiYgKihiKzIp
KSB7CgkqYiA9IHRvdXBwZXIoKmIpOwoJYisrOyAqYSA9ICAqYiA+PSAnQScgPyAoKCgqYiAm
IDB4ZGYpIC0gJ0EnKSArMTApIDogKmIgLSAnMCc7CgkqYSAqPSAxNjsgIAoJYisrOyAqYSAr
PSAqYiA+PSAnQScgPyAoKCgqYiAmIDB4ZGYpIC0gJ0EnKSArMTApIDogKmIgLSAnMCc7CiAg
ICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlICcrJzoKICAgICAgKmEgPSAnICc7CiAgICAg
IGJyZWFrOwogICAgfQogIH0KfQoKdm9pZCBjZ2lpbml0KHZvaWQpCnsKICBpbnQgCiAgICBj
b250ZW50X2xlbmd0aCA9IDAsIAogICAgaSA9IDA7CiAgY2hhciAKICAgICpxdWVyeSA9IE5V
TEwsIAogICAgKmNwID0gTlVMTCwgCiAgICAqcmVxdWVzdF9tZXRob2QgPSBnZXRlbnYoIlJF
UVVFU1RfTUVUSE9EIik7CiAgCiAgaWYgKCFyZXF1ZXN0X21ldGhvZCkgZGllKCJObyBSRVFV
RVNUX01FVEhPRCIsIE5VTEwpOwoKICBpZiAoIXN0cmNtcChyZXF1ZXN0X21ldGhvZCwiUE9T
VCIpKSB7CiAgICBtZXRob2QgPSBQT1NUOwogICAgaWYoZ2V0ZW52KCJDT05URU5UX1RZUEUi
KSAmJiAKICAgICAgIHN0cmNtcChnZXRlbnYoIkNPTlRFTlRfVFlQRSIpLCJhcHBsaWNhdGlv
bi94LXd3dy1mb3JtLXVybGVuY29kZWQiKSkgCiAgICAgIGRpZSgiQ09OVEVOVF9UWVBFIG5v
dCBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiLAoJICAiQ09OVEVOVF9UWVBF
IG11c3QgYmUgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcuIik7CiAgICAK
ICAgIGlmIChnZXRlbnYoIkNPTlRFTlRfTEVOR1RIIikpIGNvbnRlbnRfbGVuZ3RoID0gYXRv
aShnZXRlbnYoIkNPTlRFTlRfTEVOR1RIIikpOwogICAgZWxzZSBkaWUoIk5vIENPTlRFTlRf
TEVOR1RIIiwgTlVMTCk7CgkKICAgIHF1ZXJ5ID0gKGNoYXIgKiltYWxsb2Moc2l6ZW9mKGNo
YXIpICogY29udGVudF9sZW5ndGggKyAxKTsKICAgIGlmIChxdWVyeSA9PSBOVUxMKSBkaWUg
KCJtYWxsb2MoKSBmYWlsZWQiLE5VTEwpOwogICAgICAKICAgIGlmIChmcmVhZChxdWVyeSxz
aXplb2YoY2hhciksY29udGVudF9sZW5ndGgsc3RkaW4pICE9IGNvbnRlbnRfbGVuZ3RoKQog
ICAgICBkaWUoIlJhbiBvdXQgb2YgaW5wdXQgd2hpbGUgcHJvY2Vzc2luZyByZXF1ZXN0Iiwg
TlVMTCk7CgkgIAogICAgcXVlcnlbY29udGVudF9sZW5ndGhdID0gJ1wwJzsKICB9IGVsc2Ug
aWYgKCFzdHJjbXAocmVxdWVzdF9tZXRob2QsIkdFVCIpKSB7CiAgICBtZXRob2QgPSBHRVQ7
CiAgICBpZiAoZ2V0ZW52KCJRVUVSWV9TVFJJTkciKSkgcXVlcnkgPSBzdHJkdXAoZ2V0ZW52
KCJRVUVSWV9TVFJJTkciKSk7CiAgICBlbHNlIGRpZSgiTm8gUVVFUllfU1RSSU5HIixOVUxM
KTsKICAgIGlmICghcXVlcnkpIGRpZSAoIm1hbGxvYygpIGZhaWxlZCIsTlVMTCk7CiAgfSBl
bHNlIHsKICAgIGRpZSAoIk1ldGhvZCBub3QgR0VUIG5vciBQT1NUIiwgIk1ldGhvZCBtdXN0
IGJlICdHRVQnIG9yICdQT1NUJy4iKTsKICB9CgogIC8qIGlucHV0IGlzIGluIHF1ZXJ5LiBs
ZXQncyBwYXJzZSBpdC4gKi8KICBpZiAoc3RyY2hyKHF1ZXJ5LCc9JykpIHsgLyogbmFtZSA9
IHZhbHVlIHBhaXJzICovCiAgICBwYXJhbXNbaV0ubmFtZSA9IHN0cnRvayhxdWVyeSwgIiYi
KTsKICAgIHdoaWxlICgoKytpIDwgTUFYX1BBUkFNUykgJiYgKHBhcmFtc1tpXS5uYW1lID0g
c3RydG9rKE5VTEwsICImIikpKTsgLyogdG9rZW5pemUgKi8KICAgIG51bV9wYXJhbXMgPSBp
OwogICAgZm9yKGk9MDsgaSA8IG51bV9wYXJhbXM7IGkrKykgewogICAgICBpZiAoKGNwID0g
c3RyY2hyKHBhcmFtc1tpXS5uYW1lLCAnPScpKSkgewoJKmNwID0gJ1wwJzsKCXBhcmFtc1tp
XS52YWwgPSBjcCsxOwogICAgICB9IGVsc2UgewoJcGFyYW1zW2ldLnZhbCA9ICIiOwogICAg
ICB9CiAgICAgIHVuZXNjYXBlKHBhcmFtc1tpXS5uYW1lKTsKICAgICAgdW5lc2NhcGUocGFy
YW1zW2ldLnZhbCk7CiAgICB9CiAgfSBlbHNlIHsgLyogaXNpbmRleCAqLwogICAgdW5lc2Nh
cGUocXVlcnkpOwogICAga2V5d29yZHMgPSBxdWVyeTsKICB9Cn0KCnZvaWQgZml4cGF0aCAo
cmVnaXN0ZXIgY2hhciAqIGEpIAp7CiAgcmVnaXN0ZXIgY2hhciAqYiA9IGE7CgogIGlmICgh
KmEpIHJldHVybjsKICBpZiAoKmEgPT0gJy8nKSBiKys7CiAgd2hpbGUgKCpiKSAKICAgIGlm
ICgqYiA9PSAnLicgJiYgKihiKzEpID09ICcuJyAmJiAqKGIrMikgPT0gJy8nKSBiKz0zOwog
ICAgZWxzZSAqYSsrID0gKmIrKzsKICAqYSA9ICdcMCc7Cn0KCmNoYXIgKiBtYWtlcXVlcnko
dm9pZCkgCnsKICBjaGFyICogYnVmLCAqY3AsICpuYW1lLCAqdmFsOwogIGludCBpLCBvZmZz
ZXQsICB0b3RfbGVuID0gMCwgbGVuLCBzaXplID0gMTAyNDsKICBjcCA9IGJ1ZiA9IChjaGFy
ICopbWFsbG9jKHNpemUpOwogIGlmICghYnVmKSBkaWUgKCJtYWxsb2MoKSBmYWlsZWQiLCBO
VUxMKTsKICBmb3IgKGk9MDsgaTxudW1fcGFyYW1zOyBpKyspIHsKICAgIG5hbWUgPSBlc2Nh
cGUocGFyYW1zW2ldLm5hbWUpOwogICAgdmFsICA9IGVzY2FwZShwYXJhbXNbaV0udmFsKTsg
CiAgICB0b3RfbGVuICs9IGxlbiA9IHN0cmxlbihuYW1lKSArIHN0cmxlbih2YWwpICsgMjsK
ICAgIGlmICh0b3RfbGVuID4gc2l6ZSkgewogICAgICB3aGlsZSAodG90X2xlbiA+IHNpemUp
IHNpemUgKj0yOwogICAgICBvZmZzZXQgPSBjcCAtIGJ1ZjsKICAgICAgYnVmID0gcmVhbGxv
YyhidWYsIHNpemUpOwogICAgICBpZiAoIWJ1ZikgZGllICgicmVhbGxvYygpIGZhaWxlZCIs
IE5VTEwpOwogICAgICBjcCA9IGJ1ZiArIG9mZnNldDsKICAgIH0KICAgIHNwcmludGYoY3As
IiVzPSVzJiIsbmFtZSx2YWwpOwogICAgY3ArPWxlbjsgdG90X2xlbiArPWxlbjsKICAgIGZy
ZWUobmFtZSk7IGZyZWUodmFsKTsKICB9CiAgKihjcC0xKSA9ICdcMCc7CiAgcmV0dXJuIGJ1
ZjsKfQoKaW50IG1haW4gKGludCBhcmdjLCBjaGFyICoqYXJndikKewogIGludCBzaXplLCBp
LCBmZFsyXSwgcGlkOwogIGNoYXIgKnF1ZXJ5LCAqcGF0aCwgc3NpemVbMTI4XSwgKmJ1ZjsK
CiAgcGF0aCA9IHN0cnJjaHIoYXJndlswXSwnLycpOwogIGlmICghcGF0aCkgcGF0aCA9IGFy
Z3ZbMF07CiAgZWxzZSBwYXRoKys7CiAgYnVmID0gbWFsbG9jKHNpemVvZih2ZXJpdHlfcGF0
aF9wcmUpICArIAoJICAgICAgIHNpemVvZih2ZXJpdHlfcGF0aF9wb3N0KSArIHN0cmxlbihw
YXRoKSArIDEpOwogIGlmICghYnVmKSBkaWUoIm1hbGxvYygpIGZhaWxlZCIsIE5VTEwpOwog
IHNwcmludGYoYnVmLCIlcyVzJXMiLHZlcml0eV9wYXRoX3ByZSwgcGF0aCwgdmVyaXR5X3Bh
dGhfcG9zdCk7CiAgcGF0aCA9IGJ1ZjsKCiAgY2dpaW5pdCgpOwogIGZvciAoaT0wOyBpPG51
bV9wYXJhbXM7IGkrKykgCiAgICBpZiAoIXN0cmNhc2VjbXAocGFyYW1zW2ldLm5hbWUsICJS
ZXN1bHRUZW1wbGF0ZSIpKSAKICAgICAgZml4cGF0aChwYXJhbXNbaV0udmFsKTsKICBpZiAo
bnVtX3BhcmFtcykgcXVlcnkgPSBtYWtlcXVlcnkoKTsKICBlbHNlIHF1ZXJ5ID0gZXNjYXBl
KGtleXdvcmRzKTsKICBzaXplID0gc3RybGVuKHF1ZXJ5KTsKICBpZiAobWV0aG9kID09IEdF
VCkgewogICAgYnVmID0gKGNoYXIqKSBtYWxsb2Moc2l6ZW9mKCJRVUVSWV9TVFJJTkc9Iikg
KyBzaXplICsgMSk7CiAgICBpZiAoIWJ1ZikgZGllKCJtYWxsb2MoKSBmYWlsZWQiLCBOVUxM
KTsKICAgIHNwcmludGYoYnVmLCJRVUVSWV9TVFJJTkc9JXMiLHF1ZXJ5KTsKICAgIGlmIChw
dXRlbnYoYnVmKSkgZGllICgicHV0ZW52KCkgZmFpbGVkIiwgTlVMTCk7CiAgICBleGVjdihw
YXRoLCBhcmd2KTsKICAgIGRpZSgiZXhlY3YoKSBmYWlsZWQiLCBOVUxMKTsKICB9IGVsc2Ug
aWYgKG1ldGhvZCA9PSBQT1NUKSB7CiAgICBzcHJpbnRmKHNzaXplLCJDT05URU5UX0xFTkdU
SD0lZCIsc2l6ZSk7CiAgICBpZiAocHV0ZW52KHNzaXplKSkgZGllKCJwdXRlbnYoKSBmYWls
ZWQiLCBOVUxMKTsKICAgIGlmICggcGlwZShmZCkgKSBkaWUoInBpcGUoKSBmYWlsZWQiLCBO
VUxMKTsKICAgIGlmICgocGlkID0gZm9yaygpKSA8IDApIGRpZSgiZm9yaygpIGZhaWxlZCIs
IE5VTEwpOwogICAgaWYgKCFwaWQpIHsgLyogY2hpbGQgKi8KICAgICAgY2xvc2UoZmRbMV0p
OwogICAgICBkdXAyKGZkWzBdLDApOwogICAgICBjbG9zZShmZFswXSk7CiAgICAgIGV4ZWN2
KHBhdGgsIGFyZ3YpOwogICAgICBkaWUoImV4ZWN2KCkgZmFpbGVkIiwgTlVMTCk7CiAgICB9
IGVsc2UgeyAvKiBwYXJlbnQgKi8KICAgICAgY2xvc2UoZmRbMF0pOwogICAgICBkdXAyKGZk
WzFdLDEpOwogICAgICBjbG9zZShmZFsxXSk7CiAgICAgIGZ3cml0ZShxdWVyeSxzaXplb2Yo
Y2hhciksc2l6ZSxzdGRvdXQpOwogICAgICBleGl0KDApOwogICAgfQogIH0gZWxzZSB7CiAg
ICBkaWUgKCJNZXRob2Qgbm90IEdFVCBub3IgUE9TVCIsICJNZXRob2QgbXVzdCBiZSAnR0VU
JyBvciAnUE9TVCcuIik7CiAgfQogIGV4aXQoMCk7Cn0K

--Multipart_Fri_Jul_17_01:03:47_1998-1--