Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Jun 2001 01:37:26 +0300 (EEST)
From:      Valentin Nechayev <netch@netch.kiev.ua>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   ports/28282: secure majordomo install
Message-ID:  <200106192237.f5JMbQ108569@iv.nn.kiev.ua>

next in thread | raw e-mail | index | archive | help

>Number:         28282
>Category:       ports
>Synopsis:       secure majordomo install
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 19 15:40:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Valentin Nechayev <netch@netch.kiev.ua>
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
home sweet home
>Environment:
FreeBSD 4 or 5

>Description:

Current majordomo (ports/mail/majordomo) setup is very insecure:
1. local users can run arbitrary commands as the majordomo user.
2. Cookie mechanism is weak and isn't properly set up.
3. Unsubscribe requests are not checked properly (with cookies)
except some rare cases.

Following patch is written to deal with these problems.

>How-To-Repeat:

>Fix:

This patch provides a bunch of fixes:

1. Wrapper program is installed suid:majordom instead of suid:root.
This change even can be separated from all another changes in this patch:
the only wrapper function is to set uids & gids to values defined at
compile time and call core perl scripts; it works also well with suid:majordom,
and there is none need to give it high privileges.
Change in: files/patch-aa (patch to Makefile).

2. Wrapper is set with mode 4550, i.e. arbitrary users cannot execute it,
only majordom user and majordom group has rights to execute it.
This requires (in default FreeBSD setup) that daemon (uid=1)
is included to majordom group, in order to allow execute the wrapper
from pipe listed directly in /etc/mail/aliases (sendmail runs such
programs with uid=1 and groups inited).
>Release-Note:
>Audit-Trail:
>Unformatted:
 >> NOTE: this won't work if pipes from /etc/mail/aliases were run with another
 uid, or if MTA weren't call initgroups(). Sendmail does execute needed
 steps, another MTA can have problems.
 Changes in: scripts/createuser - add daemon to majordom group
             Makefile - don't pop useless warning dialog up
 
 3. Cookie mechanism is strenghened. To generate per-command cookie,
 MD5 is used instead of old easy-faked CRC. For this, a little Perl module
 Digest::MD5 is required.
 Changes in: Makefile (RUN_DEPENDS)
             patch-bf (patch to majordomo)
 
 4. For cookie challenge authentication, a seed is generated during install
 and put to majordomo.cf. Old behavior is to use easy-guessed value
 (majordomo home directory).
 Changes in: Makefile (call scripts/makeseed)
             scripts/makeseed - added
 
 5. To unsubscribe from list, request authentication via cookie challenge
 is requested. Old behaviour is to believe if subscriber address equals
 to requester address, which is too easy to fake.
 Change in: patch-bf (patch to majordomo)
 
 diff -rNu 0/Makefile 1/Makefile
 --- 0/Makefile	Tue Jun 19 00:06:52 2001
 +++ 1/Makefile	Wed Jun 20 01:01:13 2001
 @@ -7,10 +7,12 @@
  
  PORTNAME=	majordomo
  PORTVERSION=	1.94.5
 +PORTREVISION=	1
  CATEGORIES=	mail
  MASTER_SITES=	ftp://ftp.greatcircle.com/pub/majordomo/1.94.5/ \
  		ftp://ftp.sgi.com/other/majordomo/1.94.5/
  EXTRACT_SUFX=   .tgz
 +RUN_DEPENDS=	${LOCALBASE}/lib/perl5/site_perl/${PERL_VER}/mach/Digest/MD5.pm:${PORTSDIR}/security/p5-Digest-MD5
  
  MAINTAINER=	ports@FreeBSD.org
  
 @@ -22,17 +24,15 @@
  MAN1=		approve.1 bounce-remind.1 digest.1
  MAN8=		majordomo.8
  
 -pre-fetch:
 -.if !defined(BATCH) && !defined(PACKAGE_BUILDING)
 -	/usr/bin/dialog --yesno "Majordomo is unsafe to use on multi-user machines: local users can run arbitrary commands as the majordomo user. Do you wish to accept the security risk and build majordomo anyway?" 8 60 || ${FALSE}
 -.endif
 -
  pre-configure:
  		@ ${SETENV} ${MAKE_ENV} /usr/bin/perl ${SCRIPTDIR}/createuser
  		@ ${CP} ${FILESDIR}/aliases.majordomo ${WRKSRC}
  
  pre-install:
 -		@ ${CP} ${WRKSRC}/sample.cf ${WRKSRC}/majordomo.cf
 +		@ if test -f ${WRKSRC}/majordomo.cf; then :; else \
 +			${CP} ${WRKSRC}/sample.cf ${WRKSRC}/majordomo.cf; \
 +			/usr/bin/perl ${SCRIPTDIR}/makeseed ${WRKSRC}/majordomo.cf; \
 +		fi
  
  post-install:
  .for file in ${MAN1}
 diff -rNu 0/files/patch-aa 1/files/patch-aa
 --- 0/files/patch-aa	Mon Jul 12 07:09:14 1999
 +++ 1/files/patch-aa	Wed Jun 20 00:22:09 2001
 @@ -1,5 +1,5 @@
 ---- Makefile.orig	Wed Aug 27 08:56:21 1997
 -+++ Makefile	Sat Jul 10 23:28:11 1999
 +--- Makefile.orig	Tue Jan 18 16:01:17 2000
 ++++ Makefile	Wed Jun 20 00:20:35 2001
  @@ -13,22 +13,22 @@
   #
    
 @@ -28,6 +28,18 @@
   
   # These set the permissions for all installed files and executables (except
   # the wrapper), respectively.  Some sites may wish to make these more
 +@@ -40,9 +40,9 @@
 + # If your system is POSIX (e.g. Sun Solaris, SGI Irix 5 and 6, Dec Ultrix MIPS,
 + # BSDI or other 4.4-based BSD, Linux) use the following four lines.  Do not
 + # change these values!
 +-WRAPPER_OWNER = root
 ++WRAPPER_OWNER = $(W_USER)
 + WRAPPER_GROUP = $(W_GROUP)
 +-WRAPPER_MODE = 4755
 ++WRAPPER_MODE = 4550
 + POSIX = -DPOSIX_UID=$(W_USER) -DPOSIX_GID=$(W_GROUP)
 + # Otherwise, if your system is NOT POSIX (e.g. SunOS 4.x, SGI Irix 4,
 + # HP DomainOS) then comment out the above four lines and uncomment
  @@ -62,11 +62,11 @@
   # parent process, and without the leading "W_" in the variable names) gets
   # passed to processes run by "wrapper"
 diff -rNu 0/files/patch-bf 1/files/patch-bf
 --- 0/files/patch-bf	Wed Sep 10 05:52:53 1997
 +++ 1/files/patch-bf	Wed Jun 20 00:14:32 2001
 @@ -1,6 +1,14 @@
 ---- majordomo.orig	Wed Aug 27 23:55:29 1997
 -+++ majordomo	Wed Sep 10 00:57:24 1997
 -@@ -75,7 +75,7 @@
 +--- majordomo.orig	Thu Jan 13 19:29:31 2000
 ++++ majordomo	Wed Jun 20 00:13:16 2001
 +@@ -64,6 +64,7 @@
 + require "majordomo.pl";		# all sorts of general-purpose Majordomo subs
 + require "shlock.pl";		# NNTP-style file locking
 + require "config_parse.pl";	# functions to parse the config files
 ++use Digest::MD5 qw( md5_hex );
 + 
 + print STDERR "$0:  requires succeeded.  Setting defaults.\n" if $DEBUG; 
 + 
 +@@ -75,7 +76,7 @@
   # Define all of the mailer properties:
   # It is possible that one or both of $sendmail_command and $bounce_mailer
   # are not defined, so we provide reasonable defaults.
 @@ -9,3 +17,29 @@
     unless defined $sendmail_command;
   $bounce_mailer = "$sendmail_command -f\$sender -t"
     unless defined $bounce_mailer;
 +@@ -405,9 +406,6 @@
 + 	# making the request. 
 + 	#
 + 	if (! $approved
 +-	    && ! ((&addr_match($reply_to, $subscriber,
 +-			       (&cf_ck_bool($clean_list,"mungedomain")
 +-				? 2 : undef))))
 + 	    && (($unsub_policy =~ /confirm/)
 + 		&& (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) 
 + 	  { 
 +@@ -1906,14 +1904,7 @@
 +     # Because of backslashing and all of the splitting on whitespace and
 +     # joining that goes on, we need to ignore whitespace.
 +     $combined =~ s/\s//g;
 +-    
 +-    for ($i = 0; $i < length($combined); $i++) {
 +-	$cookie ^= ord(substr($combined, $i));
 +-	$carry = ($cookie >> 28) & 0xf;
 +-	$cookie <<= 4;
 +-	$cookie |= $carry;
 +-    }
 +-    return (sprintf("%08x", $cookie));
 ++    return md5_hex( $combined );
 + }
 + 
 + 
 diff -rNu 0/scripts/createuser 1/scripts/createuser
 --- 0/scripts/createuser	Mon Nov  9 03:09:25 1998
 +++ 1/scripts/createuser	Wed Jun 20 00:32:46 2001
 @@ -59,3 +59,11 @@
  	print "Failed to add/modify user majordom!\n";
  	exit 1;
  }
 +
 +## Add daemon to majordom group, to allow sendmail to call wrapper
 +## via direct pipes in /etc/mail/aliases
 +$result = system( "pw groupmod majordom -m daemon" );
 +if( $result ) {
 +	print "Failed to add/modify user majordom!\n";
 +	exit 1;
 +}
 diff -rNu 0/scripts/makeseed 1/scripts/makeseed
 --- 0/scripts/makeseed	Thu Jan  1 03:00:00 1970
 +++ 1/scripts/makeseed	Wed Jun 20 00:54:56 2001
 @@ -0,0 +1,14 @@
 +#!/usr/bin/perl
 +my $file = $ARGV[0];
 +my $seed = '';
 +my $i;
 +my $patt = "./0123456789abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM";
 +die unless $file;
 +srand;
 +for( $i = 1; $i <= 40; $i++ ) {
 +   $seed = $seed . substr( $patt, int( rand() * 64 ), 1 );
 +}
 +open OUT, ">>$file" || die "Cannot open output file";
 +print OUT "\n## Set cookie_seed to value generated during install\n";
 +printf OUT '$cookie_seed="%s";'."\n", $seed;
 +close( OUT );

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200106192237.f5JMbQ108569>