OpenPKG CVS Repository
  http://cvs.openpkg.org/
  ____________________________________________________________________________

  Server: cvs.openpkg.org                  Name:   Thomas Lotterer
  Root:   /e/openpkg/cvs                   Email:  [EMAIL PROTECTED]
  Module: openpkg-src                      Date:   05-Mar-2003 16:38:17
  Branch: OPENPKG_1_STABLE                 Handle: 2003030515381600

  Added files:              (Branch: OPENPKG_1_STABLE)
    openpkg-src/kerberos    kerberos.patch
  Modified files:           (Branch: OPENPKG_1_STABLE)
    openpkg-src/kerberos    kerberos.spec

  Log:
    MFC: CAN-2003-0041

  Summary:
    Revision    Changes     Path
    1.1.2.1     +305 -0     openpkg-src/kerberos/kerberos.patch
    1.10.2.2    +4  -2      openpkg-src/kerberos/kerberos.spec
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: openpkg-src/kerberos/kerberos.patch
  ============================================================================
  $ cvs diff -u -r0 -r1.1.2.1 kerberos.patch
  --- /dev/null 2003-03-05 16:38:16.000000000 +0100
  +++ kerberos.patch    2003-03-05 16:38:17.000000000 +0100
  @@ -0,0 +1,305 @@
  +# taken from http://updates.redhat.com/8.0/en/os/SRPMS/krb5-1.2.5-8.src.rpm
  +# Patch to add in missing protection against special characters and
  +# malicious servers, backported from netkit ftp 0.17 sources, (There are
  +# probably other security fixes that are missing from this old ftp
  +# source too).  Mark Cox, [EMAIL PROTECTED], Jan 2003
  +# http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0041
  +
  +--- krb5-1.2.5/src/appl/gssftp/ftp/cmds.c.ORIG       2003-01-20 10:21:41.000000000 
