From 2b79935e9e14a5d87f234079de7a0d0351a9232e Mon Sep 17 00:00:00 2001 From: lars Date: Sat, 24 Dec 2005 10:01:08 +0000 Subject: [PATCH] utf-8 support fixed pretty names work again fixed check for added mail addresses config_all added error messages for list creation clarified --- ezmlm-web-3.0/CHANGES | 2 +- ezmlm-web-3.0/TODO | 2 - ezmlm-web-3.0/ezmlm-web.cgi | 123 +++++++++------ ezmlm-web-3.0/lang/de.hdf | 22 ++- ezmlm-web-3.0/lang/en.hdf | 12 +- ezmlm-web-3.0/template/config_all.cs | 163 ++++++++++++++++++++ ezmlm-web-3.0/template/config_main.cs | 15 +- ezmlm-web-3.0/template/config_posting.cs | 8 +- ezmlm-web-3.0/template/config_processing.cs | 2 +- ezmlm-web-3.0/template/list_create.cs | 2 +- ezmlm-web-3.0/template/nav.cs | 2 + ezmlm-web-3.0/template/subscribers.cs | 4 +- 12 files changed, 280 insertions(+), 77 deletions(-) create mode 100644 ezmlm-web-3.0/template/config_all.cs diff --git a/ezmlm-web-3.0/CHANGES b/ezmlm-web-3.0/CHANGES index 69e8ad1..ff1ca85 100644 --- a/ezmlm-web-3.0/CHANGES +++ b/ezmlm-web-3.0/CHANGES @@ -102,4 +102,4 @@ Version 3.0 - 12/21/02005 * commas are not necessary anymore in webusers file * support for MAIL_DOMAIN config setting * requires the clearsilver template engine - +* changed directory for safely removed mailinglists diff --git a/ezmlm-web-3.0/TODO b/ezmlm-web-3.0/TODO index 0c01b89..ed45e42 100644 --- a/ezmlm-web-3.0/TODO +++ b/ezmlm-web-3.0/TODO @@ -6,8 +6,6 @@ support for: * charset * show log -split filter and manipulate - allow dynamic addition of user-made config templates (seperate directory, ...) language switch support diff --git a/ezmlm-web-3.0/ezmlm-web.cgi b/ezmlm-web-3.0/ezmlm-web.cgi index f48c49a..a8dbcb4 100755 --- a/ezmlm-web-3.0/ezmlm-web.cgi +++ b/ezmlm-web-3.0/ezmlm-web.cgi @@ -201,10 +201,21 @@ elsif ($action eq '' || $action eq 'list_select') { } elsif (($action eq 'config_ask') || ($action eq 'config_do')) { # User wants to see/change the configuration ... my $subset = $q->param('config_subset'); - if (defined($q->param('list')) && ($subset ne '') - && ($subset =~ /^[\w]*$/) && (-e "$TEMPLATE_DIR/config_$subset" . ".cs")) { - $success = 'UpdateConfig' if (($action eq 'config_do') && &update_config()); - $pagename = 'config_' . $subset; + if (defined($q->param('list')) && ($subset ne '')) { + if ($subset =~ m/^RESERVED-([\w_-]*)$/) { + $pagename = $1 + } elsif (($subset =~ /^[\w]*$/) && (-e "$TEMPLATE_DIR/config_$subset" . ".cs")) { + $pagename = 'config_' . $subset; + } else { + $pagename = ''; + } + if ($pagename ne '') { + $success = 'UpdateConfig' if (($action eq 'config_do') && &update_config()); + } else { + $error = 'UnknownConfigPage'; + warn "missing config page: $subset"; + $pagename = 'list_select'; + } } else { $error = 'ParameterMissing'; $pagename = 'list_select'; @@ -299,7 +310,7 @@ sub output_page { die "sub template ($TEMPLATE_DIR/$pagename.cs) not found!" unless (-e "$TEMPLATE_DIR/$pagename.cs"); # print http header - print "Content-Type: text/html\n\n"; + print "Content-Type: text/html; charset=utf-8\n\n"; my $cs = ClearSilver::CS->new($pagedata); @@ -398,12 +409,20 @@ sub set_pagedata4list &set_pagedata4part_list($part_type) if ($part_type ne ''); $i = 0; - my $item; + my $address; + my $addr_name; + my %pretty; + tie %pretty, "DB_File", "$LIST_DIR/$listname/webnames" if ($PRETTY_NAMES); # TODO: use "pretty" output style for visible mail address - foreach $item ($list->subscribers($part_type)) { - $pagedata->setValue("Data.List.Subscribers." . $i, "$item") unless ($item eq ''); + foreach $address (sort $list->subscribers($part_type)) { + if ($address ne '') { + $pagedata->setValue("Data.List.Subscribers." . $i . '.address', "$address"); + $addr_name = ($PRETTY_NAMES)? $pretty{$address} : ''; + $pagedata->setValue("Data.List.Subscribers." . $i . '.name', $addr_name); + } $i++; } + untie %pretty if ($PRETTY_NAMES); $pagedata->setValue("Data.List.hasDenyList", 1) if ($list->isdeny); $pagedata->setValue("Data.List.hasAllowList", 1) if ($list->isallow); @@ -496,7 +515,7 @@ sub set_pagedata4options { # they have no meaning, so we should adapt them to reality $pagedata->setValue("Data.List.Options.t" , 1) if (-e "$dir_of_list/text/trailer"); - $pagedata->setValue("Data.List.Options.p" , 1) + $pagedata->setValue("Data.List.Options.f" , 1) if (-e "$dir_of_list/prefix"); $pagedata->setValue("Data.List.Options.x" , 1) if ((-e "$dir_of_list/mimeremove") || (-e "$dir_of_list/mimereject")); @@ -568,22 +587,30 @@ sub delete_list { # they don't show up. That way they can always be recovered by a helpful # sysadmin should he/she be in the mood :) + my $SAFE_DIR = "$LIST_DIR/_deleted_lists"; + mkdir "$SAFE_DIR", 0700 if (! -e "$SAFE_DIR"); + + # look for an unused directory name + my $i = 0; + while (-e "$SAFE_DIR/" . $q->param('list') . "-$i") { $i++; } + + $SAFE_DIR .= '/' . $q->param('list') . "-$i"; + my ($oldfile); $oldfile = "$LIST_DIR/" . $q->param('list'); - my ($newfile); $newfile = "$LIST_DIR/." . $q->param('list'); - unless (move($oldfile, $newfile)) { + unless (move($oldfile, $SAFE_DIR)) { $warning = 'SafeRemoveRenameDirFailed'; return (1==0); } - mkdir "$HOME_DIR/deleted.qmail", 0700 if(!-e "$HOME_DIR/deleted.qmail"); unless (opendir(DIR, "$HOME_DIR")) { $warning = 'DotQmailDirAccessDenied'; return (1==0); } + # TODO: this could possibly move some qmail files of other lists - improve it! my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; closedir DIR; foreach (@files) { - unless (move($_, "$HOME_DIR/deleted.qmail/")) { + unless (move($_, "$SAFE_DIR")) { $warning = 'SafeRemoveMoveDotQmailFailed'; return (1==0); } @@ -624,7 +651,7 @@ sub untaint { next if($params[$i] eq 'mailaddressfile'); foreach $param ($q->param($params[$i])) { next if $param eq ''; - if ($param =~ /^([#-\@\w\.\/\[\]\:\n\r\>\< _]+)$/) { + if ($param =~ /^([#-\@\w\.\/\[\]\:\n\r\>\< _"']+)$/) { push @values, $1; } else { warn "Tainted input in '$params[$i]': " . $q->param($params[$i]); @@ -666,10 +693,11 @@ sub check_permission_for_action { sub add_address { # Add an address to a list .. - my ($address, $list, $part, @addresses, $count); + my ($address, $list, $part, @addresses, $fail_count); $list = new Mail::Ezmlm("$LIST_DIR/" . $q->param('list')); $part = &get_list_part(); + $fail_count = 0; if (($q->param('mailaddressfile')) && ($FILE_UPLOAD)) { # Sanity check @@ -684,9 +712,12 @@ sub add_address { my($fh) = $q->param('mailaddressfile'); while (<$fh>) { next if (/^\s*$/ or /^#/); # blank, comments - next unless ( /(\w[\-\w_\.]*)@(\w[\-\w_\.]+)/ ); # email address ... - chomp(); - push @addresses, "$_"; + if ( /(\w[\-\w_\.]*)@(\w[\-\w_\.]+)/ ) { + chomp(); + push @addresses, "$_"; + } else { + $fail_count++; + } } } @@ -697,8 +728,8 @@ sub add_address { $address .= $DEFAULT_HOST if ($q->param('mailaddress_add') =~ /\@$/); # untaint - if ($address =~ /(\w[\-\w_\.]*)@(\w[\-\w_\.]+)/) { - push @addresses, "$1\@$2"; + if ($address =~ m/(\w[\-\w_\.]*)@(\w[\-\w_\.]+)/) { + push @addresses, "$address"; } else { warn "invalid address to add: $address to $part"; $warning = 'AddAddress'; @@ -707,23 +738,28 @@ sub add_address { } - $count = 0; - foreach $address (@addresses) { + my %pretty; + my $add; + tie %pretty, "DB_File", "$LIST_DIR/" . $q->param('list') . "/webnames" if ($PRETTY_NAMES); + foreach $address (@addresses) { - my($add) = Mail::Address->parse($address); - if(defined($add->name()) && $PRETTY_NAMES) { - my(%pretty); - tie %pretty, "DB_File", "$LIST_DIR/" . $q->param('list') . "/webnames"; - $pretty{$add->address()} = $add->name(); - untie %pretty; - } - - if ($list->issub($add->address(), $part)) { - $warning = 'AddAddress'; + ($add) = Mail::Address->parse($address); + if (($add->address() =~ /^\w[\w_-]*\@/) && !($list->issub($add->address(), $part))) { + # it seems, that we cannot trust the return value of "$list->sub" + $list->sub($add->address(), $part); + if(defined($add->name()) && $PRETTY_NAMES) { + $pretty{$add->address()} = $add->name(); + } } else { - $warning = 'AddAddress' unless ($list->sub($add->address(), $part)); + $fail_count++; } - $count++; + } + untie %pretty if ($PRETTY_NAMES); + if ($fail_count gt 0) { + $warning = 'AddAddress'; + return (1==0); + } else { + return (0==0); } } @@ -823,8 +859,12 @@ sub create_list { $warning = 'InvalidLocalPart'; return (1==0); } - if(-e ("$LIST_DIR/$listname/lock") || -e ("$HOME_DIR/.qmail-$qmail")) { - $warning = 'ListAlreadyExists'; + if (-e "$LIST_DIR/$listname/lock") { + $warning = 'ListNameAlreadyExists'; + return (1==0); + } + if (-e "$HOME_DIR/.qmail-$qmail") { + $warning = 'ListAddressAlreadyExists'; return (1==0); } @@ -1151,17 +1191,6 @@ sub webauth_create_allowed { # --------------------------------------------------------------------------- -sub pretty_names { - return undef unless($PRETTY_NAMES); - my (%pretty, %prettymem); - tie %pretty, "DB_File", "$LIST_DIR/" . $q->param('list') . '/webnames'; - %prettymem = %pretty; - untie %pretty; - - return \%prettymem; -} - -# ------------------------------------------------------------------------- sub rmtree { # A subroutine to recursively delete a directory (like rm -f). # Based on the one in the perl cookbook :) diff --git a/ezmlm-web-3.0/lang/de.hdf b/ezmlm-web-3.0/lang/de.hdf index 214b291..702202c 100644 --- a/ezmlm-web-3.0/lang/de.hdf +++ b/ezmlm-web-3.0/lang/de.hdf @@ -10,7 +10,7 @@ Lang { Subscribers = AbonnentInnen AllowList = Zulassungsliste DenyList = Ablehnungsliste - DigestList = Übersichtsliste + DigestList = Zusammenfassung ModList = ModeratorInnen ConfigMain = Einstellungen ConfigSub = Einschreibung @@ -18,6 +18,7 @@ Lang { ConfigAdmin = Administration ConfigArchive = Archivierung ConfigProcess = Verarbeitung + ConfigAll = Übersicht TextFiles = Texte ListSelect = Auswahl einer Liste Properties = Eigenschaften von @@ -32,6 +33,7 @@ Lang { ConfigAdmin = Fern-Administration der Liste ConfigArchive = Archivierung der Liste ConfigProcess = Nachrichtenverarbeitung + ConfigAll = Einstellungen im Überblick SubscriberList = AbonnentInnen der Liste AllowList = Zugelassene Nutzer DenyList = Abzuweisende Nutzer @@ -62,6 +64,7 @@ Lang { Forbidden = Fehler: dir fehlen die notwendigen Rechte für diese Aktion ListDirUnavailable = Fehler beim Zugriff auf das Hauptverzeichnis der Listen! InvalidFileName = Der Dateiname ist nicht zulässig. + UnknownConfigPage = Die gähle Konfigurations-Seite existiert nicht! } @@ -72,7 +75,8 @@ Lang { DeleteList = Die Löschung der Mailingliste schlug fehl! UpdateConfig = Beim Speichern der Einstellungen trat ein Fehler auf! SaveFile = Die Datei konnte nicht gespeichert werden! - ListAlreadyExists = Es gibt bereits eine Liste mit diesem Namen. + ListNameAlreadyExists = Es gibt bereits eine Liste mit diesem Namen. + ListAddressAlreadyExists = Es gibt bereits eine Liste mit dieser Adresse. ListDoesNotExist = Eine Liste dieses Namens existiert nicht. ListDirAccessDenied = Fehler beim Zugriff auf das Verzeichnis der Liste TextDirAccessDenied = Beim Zugriff auf das Text-Verzeichnis der Liste trat ein Fehler auf. @@ -93,7 +97,7 @@ Lang { SuccessMessage { AddAddress = Einschreibung erfolgreich - DeleteAddress = Löschung erfolgreich abgeschlossen + DeleteAddress = Austragung erfolgreich abgeschlossen CreateList = Die neue Liste wurde erfolgreich angelegt. DeleteList = Die Mailingliste wurde gelöscht. UpdateConfig = Die neuen Einstellungen wurden erfolgreich gespeichert. @@ -147,7 +151,7 @@ Lang { ListName = Name der Liste ListAddress = Addresse der Liste ListOptions = Grundlegende Einstellungen - AllowedToEdit = Die Nutzer, die diese Liste per Web-Interface konfigurieren dürfen: + AllowedToEdit = Nutzer, die diese Liste per Web-Interface konfigurieren dürfen: HeaderRemove = zu entfernende Kopfzeilen HeaderAdd = hinzuzufügende Kopfzeilen MimeRemove = Nachrichtenbestandteile dieses Typs werden entfernt @@ -182,12 +186,13 @@ Lang { ConfigAdmin = Fern-AdministratorInnen sind (per Voreinstellung) auch ModeratorInnen für die Einschreibung und für eingesandte Mails. Sie können berechtigt sein, per Mail Nutzer ein- und auszutragen, sowie Textbausteine zu verändern. ConfigArchive = Das Mailinglisten-Archiv ist per Mail verfügbar. Außerdem benötigst du ein Archiv, falls du vergangene Mails im Internet zur Verfügung stellen möchtest (z.B. mit ezmlm-www). ConfigProcess = Die folgenden Regeln werden auf alle Mails angewandt, bevor sie an die AbonnentInnen verteilt werden. - ConfigMain = Die allgemeinen Eigenschaften bestimmen einige wichtige Verhaltensweisen der Mailingliste. - ConfigPosting = Die Einsende-Konfiguration bestimmt, wer Nachrichten einsenden darf und wie diese Mails verarbeitet werden sollen. + ConfigMain = Hier findest du ein paar allgemeine Einstellungen der Mailingliste, die sich nicht in den themenorientierten Rubriken unterbringen ließen. + ConfigPosting = Die Einsende-Konfiguration bestimmt, wer Nachrichten einsenden darf und welchen Bedingungen die Mails genügen müssen. ConfigSub = Hier kannst du festlegen, wer sich als Abonnent selbständig eintragen darf und wie der Einschreibungsprozess abläuft. + ConfigAll = Diese Seite enthält alle verfügbaren Optionen auf einen Blick. ListDelete = Die Mailingliste und alle damit verbundenen Daten werden hiermit vollständig entfernt. - AllowList = An die Adressen der Zulassungsliste werden keine Mails verschickt. Einsendungen durch diese Adressen werden so behandelt, als kämen sie von AbonnentInnen. Üblicherweise werden Aliase von AbonnentInnen in die Zulassungsliste eingetragen. - DenyList = Falls du Mails von bestimmte Mailadressen verweigern möchtest, dann füge sie einfach zur (aktivierten) Ablehnungsliste hinzu Dies kann nützlich sein, um unbeliebte Nutzer auszuschließen oder um störende Abwesenheitsbenachrichtigungen zu verhindern. + AllowList = An die Adressen der Zulassungsliste werden keine Mails verschickt. Einsendungen von diesen Adressen werden so behandelt, als kämen sie von AbonnentInnen. Üblicherweise solltest du Aliase von AbonnentInnen in die Zulassungsliste eintragen. + DenyList = Falls du Mails von bestimmte Mailadressen verweigern möchtest, dann füge sie einfach zur Ablehnungsliste hinzu Dies kann nützlich sein, um unbeliebte Nutzer auszuschließen oder um störende Abwesenheitsbenachrichtigungen zu verhindern. DigestList = Einige AbonnentInnen deiner Mailingliste sind möglicherweise nicht an jeder einzelnen Nachricht interessiert, sondern ziehen es vor, stattdessen regelmäßig automatisch erstellte Zusammenfassungen zu erhalten. ModList = ModeratorInnen (für die Einschreibung von AbonnentInnen und die Einsendungen an die Liste) und Fern-AdministratorInnen können die Kontrolle über viele wichtige Aspekte der Liste übernehmen (falls du sie dementsprechend konfigurierst). SubscriberList = Die AbonnentInnen der Mailingliste empfangen alle versandten Nachrigten der Liste. Zudem kann es ihnen gestattet sein, Nachrichten direkt oder indirekt zur weiteren Verteilung an die Liste zu senden. Oft ist es anonymen Nutzern gestattet, sich selbständig in die Mailingliste einzuschreiben, ohne die Hilfe eines Administrators in Anspruch nehmen zu müssen. @@ -202,6 +207,7 @@ Lang { ConfigSub = Einschreibungsdetails ConfigMain = Allgemeine Listen-Einstellungen ConfigProcess = Verarbeitungsregeln + ConfigAll = Einstellungen ListCreate = Eigenschaften der neuen Liste ListDelete = Löschung der Mailingliste RelevantOptions = Relevante Optionen diff --git a/ezmlm-web-3.0/lang/en.hdf b/ezmlm-web-3.0/lang/en.hdf index 6709c5a..2479982 100644 --- a/ezmlm-web-3.0/lang/en.hdf +++ b/ezmlm-web-3.0/lang/en.hdf @@ -18,6 +18,7 @@ Lang { ConfigAdmin = administration ConfigArchive = archive ConfigProcess = processing + ConfigAll = overview TextFiles = Text files ListSelect = Choose a list Properties = Properties of @@ -32,6 +33,7 @@ Lang { ConfigAdmin = Remote administration ConfigArchive = Archive options ConfigProcess = Message processing + ConfigAll = Complete configuration SubscriberList = Subscribers of the list AllowList = Allowed users DenyList = Blocked users @@ -62,6 +64,7 @@ Lang { Forbidden = Error: you are not allowed to do this! ListDirUnavailable = Could not create the list directory! InvalidFileName = The name of the file is invalid! + UnknownConfigPage = The chosen config page is invalid! } @@ -72,7 +75,8 @@ Lang { DeleteList = Removal of mailing list failed! UpdateConfig = Update of configuration failed! SaveFile = The file could not be saved! - ListAlreadyExists = There is already a list with this name! + ListNameAlreadyExists = There is already a list with this name! + ListAddressAlreadyExists = There is already a list with this address! ListDoesNotExist = A list with this name does not exist! ListDirAccessDenied = Unable to access the list's directory: TextDirAccessDenied = Unable to access the list's directory of text files: @@ -147,7 +151,7 @@ Lang { ListName = List Name ListAddress = List Address ListOptions = Basic List Options - AllowedToEdit = Users allowed to edit this list via web interface + AllowedToEdit = Users allowed to edit this list via web interface: HeaderRemove = Headers to strip from all outgoing mail HeaderAdd = Headers to add to all outgoing mail MimeRemove = Mime types to strip from all outgoing mail @@ -183,9 +187,10 @@ Lang { ConfigAdmin = Remote administrators are (by default) also moderators for subscription and for posting. They may have the permission to (un)subscribe users and to change the text files of the list by sending emails to the mailing list software. ConfigArchive = The mailing list archive can be accessed by mail. Additionally you will want to create a list archive, if you plan to publish it (e.g. with ezmlm-www). ConfigProcess = Modify some message properties, before they are distributed to the subscribers. - ConfigMain = The basic properties of a list define some important settings (e.g. mail address) and the general behaviour (public or closed). + ConfigMain = Here you find some settings, that did not fit into any other category. ConfigPosting = The posting configuration determines, who is allowed to send messages to the list and how these mails will be processed. ConfigSub = Here you may define, who is allowed to subscribe to the list and you can set some details of the subscription process. + ConfigAll = This is the complete list of all available properties of the list. Usually it should be easier to use the topic-based configuration pages, but - of course - this is your choice. ListDelete = This mailinglist and everything inside of it will be removed completely. AllowList = Members of the allow list will not receive outgoing mails, but they have the same rights, as normal subscribers. Usually the allow list will contain mail aliases of subscribers. DenyList = If you want to prevent specific mail addresses from using this list (subscription, posting, ...), then you should add them to the deny list and activate it. This can be useful for annoying people and even for notorious vacation reply users. But since it is fairly easy to fake an mail address, this will not really improve security. @@ -203,6 +208,7 @@ Lang { ConfigSub = Subscription details ConfigMain = General list configuration ConfigProcess = Processing rules + ConfigAll = Available properties ListCreate = Properties of the new list ListDelete = Remove this mailinglist RelevantOptions = Useful settings diff --git a/ezmlm-web-3.0/template/config_all.cs b/ezmlm-web-3.0/template/config_all.cs new file mode 100644 index 0000000..bf746df --- /dev/null +++ b/ezmlm-web-3.0/template/config_all.cs @@ -0,0 +1,163 @@ +
+

+
+ +
+

+
+ +
+ + +
+ + +
    + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • + + + +
  • + + +
  • + + +
  • + + +
  • + + +
  • +
    • +
  • + + +
  • + + +
    • +
  • + + +
  • 0 ?>checked="checked" /> + +
  • +
  • 0 ?>checked="checked" /> + +
  • + + +
  • +
      + +
    • :
      +
    • +
    • :
      +
    • +
  • + + +
  • :
    +
  • + + +
  • :
    +
  • + + + +
  • +

    • +
  • + +
  • + + + +
  • +
+ +
+
+ diff --git a/ezmlm-web-3.0/template/config_main.cs b/ezmlm-web-3.0/template/config_main.cs index 8723fa6..f145982 100644 --- a/ezmlm-web-3.0/template/config_main.cs +++ b/ezmlm-web-3.0/template/config_main.cs @@ -14,8 +14,11 @@