From 6a0432ae8e83df713006409cf8ba6b673ad074e5 Mon Sep 17 00:00:00 2001 From: pcanterino <> Date: Sun, 13 Feb 2005 09:42:39 +0000 Subject: [PATCH] - For security reasons, I completely changed the handling of symbolic links: Symbolic links are now treated as files, no matter where they point to. The user is just allowed to see the path where the link points to, he is allowed to delete the link, to rename it and to overwrite it by renaming an other file. Nothing else is allowed. Accessing a symbolic link pointing to a directory caused also a very strange effect: It was possible to access this directory, but you could not access the objects in it. I had to do it in this way because of the very stupid behaviour of abs_path() from the Cwd module: This function is just able to detect the absolute path of directories. Hard links are not affected by this, because it is not possible to detect them (at least I don't know how to detect them). - Changed the names of two error messages: dircopy -> dir_copy editdir -> dir_edit - Fixed various errors in some template files --- errors.dat | 8 ++++-- modules/Command.pm | 53 ++++++++++++++++++++++++++---------- modules/File/Access.pm | 6 ++-- modules/Tool.pm | 4 +-- templates.dat | 1 + templates/about.htm | 2 +- templates/confirm_unlock.htm | 4 +++ templates/dirlist_file.htm | 2 +- templates/mkdir.htm | 3 +- templates/mkfile.htm | 3 +- templates/viewlink.htm | 34 +++++++++++++++++++++++ 11 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 templates/viewlink.htm diff --git a/errors.dat b/errors.dat index 8ead289..5a54b08 100644 --- a/errors.dat +++ b/errors.dat @@ -2,18 +2,19 @@ above_root = Accessing files and directories above the virtual root directory is forbidden. binary = This editor is not able to view/edit binary files. +chprop_link = You are not allowed to change the properties of a symbolic link. chprop_root = You are not allowed to change the properties of the root directory. cmd_unknown = Unknown command: '{COMMAND}' copy_failed = Could not copy '{FILE}' to '{NEW_FILE}'. create_ar = You are not allowed to create files and directories above the virtual root directory. delete_failed = Could not delete file '{FILE}'. -dircopy = This editor is not able to copy directories. +dir_copy = This editor is not able to copy directories. +dir_edit = You cannot edit directories. dir_no_create = You have not enough permissions to create a file in directory '{DIR}'. dir_not_exist = The directory where you want to create this file or directory does not exist. dir_read_fail = Reading of directory '{DIR}' failed. dir_replace = You are not allowed to replace a directory. edit_failed = Saving of file '{FILE}' failed. The file could be damaged, please check its integrity. -editdir = You cannot edit directories. exist_edited = The target file '{FILE}' already exists and is edited by someone else. exist_no_write = The target file '{FILE}' already exists and you have not enough permissions to replace it. file_exists = A file or directory called '{FILE}' already exists. @@ -21,6 +22,9 @@ file_too_large = The file you want to view or edit is too large (max. {SIZE}&nbs in_use = The file '{FILE}' is currently edited by someone else. invalid_group = '{GROUP}' seems to be an invalid group name. Please check it and try again. invalid_upload = It seems that something is wrong with the file upload you want to submit. +link_copy = Copying symbolic links does not work. +link_edit = For security reasons, you cannot edit the target file of a symbolic link. +link_replace = You are not allowed to overwrite symbolic links. lock_failed = Locking of '{USELIST}' failed. Try it again in a moment. If the problem persists, ask the administrator to check the lock file ('{LOCK_FILE}') and to recreate it if necessary. mkdir_failed = Could not create directory '{DIR}'. mkfile_failed = Could not create file '{FILE}'. diff --git a/modules/Command.pm b/modules/Command.pm index adb62a7..cd3f6fb 100644 --- a/modules/Command.pm +++ b/modules/Command.pm @@ -6,7 +6,7 @@ package Command; # Execute Dev-Editor's commands # # Author: Patrick Canterino -# Last modified: 2005-02-10 +# Last modified: 2005-02-12 # use strict; @@ -96,7 +96,7 @@ sub exec_show($$) my $tpl = new Template; - if(-d $physical) + if(-d $physical && not -l $physical) { # Create directory listing @@ -116,7 +116,7 @@ sub exec_show($$) my $filter2 = ($filter1 && $filter1 ne '*') ? $filter1 : ''; # Wildcard for output # Create the link to the upper directory - # (only if we are not in the root directory) + # (only if the current directory is not the root directory) unless($virtual eq '/') { @@ -165,7 +165,7 @@ sub exec_show($$) my $phys_path = $physical.'/'.$file; my $virt_path = encode_entities($virtual.$file); - my @stat = stat($phys_path); + my @stat = lstat($phys_path); my $in_use = $uselist->in_use($virtual.$file); my $too_large = $config->{'max_file_size'} && $stat[7] > $config->{'max_file_size'}; @@ -178,12 +178,14 @@ sub exec_show($$) $ftpl->fillin('DATE',encode_entities(strftime($config->{'timeformat'},($config->{'use_gmt'}) ? gmtime($stat[9]) : localtime($stat[9])))); $ftpl->fillin('URL',equal_url(encode_entities($config->{'httproot'}),$virt_path)); + $ftpl->parse_if_block('link',-l $phys_path); + $ftpl->parse_if_block('no_link',not -l $phys_path); $ftpl->parse_if_block('not_readable',not -r $phys_path); $ftpl->parse_if_block('binary',-B $phys_path); $ftpl->parse_if_block('readonly',not -w $phys_path); - $ftpl->parse_if_block('viewable',-r $phys_path && -T $phys_path && not $too_large); - $ftpl->parse_if_block('editable',(-r $phys_path && -w $phys_path && -T $phys_path && not $too_large) && not $in_use); + $ftpl->parse_if_block('viewable',(-r $phys_path && -T $phys_path && not $too_large) || -l $phys_path); + $ftpl->parse_if_block('editable',((-r $phys_path && -w $phys_path && -T $phys_path && not $too_large) && not $in_use) && not -l $phys_path); $ftpl->parse_if_block('in_use',$in_use); $ftpl->parse_if_block('unused',not $in_use); @@ -209,6 +211,21 @@ sub exec_show($$) $tpl->parse_if_block('filter',$filter2); $tpl->parse_if_block('gmt',$config->{'use_gmt'}); } + elsif(-l $physical) + { + # Show the target of a symbolic link + + my $link_target = readlink($physical); + + $tpl->read_file($config->{'templates'}->{'viewlink'}); + + $tpl->fillin('FILE',encode_entities($virtual)); + $tpl->fillin('DIR',$upper_path); + $tpl->fillin('URL',encode_entities(equal_url($config->{'httproot'},$virtual))); + $tpl->fillin('SCRIPT',$script); + + $tpl->fillin('LINK_TARGET',encode_entities($link_target)); + } else { # View a file @@ -265,9 +282,10 @@ sub exec_beginedit($$) my $dir = upper_path($virtual); my $uselist = $data->{'uselist'}; - return error($config->{'errors'}->{'editdir'},$dir) if(-d $physical); - return error($config->{'errors'}->{'in_use'}, $dir,{FILE => $virtual}) if($uselist->in_use($virtual)); - return error($config->{'errors'}->{'no_edit'},$dir) unless(-r $physical && -w $physical); + return error($config->{'errors'}->{'link_edit'},$dir) if(-l $physical); + return error($config->{'errors'}->{'dir_edit'}, $dir) if(-d $physical); + return error($config->{'errors'}->{'in_use'}, $dir,{FILE => $virtual}) if($uselist->in_use($virtual)); + return error($config->{'errors'}->{'no_edit'}, $dir) unless(-r $physical && -w $physical); # Check on binary files @@ -370,7 +388,8 @@ sub exec_endedit($$) return error($config->{'errors'}->{'in_use'},$dir,{FILE => $virtual}) if($uselist->in_use($virtual)); } - return error($config->{'errors'}->{'editdir'},$dir) if(-d $physical); + return error($config->{'errors'}->{'link_edit'},$dir) if(-l $physical); + return error($config->{'errors'}->{'dir_edit'},$dir) if(-d $physical); return error($config->{'errors'}->{'no_edit'},$dir) if(-e $physical && !(-r $physical && -w $physical)); return error($config->{'errors'}->{'text_to_binary'},$dir) unless(-T $physical); @@ -480,7 +499,7 @@ sub exec_upload($$) my $virtual = $data->{'virtual'}; my $cgi = $data->{'cgi'}; - return error($config->{'errors'}->{'no_directory'},upper_path($virtual),{FILE => $virtual}) unless(-d $physical); + return error($config->{'errors'}->{'no_directory'},upper_path($virtual),{FILE => $virtual}) unless(-d $physical && not -l $physical); return error($config->{'errors'}->{'dir_no_create'},$virtual,{DIR => $virtual}) unless(-w $physical); if(my $uploaded_file = $cgi->param('uploaded_file')) @@ -495,6 +514,7 @@ sub exec_upload($$) if(-e $file_phys) { + return error($config->{'errors'}->{'link_replace'},$virtual) if(-l $file_phys); return error($config->{'errors'}->{'dir_replace'},$virtual) if(-d $file_phys); return error($config->{'errors'}->{'exist_no_write'},$virtual,{FILE => $file_virt}) unless(-w $file_phys); return error($config->{'errors'}->{'file_exists'},$virtual,{FILE => $file_virt}) unless($cgi->param('overwrite')); @@ -546,8 +566,9 @@ sub exec_copy($$) my $dir = upper_path($virtual); my $new_physical = $data->{'new_physical'}; - return error($config->{'errors'}->{'dircopy'},$dir) if(-d $physical); - return error($config->{'errors'}->{'no_copy'},$dir) unless(-r $physical); + return error($config->{'errors'}->{'link_copy'},$dir) if(-l $physical); + return error($config->{'errors'}->{'dir_copy'},$dir) if(-d $physical); + return error($config->{'errors'}->{'no_copy'},$dir) unless(-r $physical); if($new_physical) { @@ -558,6 +579,7 @@ sub exec_copy($$) if(-e $new_physical) { return error($config->{'errors'}->{'exist_edited'},$new_dir,{FILE => $new_virtual}) if($data->{'uselist'}->in_use($data->{'new_virtual'})); + return error($config->{'errors'}->{'link_replace'},$new_dir) if(-l $new_physical); return error($config->{'errors'}->{'dir_replace'},$new_dir) if(-d $new_physical); return error($config->{'errors'}->{'exist_no_write'},$new_dir,{FILE => $new_virtual}) unless(-w $new_physical); @@ -633,7 +655,7 @@ sub exec_rename($$) if(-e $new_physical) { return error($config->{'errors'}->{'exist_edited'},$new_dir,{FILE => $new_virtual}) if($data->{'uselist'}->in_use($data->{'new_virtual'})); - return error($config->{'errors'}->{'dir_replace'},$new_dir) if(-d $new_physical); + return error($config->{'errors'}->{'dir_replace'},$new_dir) if(-d $new_physical && not -l $new_physical); return error($config->{'errors'}->{'exist_no_write'},$new_dir,{FILE => $new_virtual}) unless(-w $new_physical); if(not $data->{'cgi'}->param('confirmed')) @@ -697,7 +719,7 @@ sub exec_remove($$) return error($config->{'errors'}->{'remove_root'},'/') if($virtual eq '/'); return error($config->{'errors'}->{'no_delete'},$dir) unless(-w upper_path($physical)); - if(-d $physical) + if(-d $physical && not -l $physical) { # Remove a directory @@ -770,6 +792,7 @@ sub exec_chprop($$) return error($config->{'errors'}->{'no_users'},$dir,{FILE => $virtual}) unless($users); return error($config->{'errors'}->{'chprop_root'},'/') if($virtual eq '/'); return error($config->{'errors'}->{'not_owner'},$dir,{FILE => $virtual}) unless(-o $physical); + return error($config->{'errors'}->{'chprop_link'},$dir) if(-l $physical); return error($config->{'errors'}->{'in_use'},$dir,{FILE => $virtual}) if($data->{'uselist'}->in_use($virtual)); my $cgi = $data->{'cgi'}; diff --git a/modules/File/Access.pm b/modules/File/Access.pm index 4c4d0da..dd6403b 100644 --- a/modules/File/Access.pm +++ b/modules/File/Access.pm @@ -7,7 +7,7 @@ package File::Access; # using only one command # # Author: Patrick Canterino -# Last modified: 2005-02-10 +# Last modified: 2005-02-12 # use strict; @@ -46,7 +46,7 @@ $has_flock = eval { local $SIG{'__DIE__'}; flock(STDOUT,0); 1 }; # Params: Directory # # Return: Hash reference: dirs => directories -# files => files +# files => files and symbolic links sub dir_read($) { @@ -72,7 +72,7 @@ sub dir_read($) { next if($entry eq '.' || $entry eq '..'); - if(-d $dir.'/'.$entry) + if(-d $dir.'/'.$entry && not -l $dir.'/'.$entry) { push(@dirs,$entry); } diff --git a/modules/Tool.pm b/modules/Tool.pm index 2347445..acc4722 100644 --- a/modules/Tool.pm +++ b/modules/Tool.pm @@ -6,7 +6,7 @@ package Tool; # Some shared sub routines # # Author: Patrick Canterino -# Last modified: 2005-01-08 +# Last modified: 2005-02-12 # use strict; @@ -83,7 +83,7 @@ sub check_path($$) my $short_path = substr($path,length($root)); $short_path =~ tr!\\!/!; $short_path = '/'.$short_path if($short_path !~ m!^/!); - $short_path = $short_path.'/' if($short_path !~ m!/$! && -d $path); + $short_path = $short_path.'/' if($short_path !~ m!/$! && -d $path && not -l $path); return ($path,$short_path); } diff --git a/templates.dat b/templates.dat index 65472cc..a3fcdb3 100644 --- a/templates.dat +++ b/templates.dat @@ -19,5 +19,6 @@ mkfile = templates/mkfile.htm renamefile = templates/renamefile.htm upload = templates/upload.htm viewfile = templates/viewfile.htm +viewlink = templates/viewlink.htm # End of configuration file \ No newline at end of file diff --git a/templates/about.htm b/templates/about.htm index 5ad69fc..4acc3df 100644 --- a/templates/about.htm +++ b/templates/about.htm @@ -12,7 +12,7 @@

Dev-Editor {VERSION}

-

© 1999-2000 Roland Blüthgen, Frank Schönmann
+

© 1999-2000 Roland Blüthgen, Frank Schönmann
© 2003-2005 Patrick Canterino

http://devedit.sourceforge.net/

diff --git a/templates/confirm_unlock.htm b/templates/confirm_unlock.htm index e620f17..f75f359 100644 --- a/templates/confirm_unlock.htm +++ b/templates/confirm_unlock.htm @@ -23,5 +23,9 @@

+ +
+ +

About Dev-Editor

\ No newline at end of file diff --git a/templates/dirlist_file.htm b/templates/dirlist_file.htm index f08398a..5df126e 100644 --- a/templates/dirlist_file.htm +++ b/templates/dirlist_file.htm @@ -2,5 +2,5 @@ {SIZE} {DATE}{IF gmt} (GMT){ENDIF} {FILE_NAME} -({IF viewable}View{ELSE}View{ENDIF} | {IF editable}Edit{ELSE}Edit{ENDIF} | Copy{IF unused}{IF dir_writeable} | Rename | Delete{ENDIF}{ENDIF}{IF in_use} | Unlock{ENDIF} |{IF unused}{IF users} Chmod/Chgrp |{ENDIF}{ENDIF} View in Browser) +({IF viewable}View{ELSE}View{ENDIF} | {IF editable}Edit{ELSE}Edit{ENDIF}{IF no_link} | Copy{ENDIF}{IF unused}{IF dir_writeable} | Rename | Delete{ENDIF}{ENDIF}{IF no_link}{IF in_use} | Unlock{ENDIF} |{IF unused}{IF users} Chmod/Chgrp |{ENDIF}{ENDIF}{ELSE} |{ENDIF} View in Browser) diff --git a/templates/mkdir.htm b/templates/mkdir.htm index 565e904..db8b11a 100644 --- a/templates/mkdir.htm +++ b/templates/mkdir.htm @@ -22,7 +22,6 @@
-

About Dev-Editor

About Dev-Editor

\ No newline at end of file diff --git a/templates/mkfile.htm b/templates/mkfile.htm index 66e2c83..7c6c059 100644 --- a/templates/mkfile.htm +++ b/templates/mkfile.htm @@ -22,7 +22,6 @@
-

About Dev-Editor

About Dev-Editor

\ No newline at end of file diff --git a/templates/viewlink.htm b/templates/viewlink.htm new file mode 100644 index 0000000..451cded --- /dev/null +++ b/templates/viewlink.htm @@ -0,0 +1,34 @@ + + + + +Target of symbolic link {FILE} + + + + +

Target of symbolic link {FILE}

+ +

(equals {URL})

+ +

Back to {DIR}

+ +

'{FILE}' is a symbolic link pointing to:
+{LINK_TARGET}

+ +

For security reasons, you cannot access the target of this link.

+ +
+ + + + + + + + + +
Go to directory/file: About Dev-Editor
+ + \ No newline at end of file -- 2.34.1