+0000
  ++++ krb5-1.2.5/src/appl/gssftp/ftp/cmds.c    2003-01-20 11:03:40.000000000 +0000
  +@@ -69,6 +69,7 @@
  + extern      char **ftpglob();
  + extern      char *home;
  + extern      char *remglob();
  ++static int checkglob(int fd, const char *pattern);
  + extern      char *getenv();
  + #ifndef HAVE_STRERROR
  + #define strerror(error) (sys_errlist[error])
  +@@ -88,6 +89,64 @@
  + extern int do_auth();
  + 
  + /*
  ++ * pipeprotect: protect against "special" local filenames by prepending
  ++ * "./". Special local filenames are "-" and "|..." AND "/...".
  ++ */
  ++static char *pipeprotect(char *name) 
  ++{
  ++    char *nu;
  ++    if (strcmp(name, "-") && *name!='|' && *name!='/') {
  ++            return name;
  ++    }
  ++
  ++    /* We're going to leak this memory. XXX. */
  ++    nu = malloc(strlen(name)+3);
  ++    if (nu==NULL) {
  ++            perror("malloc");
  ++            code = -1;
  ++            return NULL;
  ++    }
  ++    strcpy(nu, ".");
  ++    if (*name != '/') strcat(nu, "/");
  ++    strcat(nu, name);
  ++    return nu;
  ++}
  ++
  ++/*
  ++ * Look for embedded ".." in a pathname and change it to "!!", printing
  ++ * a warning.
  ++ */
  ++static char *pathprotect(char *name)
  ++{
  ++    int gotdots=0, i, len;
  ++    
  ++    /* Convert null terminator to trailing / to catch a trailing ".." */
  ++    len = strlen(name)+1;
  ++    name[len-1] = '/';
  ++
  ++    /*
  ++     * State machine loop. gotdots is < 0 if not looking at dots,
  ++     * 0 if we just saw a / and thus might start getting dots,
  ++     * and the count of dots seen so far if we have seen some.
  ++     */
  ++    for (i=0; i<len; i++) {
  ++            if (name[i]=='.' && gotdots>=0) gotdots++;
  ++            else if (name[i]=='/' && gotdots<0) gotdots=0;
  ++            else if (name[i]=='/' && gotdots==2) {
  ++                printf("Warning: embedded .. in %.*s (changing to !!)\n",
  ++                       len-1, name);
  ++                name[i-1] = '!';
  ++                name[i-2] = '!';
  ++                gotdots = 0;
  ++            }
  ++            else if (name[i]=='/') gotdots = 0;
  ++            else gotdots = -1;
  ++    }
  ++    name[len-1] = 0;
  ++    return name;
  ++}
  ++
  ++/*
  +  * `Another' gets another argument, and stores the new argc and argv.
  +  * It reverts to the top level (via main.c's intr()) on EOF/error.
  +  *
  +@@ -832,7 +891,15 @@
  + 
  +     if (argc == 2) {
  +             argc++;
  +-            argv[2] = argv[1];
  ++            /* 
  ++             * Protect the user from accidentally retrieving special
  ++             * local names.
  ++             */
  ++            argv[2] = pipeprotect(argv[1]);
  ++            if (!argv[2]) {
  ++                    code = -1;
  ++                    return 0;
  ++            }
  +             loc++;
  +     }
  +     if (argc < 2 && !another(&argc, &argv, "remote-file"))
  +@@ -1007,8 +1074,19 @@
  +                     if (mapflag) {
  +                             tp = domap(tp);
  +                     }
  +-                    recvrequest("RETR", tp, cp, "w",
  +-                        tp != cp || !interactive);
  ++                    /* Reject embedded ".." */
  ++                    tp = pathprotect(tp);
  ++
  ++                    /* Prepend ./ to "-" or "!*" or leading "/" */
  ++                    tp = pipeprotect(tp);
  ++                    if (tp == NULL) {
  ++                            /* hmm... how best to handle this? */
  ++                            mflag = 0;
  ++                    }
  ++                    else {
  ++                        recvrequest("RETR", tp, cp, "w",
  ++                                    tp != cp || !interactive);
  ++                    }
  +                     if (!mflag && fromatty) {
  +                             ointer = interactive;
  +                             interactive = 1;
  +@@ -1024,16 +1102,14 @@
  + }
  + 
  + char *
  +-remglob(argv,doswitch)
  +-    char *argv[];
  +-    int doswitch;
  ++remglob(char *argv[], int doswitch)
  + {
  +     char temp[16];
  +-    static char buf[MAXPATHLEN];
  ++    static char buf[PATH_MAX];
  +     static FILE *ftemp = NULL;
  +     static char **args;
  +-    int oldverbose, oldhash;
  +-    char *cp, *mode;
  ++    int oldverbose, oldhash, badglob = 0;
  ++    char *cp;
  + 
  +     if (!mflag) {
  +             if (!doglob) {
  +@@ -1055,36 +1131,154 @@
  +             return (cp);
  +     }
  +     if (ftemp == NULL) {
  +-            (void) strncpy(temp, _PATH_TMP, sizeof(temp) - 1);
  +-            temp[sizeof(temp) - 1] = '\0';
  +-            (void) mktemp(temp);
  ++            int oldumask, fd;
  ++            (void) strcpy(temp, _PATH_TMP);
  ++
  ++            /* libc 5.2.18 creates with mode 0666, which is dumb */
  ++            oldumask = umask(077);
  ++            fd = mkstemp(temp);
  ++            umask(oldumask);
  ++
  ++            if (fd<0) {
  ++                    printf("Error creating temporary file, oops\n");
  ++                    return NULL;
  ++            }
  ++
  +             oldverbose = verbose, verbose = 0;
  +             oldhash = hash, hash = 0;
  +             if (doswitch) {
  +                     pswitch(!proxy);
  +             }
  +-            for (mode = "w"; *++argv != NULL; mode = "a")
  +-                    recvrequest ("NLST", temp, *argv, mode, 0);
  ++            while (*++argv != NULL) {
  ++                    int     dupfd = dup(fd);
  ++
  ++                    recvrequest ("NLST", temp, *argv, "a", 0);
  ++                    if (!checkglob(dupfd, *argv)) {
  ++                            badglob = 1;
  ++                            break;
  ++                    }
  ++            }
  ++            unlink(temp);
  ++
  +             if (doswitch) {
  +                     pswitch(!proxy);
  +             }
  +             verbose = oldverbose; hash = oldhash;
  +-            ftemp = fopen(temp, "r");
  +-            (void) unlink(temp);
  ++            if (badglob) {
  ++                    printf("Refusing to handle insecure file list\n");
  ++                    close(fd);
  ++                    return NULL;
  ++            }
  ++            ftemp = fdopen(fd, "r");
  +             if (ftemp == NULL) {
  +                     printf("can't find list of remote files, oops\n");
  +                     return (NULL);
  +             }
  ++            rewind(ftemp);
  +     }
  +     if (fgets(buf, sizeof (buf), ftemp) == NULL) {
  +             (void) fclose(ftemp), ftemp = NULL;
  +             return (NULL);
  +     }
  +-    if ((cp = strchr(buf, '\n')) != NULL)
  ++    if ((cp = index(buf, '\n')) != NULL)
  +             *cp = '\0';
  +     return (buf);
  + }
  + 
  ++/*
  ++ * Check whether given pattern matches `..'
  ++ * We assume only a glob pattern starting with a dot will match
  ++ * dot entries on the server.
  ++ */
  ++static int
  ++isdotdotglob(const char *pattern)
  ++{
  ++    int     havedot = 0;
  ++    char    c;
  ++
  ++    if (*pattern++ != '.')
  ++            return 0;
  ++    while ((c = *pattern++) != '\0' && c != '/') {
  ++            if (c == '*' || c == '?')
  ++                    continue;
  ++            if (c == '.' && havedot++)
  ++                    return 0;
  ++    }
  ++    return 1;
  ++}
  ++
  ++/*
  ++ * This function makes sure the list of globbed files returned from
  ++ * the server doesn't contain anything dangerous such as
  ++ * /home/<yourname>/.forward, or ../.forward,
  ++ * or |mail [EMAIL PROTECTED] </etc/passwd, etc.
  ++ * Covered areas:
  ++ *  -       returned name starts with / but glob pattern doesn't
  ++ *  -       glob pattern starts with / but returned name doesn't
  ++ *  -       returned name starts with |
  ++ *  -       returned name contains .. in a position where glob
  ++ *  pattern doesn't match ..
  ++ *  I.e. foo/.* allows foo/../bar but not foo/.bar/../fly
  ++ *
  ++ * Note that globbed names starting with / should really be stored
  ++ * under the current working directory; this is handled in mget above.
  ++ *                                          --okir
  ++ */
  ++static int
  ++checkglob(int fd, const char *pattern)
  ++{
  ++    const char      *sp;
  ++    char            buffer[MAXPATHLEN], dotdot[MAXPATHLEN];
  ++    int             okay = 1, nrslash, initial, nr;
  ++    FILE            *fp;
  ++
  ++    /* Find slashes in glob pattern, and verify whether component
  ++     * matches `..'
  ++     */
  ++    initial = (pattern[0] == '/');
  ++    for (sp = pattern, nrslash = 0; sp != 0; sp = strchr(sp, '/')) {
  ++            while (*sp == '/')
  ++                    sp++;
  ++            if (nrslash >= MAXPATHLEN) {
  ++                    printf("Incredible pattern: %s\n", pattern);
  ++                    return 0;
  ++            }
  ++            dotdot[nrslash++] = isdotdotglob(sp);
  ++    }
  ++
  ++    fp = fdopen(fd, "r");
  ++    while (okay && fgets(buffer, sizeof(buffer), fp) != NULL) {
  ++            char    *sp;
  ++
  ++            if ((sp = strchr(buffer, '\n')) != 0) {
  ++                    *sp = '\0';
  ++            } else {
  ++                    printf("Extremely long filename from server: %s",
  ++                            buffer);
  ++                    okay = 0;
  ++                    break;
  ++            }
  ++            if (buffer[0] == '|'
  ++             || (buffer[0] != '/' && initial)
  ++             || (buffer[0] == '/' && !initial))
  ++                    okay = 0;
  ++            for (sp = buffer, nr = 0; sp; sp = strchr(sp, '/'), nr++) {
  ++                    while (*sp == '/')
  ++                            sp++;
  ++                    if (sp[0] == '.' && !strncmp(sp, "../", 3)
  ++                     && (nr >= nrslash || !dotdot[nr]))
  ++                            okay = 0;
  ++            }
  ++    }
  ++
  ++    if (!okay)
  ++            printf("Filename provided by server "
  ++                   "doesn't match pattern `%s': %s\n", pattern, buffer);
  ++
  ++    fclose(fp);
  ++    return okay;
  ++}
  ++
  + char *
  + onoff(bool)
  +     int bool;
  @@ .
  patch -p0 <<'@@ .'
  Index: openpkg-src/kerberos/kerberos.spec
  ============================================================================
  $ cvs diff -u -r1.10.2.1 -r1.10.2.2 kerberos.spec
  --- openpkg-src/kerberos/kerberos.spec        18 Jan 2003 14:12:31 -0000      
1.10.2.1
  +++ openpkg-src/kerberos/kerberos.spec        5 Mar 2003 15:38:16 -0000       
1.10.2.2
  @@ -9,7 +9,7 @@
   ##  the above copyright notice and this permission notice appear in all
   ##  copies.
   ##
  -##  THIS SOFTWARE IS PROVIDED AS IS'' AND ANY EXPRESSED OR IMPLIED
  +##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
  @@ -33,10 +33,11 @@
   Group:        Cryptography
   License:      MIT
   Version:      1.2.6
  -Release:      1.20020923
  +Release:      1.20030305
   
   #   list of sources
   Source0:      
http://www.crypto-publish.org/dist/mit-kerberos5/krb5-%{version}.tar.gz
  +Patch0:       kerberos.patch
   
   #   build information
   Prefix:       %{l_prefix}
  @@ -56,6 +57,7 @@
   
   %prep
       %setup -q -n krb5-%{version}
  +    %patch -p1
   
   %build
       cd src
  @@ .
______________________________________________________________________
The OpenPKG Project                                    www.openpkg.org
CVS Repository Commit List                     [EMAIL PROTECTED]

Reply via email to