Great Circle Associates Majordomo-Workers
(March 1996)
 

Indexed By Date: [Previous] [Next] Indexed By Thread: [Previous] [Next]

Subject: Re: Cascading help messages loop
From: Joe Pruett <joey @ teleport . com>
Date: Mon, 11 Mar 1996 09:55:54 -0800
To: michele @ garnet . berkeley . edu, majordomo-workers @ greatcircle . com, Brent @ GreatCircle . COM

> How about this: start with the user's one-line request.  Append the user's
> email address, if they haven't already specified it on the request.
> Normalize it by stripping comments out of email address, stripping multiple
> whitespace, converting to all lower-case, etc.  Append or prepend a
> site-specific "secret" from the /etc/majordomo.cf file.  Run this whole
> line through MD5 or SNEFRU or some other crypto-checksum function; use the
> result of that as the verification cookie the user has to return, as
> Michele describes above.
> 
> As long as your site's secret is still the same when the user sends back
> the verification, it's easy to verify the cookie.  However, there's no good
> way for an attacker to figure out what you're site's secret is except by
> brute force; if you choose a good secret (like choosing a good password),
> that should be very difficult.
> 
> So, anybody got a version of MD5 or SNEFRU implemented in Perl?  :-)
> 


this has already been implemented by me (but with just a simple checksum,
not md5) and submitted to you guys.  i was told it would be in the next
release, but i haven't seen any sign of that.

for the brave at heart, here are some diffs that should work for people.
just add $cookie_seed to majordomo.cf with an 8 digit hex number (the
"secret").
----
diff -c ./config_parse.pl /home/majordomo/config_parse.pl
*** ./config_parse.pl	Sat Jan  7 09:30:56 1995
--- /home/majordomo/config_parse.pl	Tue Jan  9 13:46:19 1996
***************
*** 86,92 ****
          'noadvertise',		'', # if regexp matches address 
  					# don't show list
  	'description',		'', # description of list, one line 55 char 
!         'subscribe_policy',	"open\001closed\001auto\001open",
  					 # open, closed, or auto.
          'mungedomain',		'no', # is user@foo.com == user@host.foo.com
          'admin_passwd',		'#!$list.".admin"',   # administration password
--- 86,92 ----
          'noadvertise',		'', # if regexp matches address 
  					# don't show list
  	'description',		'', # description of list, one line 55 char 
!         'subscribe_policy',	"open\001closed\001auto\001confirm\001open",
  					 # open, closed, or auto.
          'mungedomain',		'no', # is user@foo.com == user@host.foo.com
          'admin_passwd',		'#!$list.".admin"',   # administration password
***************
*** 181,194 ****
  characters.",
  
  'subscribe_policy', 
! "One of 3 possible values: open, closed, auto.  Open allows people to
! subscribe themselves to the list. Auto allows anybody to subscribe
! anybody to the list without maintainer approval. The existence of the
! file <listname>.auto is the same as specifying the value auto.  Closed
! requires maintainer approval for all subscribe requests to the
! list. In addition to the keyword, if the file <listname>.closed
! exists, it is the same as specifying the value closed. The value of
! this keyword overrides the value supplied by any existent files.",
  
  'mungedomain', 
  "If set to yes, a different method is used to determine a matching
--- 181,197 ----
  characters.",
  
  'subscribe_policy', 
! "One of 4 possible values: open, closed, auto, confirm.  Open allows
! people to subscribe themselves to the list. Auto allows anybody to
! subscribe anybody to the list without maintainer approval. The
! existence of the file <listname>.auto is the same as specifying the
! value auto.  Closed requires maintainer approval for all subscribe
! requests to the list. In addition to the keyword, if the file
! <listname>.closed exists, it is the same as specifying the value
! closed.  Confirm causes majordomo to send a reply back to the
! subscriber which includes a authentication number which must
! be sent back in with another subscribe commad.  The value of this
! keyword overrides the value supplied by any existent files.",
  
  'mungedomain', 
  "If set to yes, a different method is used to determine a matching
diff -c ./majordomo /home/majordomo/majordomo
*** ./majordomo	Wed May 10 05:11:24 1995
--- /home/majordomo/majordomo	Mon Jan  8 17:32: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
***************
*** 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 {
***************
*** 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));
  }

Indexed By Date Previous: Re: Cascading help messages loop
From: Dave Wolfe <dwolfe@risc.sps.mot.com>
Next: Re: Cascading help messages loop
From: Brent@GreatCircle.COM (Brent Chapman)
Indexed By Thread Previous: Re: Cascading help messages loop
From: Dave Wolfe <dwolfe@risc.sps.mot.com>
Next: Re: Cascading help messages loop
From: Brent@GreatCircle.COM (Brent Chapman)

Google
 
Search Internet Search www.greatcircle.com