Bugtraq mailing list archives

Re: mail storm


From: darrell () teleport com (Darrell Fuhriman)
Date: Tue, 13 Aug 1996 16:55:55 -0700


At least 1 major mailing list package (LSoft Inc's ListServ) has an option
to "confirm" subscriptions.  If you try to subscripe, Listserv sends back
a "magic cookie" 5-digit random number, and you have to send back a second
'OK that_number' to actually complete the subscription (Listserv is very

We have a similar patch to Majordomo that we wrote back when this whole mess
started in earnest.  It's cut down on our problems with this dramatically
(we have about 600 mailing lists.)

BTW, this fix has been included in the recent majordomo alphas.

Anyway, you need to set the list type to "confirm", the next release of
majordomo will have this as "open+confirm" and "closed+confirm" instead.

Darrell Fuhriman

*** majordomo   Wed May 10 05:11:24 1995
--- /home/majordomo/majordomo   Mon Jun 10 13:40:31 1996
***************
*** 168,173 ****
--- 168,174 ----
      elsif ($cmd eq "help") { &do_help(@parts); }
      elsif ($cmd eq "get") { &do_get(@parts); }
      elsif ($cmd eq "index") { &do_index(@parts); }
+     elsif ($cmd eq "auth") { &do_auth(@parts); }
      else {
        &squawk("Command '$cmd' not recognized.");
        $count--;       # if we get to here, it wasn't really a command
***************
*** 215,221 ****
        #    subscriber is the person making the request
        if ($approved
            || ($config_opts{$clean_list,"subscribe_policy"} eq "auto" )
!           || (($config_opts{$clean_list,"subscribe_policy"} ne "closed" )
                &&  &addr_match($reply_to, $subscriber,
                (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef)))) {
            # Either the request is approved, or the list is open and the
--- 216,224 ----
        #    subscriber is the person making the request
        if ($approved
            || ($config_opts{$clean_list,"subscribe_policy"} eq "auto" )
!           || (($config_opts{$clean_list,"subscribe_policy"} eq "confirm")
!               && (&gen_cookie($sm, $clean_list, $subscriber) eq $auth_info))
!           || (($config_opts{$clean_list,"subscribe_policy"} eq "open" )
                &&  &addr_match($reply_to, $subscriber,
                (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef)))) {
            # Either the request is approved, or the list is open and the
***************
*** 290,295 ****
--- 293,300 ----
        # unsubscribe themselves without the owner's approval).
        if ($approved
            || ($config_opts{$clean_list,"subscribe_policy"} eq "auto" )
+           || (($config_opts{$clean_list,"subscribe_policy"} eq "confirm")
+               && (&gen_cookie($sm, $clean_list, $subscriber) eq $auth_info))
            || &addr_match($reply_to, $subscriber,
                (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) {
            # Either the request is approved, or the subscriber is the
***************
*** 323,330 ****
                unlink("$listdir/$clean_list.old");
                print REPLY "Succeeded.\n";
                &log("unsubscribe $clean_list $subscriber");
                &sendmail(BYE, "$clean_list-approval",
!                   "UNSUBSCRIBE $clean_list");
                print BYE "$subscriber has unsubscribed from $clean_list.\n";
                print BYE "No action is required on your part.\n";
                close(BYE);
--- 328,336 ----
                unlink("$listdir/$clean_list.old");
                print REPLY "Succeeded.\n";
                &log("unsubscribe $clean_list $subscriber");
+               local($addr) = &valid_addr($subscriber);
                &sendmail(BYE, "$clean_list-approval",
!                   "UNSUBSCRIBE $clean_list $addr");
                print BYE "$subscriber has unsubscribed from $clean_list.\n";
                print BYE "No action is required on your part.\n";
                close(BYE);
***************
*** 345,350 ****
--- 351,361 ----
      }
  }

+ sub do_auth {
+     # Check to see we've got all the arguments
+     ($auth_info = shift)      || &squawk("auth: needs key");
+ }
+
  sub do_approve {
      # Check to see we've got all the arguments
      (local($passwd) = shift)  || &squawk("approve: needs passwd");
***************
*** 1132,1137 ****
--- 1143,1199 ----
      &log("help");
  }

+ sub send_confirm {
+     local($cmd) = shift;
+     local($list) = &valid_list($listdir, shift);
+     local($subscriber) = @_;
+     local($cookie) = &gen_cookie($cmd, $list, $subscriber);
+       local(*AUTH);
+
+       &sendmail(AUTH, $subscriber, "Confirmation for $cmd $list");
+
+       print AUTH <<"EOM";
+ Someone (possibly you) has requested that your email address be added
+ to or deleted from the mailing list "$list\@$whereami".
+
+ If you really want this action to be taken, please send the following
+ commands (exactly as shown) back to "$whoami":
+
+       auth $cookie
+       $cmd $list $subscriber
+
+ If you do not want to this action taken, just ignore this message and
+ no action will be taken.
+
+ If you have any questions about the policy of the list owner, please
+ contact "$list-approval@$whereami".
+
+ Thanks!
+
+ $whoami
+ EOM
+       close(AUTH);
+
+     print REPLY <<"EOM";
+ Your request to $whoami:
+
+       $cmd $list $subscriber
+
+ must be authenticated.  To accomplish this, another request must be
+ sent in with an authorization key, which has been sent to:
+       $subscriber
+
+ If you have any questions about the policy of the list owner, please
+ contact "$list-approval@$whereami".
+
+ Thanks!
+
+ $whoami
+ EOM
+     &log("send_confirm $cmd $list $subscriber");
+ }
+
+
  # Send a request for subscribe or unsubscribe approval to a list owner
  # Usage: &request_approval($cmd, $list, @subscriber)
  sub request_approval {
***************
*** 1213,1219 ****

      # delete all the temporary files; do it this long ugly way
      # because of a bug in PERL filename globbing
!     $_ = `echo $tmp.*`;
      $_ = &chop_nl($_);
      foreach (split(" ", $_)) {
        unlink($_) || warn("Can't unlink $_: $!") if ! /\*$/;
--- 1275,1281 ----

      # delete all the temporary files; do it this long ugly way
      # because of a bug in PERL filename globbing
!     $_ = `echo $tmp/majordomo.$$.*`;
      $_ = &chop_nl($_);
      foreach (split(" ", $_)) {
        unlink($_) || warn("Can't unlink $_: $!") if ! /\*$/;
***************
*** 1281,1287 ****
      close(MSG);

      # tell the list owner of the new subscriber
!     &sendmail(NOTICE, "$list-approval", "SUBSCRIBE $list");
      print NOTICE "$subscriber has been added to $list.\n";
      print NOTICE "No action is required on your part.\n";
      close(NOTICE);
--- 1343,1350 ----
      close(MSG);

      # tell the list owner of the new subscriber
!     local($addr) = &valid_addr($subscriber);
!     &sendmail(NOTICE, "$list-approval", "SUBSCRIBE $list $addr");
      print NOTICE "$subscriber has been added to $list.\n";
      print NOTICE "No action is required on your part.\n";
      close(NOTICE);
***************
*** 1318,1324 ****
--- 1381,1403 ----
  request, the part after the list name is optional, but if it's there, it
  should be an email address, NOT a person's real name.
  EOM
+     } elsif ($config_opts{$clean_list,"subscribe_policy"} eq "confirm") {
+       &send_confirm($request, $clean_list, $subscriber);
      } else {
        &request_approval($request, $clean_list, $subscriber);
      }
+ }
+
+ sub gen_cookie {
+     local($combined) = join('/', @_);
+     local($cookie) = $cookie_seed;
+     local($i, $carry);
+
+     for ($i = 0; $i < length($combined); $i++) {
+       $cookie ^= ord(substr($combined, $i));
+       $carry = ($cookie >> 28) & 0xf;
+       $cookie <<= 4;
+       $cookie |= $carry;
+     }
+     return (sprintf("%08x", $cookie));
  }



Current thread: