Bugtraq mailing list archives
Re: Security hole in mgetty+sendfax
From: gert () GREENIE MUC DE (Gert Doering)
Date: Fri, 25 Jul 1997 10:14:37 +0200
-----BEGIN PGP SIGNED MESSAGE----- Hi, Gert Doering wrote:
[Mgetty+sendfax security problem]
begin 644 faxq+faxrunq.tar.gz
Well... some minor points: - - this is not releated to the "Hylafax" (formerly FlexFax) package. Hylafax has a "faxq" program as well, but it works completely different and is not affected. - - the URL for mgetty is http://www.leo.org/~doering/mgetty/, but the patch is not yet there (weekend). - - somehow the uuencode'd file got corrupted traversing bugtraq's relay mailer [linux-security got it correctly], so I'll append it again, as a "shar" archive. gert #!/bin/sh # This is a shell archive (produced by shar 3.52.3) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # # made 07/25/1997 07:55 UTC by gert@greenie # Source directory /u/gert/src/mgetty/fax # # existing files will NOT be overwritten unless -c is specified # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 3507 -rw-r--r-- faxq # 8247 -rw-r--r-- faxrunq # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo 'WARNING: not restoring timestamps' fi rm -f 1231235999 $$.touch # # ============= faxq ============== if test -f 'faxq' && test X"$1" != X"-c"; then echo 'x - skipping faxq (File already exists)' else echo 'x - extracting faxq (Text)' sed 's/^X//' << 'SHAR_EOF' > 'faxq' && #!/bin/sh # # faxq program # # like "lpq" or "mailq", show jobs waiting in the output queue # # SCCS: @(#)faxq.in 4.3 97/07/24 Copyright (C) 1994 Gert Doering # FAX_SPOOL=/usr/spool/fax FAX_SPOOL_OUT=/usr/spool/fax/outgoing X # # echo program that will accept escapes (bash: "echo -e", sun: /usr/5bin/echo) # echo="echo" X # # an awk that is not stone-old-brain-dead (that is, not oawk...) # AWK=awk X if cd $FAX_SPOOL_OUT then: else X $echo "cannot chdir to $FAX_SPOOL_OUT..." >&2 X exit 1 fi X jobs="*/JOB" requeue="" X for flag do X case $flag in X -v) verbose="true" ;; X -o) jobs="*/JOB.done" ;; X -s) jobs="*/JOB.s*" ;; X -a) jobs="*/JOB*" ;; X -r) jobs="*/JOB.s*"; requeue="true" ;; X *) cat <<EOF_MSG >&2 $0: invalid option: $flag valid options: X -o: show old jobs X -s: show suspended jobs X -a: show all jobs X -v: verbose output X -r: restart suspended jobs EOF_MSG X exit 1 ;; X esac done X jobs=`ls $jobs 2>/dev/null` [ -z "$jobs" ] && $echo "no jobs." for i in $jobs do X USER=""; PHONE=""; PAGES=""; MAILTO=""; VERBTO=""; X ACCT=""; INPUT=""; PRI=""; RE="" X X if [ -z "$verbose" ] X then X eval `tr -d '\042\047\140\134\044\073' <$i | \ X $AWK '$1=="user" { printf "USER=%s;", $2 } X $1=="phone" { printf "PHONE=%s;", $2 } X $1=="pages" { printf "PAGES=%d;", NF-1 } X $1=="priority" { printf "PRI=\" pri=%s.\"", $2}' -` X $echo "$i: queued by $USER. $PAGES page(s) to $PHONE.$PRI" X else X eval `tr -d '\042\047\140\134\044\073' <$i | \ X $AWK '$1=="user" { printf "USER=%s;", $2 } X $1=="mail" { printf "MAILTO=\"%s\";", substr( $0, 6 ) } X $1=="phone" { printf "PHONE=%s;", $2 } X $1=="verbose_to" \ X { printf "VERBTO=\"%s\";", substr( $0, 12 ) } X $1=="acct_handle" \ X { printf "ACCT=\"%s\";", substr( $0, 13 ) } X $1=="input" { printf "INPUT=\"%s\";", substr( $0, 7 ) } X $1=="time" { printf "TIME=\"%s:%s\";", X substr( $0, 6, 2 ), substr( $0, 8,2 ) } X $1=="subject"{ printf "RE=\"%s\";", substr( $0, 9 ) } X $1=="priority"{ printf "PRI=\"%s\";", $2 } X $1=="pages" { if ( NF==2 ) printf "PAGES=\"%s\";", $2 X else if ( NF==3 ) X printf "PAGES=\"%s %s\";", $2, $3 X else X printf "PAGES=\"%s ... %s\";", $2, $NF X }' -` X $echo "$i:" X $echo "\tQueued by: $USER" X if [ -z "$VERBTO" ] X then X $echo "\t to: $PHONE" X else X $echo "\t to: $VERBTO ($PHONE)" X fi X test ! -z "$RE" && \ X $echo "\t Re: $RE" X test ! -z "$MAILTO" && \ X $echo "\t E-Mail: $MAILTO" X test ! -z "$INPUT" && \ X $echo "\t Input: $INPUT" X $echo "\t Pages: $PAGES" X test ! -z "$TIME" && \ X $echo "\tSend time: $TIME" X test ! -z "$ACCT" && \ X $echo "\tAcct info: $ACCT" X test ! -z "$PRI" && \ X $echo "\t Priority: $PRI" X X sed -e '/Status/!d' -e 's/Status/ Status:/' $i X if [ -f "$i.locked" ] ; then X $echo "\t Status: LOCKED (being sent right now)" X else X expr $i : ".*done$" >/dev/null || X $echo "\t Status: not sent yet" X fi X fi X # if "requeue", requeue *.suspended-Jobs X if [ -n "$requeue" ] && expr "$i" : ".*JOB.s" >/dev/null X then X d=`dirname $i` X if [ ! -w $d ] ; then X $echo "$i: not owner, can't restart" X else X $echo "Status "`date`" - reactivated by $LOGNAME" >>$i X mv $i $d/JOB X fi X fi X done X test -n "$verbose" -a -n "$jobs" -a -r .last_run && X $echo "\nLast \`\`faxrunq'' run at: `cat .last_run`" X SHAR_EOF $shar_touch -am 0724205497 'faxq' && chmod 0644 'faxq' || echo 'restore of faxq failed' shar_count="`wc -c < 'faxq'`" test 3507 -eq "$shar_count" || echo "faxq: original size 3507, current size $shar_count" fi # ============= faxrunq ============== if test -f 'faxrunq' && test X"$1" != X"-c"; then echo 'x - skipping faxrunq (File already exists)' else echo 'x - extracting faxrunq (Text)' sed 's/^X//' << 'SHAR_EOF' > 'faxrunq' && #!/bin/sh # # faxrunq # # look for outgoing fax jobs, send them via sendfax, if succesful, remove # them from the outgoing queue (and send a mail to the originator of the # job) # # There are still a lot rough edges - but it works, and should give you an # idea how to improve it # # SCCS: @(#)faxrunq.in 4.3 97/07/24 Copyright (C) 1994 Gert Doering X FAX_SPOOL=/usr/spool/fax FAX_SPOOL_OUT=/usr/spool/fax/outgoing FAX_SENDER="/usr/local/sbin/sendfax" FAX_ACCT=$FAX_SPOOL/acct.log X MAILER="/usr/lib/mail/execmail" X CONF_FILE="/usr/local/etc/mgetty+sendfax/faxrunq.config" X # # echo program that will accept escapes (bash: "echo -e", sun: /usr/5bin/echo) # echo="echo" X # # awk program that is not stone-old-brain-dead (that is, not oawk...) # AWK=awk X # # make sure we'll find "newslock" and other good stuff when run from "cron"... # PATH=/usr/local/bin:$PATH X # # set defaults, then process configuration file (if it exists) # do_mail_s="TRUE" do_mail_f="TRUE" exec_pgm_s="" exec_pgm_f="" max_fail_costly=5 max_fail_total=10 delete_sent="" X if [ -r $CONF_FILE ] ; then X eval `$AWK '/^ *#/ { next } X $1 == "success-send-mail" \ X { printf "do_mail_s=\"%s\";", ($2 ~ /^[yYjJtT1]/)? "T":"" } X $1 == "failure-send-mail" \ X { printf "do_mail_f=\"%s\";", ($2 ~ /^[yYjJtT1]/)? "T":"" } X $1 == "success-call-program" \ X { printf "exec_pgm_s=\"%s\";", $2 } X $1 == "failure-call-program" \ X { printf "exec_pgm_f=\"%s\";", $2 } X $1 == "maxfail-costly" && $2 ~ /^[0-9]/ \ X { printf "max_fail_costly=\"%s\";", $2 } X $1 == "maxfail-total" && $2 ~ /^[0-9]/ \ X { printf "max_fail_total=\"%s\";", $2 } X $1 == "delete-sent-jobs" \ X { printf "delete_sent=\"%s\";", ($2 ~ /^[yYjJtT1]/)? "T":"" } X END { printf "\n" }' $CONF_FILE` fi X # # command line arguments # usage="usage: $0 [-s] [-q]" X while: do X case "$1" in # sleep 30 seconds after each job, give modem time to settle X -s) sleepwait=30;shift;; # quiet operation X -q) exec >/dev/null ; shift ;; # invalid option X -*) $echo "$0: unknown option: $1" >&2 X $echo "$usage" >&2 X exit 1 X ;; X *) break X esac done X if [ $# -gt 0 ] then X $echo "$usage" >&2 X exit 1 fi X # # go to fax spool directory, process all JOB files # X cd $FAX_SPOOL_OUT || exit 1 X status="0" jobs=`ls */JOB 2>/dev/null` for job in $jobs do X if [ $status -eq 4 -a -n "$sleepwait" ] X then # old stat :no connect; modem allows next redial in $sleepwait secs X $echo "sleeping $sleepwait seconds" X sleep $sleepwait X fi X cd $FAX_SPOOL_OUT/`dirname $job` X $echo "processing $job..." # # lock JOB file (by 'link(2)'ing it to JOB.locked) # 'newslock' is a small C program that just calls link(argv[1], argv[2]) # X # make sure Lock will be removed in case the shell aborts X trap "rm -f JOB.locked 2>/dev/null" 0 X trap "rm -f JOB.locked 2>/dev/null ; exit 20" 1 2 3 15 X X newslock JOB JOB.locked 2>/dev/null X if [ $? -ne 0 ] X then X $echo "already locked" X trap 0 1 2 3 15 X continue X fi # # get user to notify (->$MAIL_TO), phone number (->$PHONE) and # earliest send time (->$TIME) # X eval `tr -d '\042\047\140\134\044\073' <JOB | \ X $AWK 'BEGIN { user=""; mail=""; verbto=""; time=""; re=""; } X $1=="user" { user=$2 } X $1=="mail" { mail=substr( $0, 6) } X $1=="phone" { printf "PHONE=%s;", $2 } X $1=="time" { time=$2 } X $1=="verbose_to" { verbto=substr($0,12) } X $1=="subject" { re=substr($0,9) } X END { if ( mail != "" ) printf "MAIL_TO=\"%s\";", mail X else printf "MAIL_TO=\"%s\";", user X printf "TIME=\"%s\";", time X printf "VERBOSE_TO=\"%s\";", verbto X printf "RE=\"%s\"", re }' - ` X # # check whether send time is reached # X if [ ! -z "$TIME" ] X then X if [ `date "+%H""%M"` -lt $TIME ] X then X $echo "...send time not reached, postponing job" X rm JOB.locked X continue X fi X fi X # # construct command line to execute # X command=`tr -d '\042\047\140\134\044\073' <JOB | \ X $AWK 'BEGIN { phone="-"; flags=""; pages="" } X $1=="phone" { phone=$2 } X $1=="header" { flags=flags" -h "$2 } X $1=="poll" { flags=flags" -p" } X $1=="normal_res" { flags=flags" -n" } X $1=="acct_handle" { flags=flags" -A \""substr($0,13)"\"" } X $1=="pages" { for( i=2; i<=NF; i++) pages=pages$i" " } X END { printf "'"$FAX_SENDER"' -v%s %s %s", \ X flags, phone, pages }' -` X # # execute faxsend command # X $echo "$command" X eval $command # # handle return values # X status=$? X $echo "command exited with status $status" X # # string to include in subject line # X if [ -z "$VERBOSE_TO" ] X then X subject="your fax to $PHONE" X else X subject="your fax to $VERBOSE_TO ($PHONE)" X fi X # # evaluate return codes, if success, remove fax job from queue # X if [ $status -eq 0 ] X then X # transmission successful X $echo "Status "`date`" successfully sent" >>JOB X X # update accounting log X $echo "$MAIL_TO $PHONE "`date`" success" >>$FAX_ACCT X X # send mail, if requested X if [ -n "$do_mail_s" ] ; then X $echo " send mail to $MAIL_TO..." X ( X trap 0 # catch BASH bug X $echo "To: $MAIL_TO" X $echo "Subject: OK: $subject" X $echo "From: root (Fax Subsystem)\n" X $echo "Your fax has been sent successfully at: \c" X date X test -z "$RE" || \ X $echo "(Subject was: $RE)\n" X $echo "\n\nJob / Log file:" X cat JOB X tries=`grep Status JOB | sed -e '1d' | wc -l` X $echo "\nSending succeeded after" $tries "unsuccessful tries." X ) | X $MAILER "$MAIL_TO" X fi X X # call "success" handler program (if requested) X if [ -n "$exec_pgm_s" ] ; then X $echo " calling program $exec_pgm_s..." X $exec_pgm_s $FAX_SPOOL_OUT/$job X fi X X # job is done -> remove it from the queue X mv JOB JOB.done X X # completely remove JOB directory (only if requested) X # instead of this, the job could be archived by "$exec_pgm_s" or so X if [ -n "$delete_sent" ] ; then X $echo " deleting job files + directory..." X cd $FAX_SPOOL_OUT X rm -rf `dirname $job` X fi X X elif [ $status -lt 10 ] X then X # error before starting to transmit (try again) X why="unknown" ; case $status in X 1) why="errors in command line" ;; X 2) why="cannot open fax device (locked?)" ;; X 3) why="modem initialization error" ;; X 4) why="dial failed - BUSY" ;; X 5) why="dial failed - NO DIALTONE" ;; X esac X $echo "Status "`date`" failed, exit($status): $why" >>JOB X else X # error while transmitting, considered fatal X why="unknown" ; case $status in X 10) why="dial failed - NO CARRIER" ;; X 11) why="protocol failure, waiting for XON" ;; X 12) why="protocol failure sending page" ;; X esac X $echo "Status "`date`" FATAL FAILURE, exit($status): $why" >>JOB X X # update accounting log X $echo "$MAIL_TO $PHONE "`date`" fail: $why" >>$FAX_ACCT X X # if failed <max_fail_costly> times, suspend job X if [ `grep "FATAL FAILURE" JOB | wc -l` -ge $max_fail_costly ] X then X $echo "Status "`date`" job suspended: too many FATAL errors" >>JOB X X # send mail, if requested X if [ -n "$do_mail_f" ] ; then X echo " send mail to $MAIL_TO..." X ( X trap 0 # catch BASH bug X $echo "To: $MAIL_TO" X $echo "Subject: FAIL: $subject failed" X $echo "From: root (Fax Subsystem)\n" X $echo "It was not possible to send your fax to $PHONE!\n" X test -z "$RE" || \ X $echo "(Subject was: $RE)\n" X $echo "The fax job is suspended, you can requeue it with the command:" X $echo " cd $FAX_SPOOL_OUT/"`dirname $job` X $echo " mv JOB.suspended JOB\n" X $echo "log file follows:" X cat JOB ) | X $MAILER "$MAIL_TO" X fi X X # call error handler, if requested X if [ -n "$exec_pgm_f" ] ; then X $echo " calling program $exec_pgm_f..." X $exec_pgm_f $FAX_SPOOL_OUT/$job X fi X X # X # suspend job (but do not delete it) X # X mv JOB JOB.suspended 2>/dev/null X fi X fi # # unlock job (even if the JOB has been renamed to JOB.suspended or # JOB.done, the link to JOB.locked still exists!) # X rm -f JOB.locked done X trap 0 1 2 3 15 X # # touch the time stamp, to make faxspool happy # rm -f $FAX_SPOOL_OUT/.last_run date >$FAX_SPOOL_OUT/.last_run chmod 644 $FAX_SPOOL_OUT/.last_run SHAR_EOF $shar_touch -am 0724205497 'faxrunq' && chmod 0644 'faxrunq' || echo 'restore of faxrunq failed' shar_count="`wc -c < 'faxrunq'`" test 8247 -eq "$shar_count" || echo "faxrunq: original size 8247, current size $shar_count" fi exit 0 - -- ftp.leo.org:/pub/comp/networking/communication/modem/mgetty/mgetty*.tar.gz greenie (login: nuucp, 089/3545988):/pub/uploads/mgetty1.1*.tar.gz ***** SEE THE DOCS on ***** http://www.leo.org/~doering/mgetty/ ***** Gert 'Mr. Mgetty' Doering --- gert () greenie muc de --- mgetty () muc de -----BEGIN PGP SIGNATURE----- Version: 2.6.2i iQCVAwUBM9hga6kuBuNlUUl1AQHgaQP+NlvJS7Fk+hPFsV4hTkJuo7tW+ZjI0n6c m7zaGR5mT1gR73GikeCAQJUfmrCU2KQRDWQYe4eXChXfvk31yF3Yg+A7thpAjpJb d2H56MEKypOooKLR0HsBaDp5ds2jqPp2pzQA5LPNcktCyfJ4VQ/TTSt/Bi5b1wRX Ufa8AMOJ7vU= =AAPP -----END PGP SIGNATURE-----
Current thread:
- Re: CPSR 7: IRIX WWW Server Thomas Walter (Jul 24)
- Re: CPSR 7: IRIX WWW Server Aaron Bornstein (Jul 24)
- Security hole in mgetty+sendfax Gert Doering (Jul 24)
- BIND Nuking Aveek Datta (Jul 24)
- Re: BIND Nuking Thomas H. Ptacek (Jul 29)
- ANNOUNCE: inn-1.5.1sec (fwd) Christopher Samuel (Jul 30)
- Re: Security hole in mgetty+sendfax Gert Doering (Jul 25)
- BIND Nuking Nicolas Dubee (Jul 25)
- Re: your mail Ariel Biener (Jul 25)
- Re: request-route Zoltan Hidvegi (Jul 28)
- Re: request-route Eric Bennett (Jul 29)
- Re: request-route John Macdonald (Jul 29)
- Re: request-route Kragen Sitaker (Jul 30)
- Re: request-route John Macdonald (Jul 31)
- perl fingerd stupidity Chris Terry (Jul 31)
- HP Security Bulletins Digest Aleph One (Jul 31)
- BIND Nuking Aveek Datta (Jul 24)
- Re: request-route Mihai SANDU (Jul 26)