/******************************************************************** * $Author: jgoerzen $ * $Revision: 1.1.1.1 $ * $Date: 2000/08/19 00:28:56 $ * $Source: /var/cvs/gopher/gopherd/dedot.c,v $ * $State: Exp $ * * Paul Lindner, University of Minnesota CIS. * * Copyright 1991, 1992 by the Regents of the University of Minnesota * see the file "Copyright" in the distribution for conditions of use. ********************************************************************* * MODULE: dedot.c * See below. ********************************************************************* * Revision History: * $Log: dedot.c,v $ * Revision 1.1.1.1 2000/08/19 00:28:56 jgoerzen * Import from UMN Gopher 2.3.1 after GPLization * * Revision 3.10 1995/09/25 05:02:32 lindner * Convert to ANSI C * * Revision 3.9 1994/04/22 03:35:16 lindner * Fix for spinning gopherd processes * * Revision 3.8 1994/04/14 15:48:52 lindner * Fix for files with single quotes * * Revision 3.7 1994/03/04 23:25:14 lindner * Fix for dedot weirdness * * Revision 3.6 1993/09/18 03:26:38 lindner * Important Security fix * * Revision 3.5 1993/08/23 18:33:57 lindner * Fix off by one error * * Revision 3.4 1993/08/06 14:28:14 lindner * Further strip out single quotes * * Revision 3.3 1993/08/05 22:19:43 lindner * Fix for single quotes * * Revision 3.2 1993/08/05 20:43:07 lindner * Added fix for dedot to remove quotes for when using system or popen * * Revision 3.1.1.1 1993/02/11 18:02:50 lindner * Gopher+1.2beta release * * Revision 1.1 1992/12/10 23:13:27 lindner * gopher 1.1 release * * *********************************************************************/ #include /* ** These routines can be used to remove ../ and ./ entries from ** pathnames. These routines do it radically, without any attempt ** at all at interpretation. This is okay for a gopher server, ** because clients aren't supposed to ask for .. or . in a request. ** ** We want to do this so that we can avoid the chroot(), so that we ** can have symbolic links under the gopher directory to other things ** (like man pages for example) outside our structure, and still be ** safe. Unless of course someone makes a link to / or somewhere silly. ** ** dedot1 will remove dots from one string in place, dedot2 will copy ** one to the other, removing in the process - the src and dst can be ** the same. dedot1 can use this to advantage - it checks first if ** things have to be removed, and calls dedot2 if necessary. This ** is a slight advantage because in most cases we won't do anything, ** and we save the expense of copying data back and forth. This ** seems to save almost half the time (very loose testing though). ** ** John Sellens jmsellens@watdragon.waterloo.edu */ void dequote1(char *); void dedot1(char *); void dedot2(char *, char *); void dequote1(char *src) { char *cp2; /** Strip out the quotes.. **/ while (*src != '\0') { if (*src == '"' || *src == '\'') { for (cp2=src; *cp2 != '\0'; cp2++) { *cp2 = *(cp2+1); } } src++; } } void dedot1(char *src ) { dequote1(src); if ( *src == '.' ) { if (src[1] == '\0' || src[1] == '/' || ( src[1] == '.' && ( src[2] == '\0' || src[2] == '/' ) ) ) { dedot2( src, src ); return; } } while ( *src ) { if ( *src++ == '/' ) { if ( *src == '.' ) { if (src[1] == '\0' || src[1] == '/' || ( src[1] == '.' && ( src[2] == '\0' || src[2] == '/' ) ) ) { dedot2( src, src ); return; } } } } return; } /* copy src to dst, blindly removing (not interpreting) ./ and ../ */ void dedot2(char *src, char *dst) { /* ** We either have /, a filename, ./ or ../ */ int i; while ( *src ) { switch ( *src ) { case '/': /* copy it, and skip any extras e.g. /a///b */ *dst++ = *src++; while ( *src == '/' ) src++; break; case '.': /* don't forget about trailing . and .. */ /* Nuke any quotes */ for (i=1; src[i] == '"' || src[i] == '\''; i++) ; if ( src[i] == '/' ) { /* ./ */ src += i+1; break; } if ( src[i] == '\0' ) { /* .\0 */ src += i; /* only 1 so we don't fall off the end */ break; } if ( src[i] == '.' && (src[i+1] == '"' || src[i+1] == '\'')) { /* ..", ..' */ src += i+2; break; } if ( src[i] == '.' && src[i+1] == '/' ) { /* ../ */ src += i+2; break; } if ( src[i] == '.' && src[i+1] == '\0' ) { /* .. */ src += i+1; /* don't fall off the end */ break; } /* must be a filename - fall through */ default: /* must be filename - copy it over */ while ( *src != '\0' && *src != '/') /** Note quotes are taken care of by Gpopen **/ *dst++ = *src++; break; } } /* and terminate it */ *dst = '\0'; }