                                ==Phrack Inc.=

                     Volume Three, Issue 30, File #7 of 12

                             =-------------------=

                               VAX/VMS Fake Mail

                                by Jack T. Tab

                             =-------------------=


In the August 1986 issue of VAX PROFESSIONAL, the BASIC subroutine that appears
at the end of this text was published.  It was not until more than two years
later that DEC included a callable mail interface with VMS 5.x.  While the
official version is much more extensive, the routine included here has one
important feature.  The ability to have a mail message appear to be from
someone else is a good addition to most "toolkits."

VMS Mail works in two manners.  The first is the familiar interactive.  The
second is as a network object.  In this method, MAIL is invoked by the
NETSERVER.COM command procedure in response to an incoming connect request.
MAIL.EXE is activated as network object 27.  The other network objects can be
viewed by using the NCP command SHOW KNOWN OBJECTS.  In this mode, MAIL.EXE
operates as a slave process, receiving instructions from the master process.
The master, in most cases, is another process running MAIL.EXE interactively.
The slave process can handle requests to deliver mail to as many recipients as
necessary.  Addresses that are not on the same node as the slave process are
forwarded by activating yet another slave process on the target node.  The
information sent by the master MAIL to the slave MAIL is quite simple and
straightforward, consisting of a series of strings.

The first string is for the FROM name.  This is what makes the subroutine
useful, as it can be anything (i.e. the_Easter_Bunny).  The next set of strings
are to whom the mail is to be sent.  One address per string, with a null
string, chr(0), terminating the list.  The third item is what the receiver(s)
sees in their TO: field.  This also can be anything.  VMS MAIL can use this
option for its .DIS distribution lists.  The final information is the body of
the message.  It too is terminated by another null string.  The subject of the
mail message is taken from the first line of this text.

The MAIL slave will send back appropriate status messages indicating problems
if they occur.  Such as "Addressee Unknown" or VMS and DECnet errors like "Disk
Quota Exceeded" or "Remote Node Not Reachable").

The only privilege that seems necessary is NETMBX.  Without it the subroutine
cannot call MAIL as a network object.  Our beloved system management resolved
the problem of people pretending to be SYSTEM by installing MAIL with NETMBX
and removing the priv from the student accounts.  The subroutine works just as
well with JNET and BITNET as it does with DECNET addresses.


***********************************CUT HERE************************************
1  %TITLE 'MAIL SUBROUTINE'

   SUB MAILT( STRING NODE, &
       STRING FROM_NAME, &
       STRING TO_LIST(), &
       STRING TO_SHOW, &
       STRING SUBJECT, &
       STRING TEXT() )

   OPTION TYPE = INTEGER

   DECLARE INTEGER FUNCTION &
     PUT_MSG

   DECLARE STRING FUNCTION &
     GET_MSG, &
     GET_INPUT

   DECLARE INTEGER CONSTANT &
     TRUE = -1, &
     FALSE = 0
   Net_Link_Open = FALSE

   Z = POS( NODE + ":" , ":" , 1)
   NODE_NAME$ = LEFT$( NODE , Z - 1 )
   ON ERROR GOTO Mail_Net_Error
   MAIL_CHANNEL = 12
   OPEN NODE_NAME$ + '::"27="' AS FILE MAIL_CHANNEL

   Net_Link_Open = TRUE

   STS = PUT_MSG( FROM_NAME )
   IF STS <> 0 THEN
     GOTO ERROR_DONE
   END IF
   RECEIVERS = 0
   TO_COUNT = 1

Mail_Recipients:
   IF TO_LIST( TO_COUNT ) = "" THEN
     GOTO End_Of_Line
   END IF
   STS = PUT_MSG( EDIT$( TO_LIST( TO_COUNT ) , 32 ) )
   IF STS <> 0 THEN
     GOTO Error_Done
   END IF
   GOSUB Errchk
   IF LINK_ERR <> 0 THEN
     GOTO Error_Done
   END IF

   IF ( ERRSTS AND 1 ) = 0 THEN
     GOTO Error_Done
   END IF

   TO_COUNT = TO_COUNT + 1
   GOTO Mail_Recipients

END_OF_LINE:
   STS = PUT_MSG( CHR$(0) )
   IF STS <> 0 THEN
     GOTO Error_Done
   END IF
   IF RECEIVERS = 0 THEN
     GOTO Mail_Done
   END IF

   STS = PUT_MSG( TO_SHOW )
   IF STS <> 0 THEN
     GOTO Error_Done
   END IF

   STS = PUT_MSG( SUBJECT )
   IF STS <> 0 THEN
     GOTO Error_Done
   END IF

   FOR I = 1 UNTIL TEXT(I) = CHR$(255)
     STS = PUT_MSG( TEXT(I) )
     IF STS <> 0 THEN
       GOTO Error_Done
     END IF
   NEXT I

   STS = PUT_MSG( CHR$(0) )
   IF STS <> 0 THEN
     GOTO Error_Done
   END IF
   SAVE_COUNT = RECEIVERS
   INDEX = 0

Delivery_Check:
   GOSUB Errchk
   IF LINK_ERR <> 0 THEN
     GOTO Error_Done
   END IF
   INDEX = INDEX + 1
   IF INDEX <> SAVE_COUNT THEN
     GOTO Delivery_Check
   END IF
   GOTO Mail_Done

Errchk:
   MAIL_STS = ASCII( GET_MSG )
   IF LINK_ERR <> 0 THEN
     ERRSTS = LINK_ERR
     RETURN
   END IF
   IF ( MAIL_STS AND 1 ) = 1 THEN
     Receivers = Receivers + 1
     ERRSTS = MAIL_STS
     RETURN
   END IF

Errmsg:
   MAIL_ERR$ = GET_MSG
   IF LINK_ERR <> 0 THEN
     ERRSTS = LINK_ERR
     RETURN
   END IF
   IF LEN( MAIL_ERR$ ) <> 1 THEN
     PRINT MAIL_ERR$
     GOTO Errmsg
   END IF
   IF ASCII( MAIL_ERR$ ) = 0 THEN
     RETURN
   ELSE
     GOTO Errmsg
   END IF

   DEF INTEGER PUT_MSG( STRING M )
   ON ERROR GOTO 1550
   MLEN = LEN( M )
   MOVE TO # MAIL_CHANNEL , M = MLEN
   PUT # MAIL_CHANNEL, COUNT MLEN
   PUT_MSG = 0
   EXIT DEF

1550 RESUME 1555

1555 PUT_MSG = ERR
     END DEF

   DEF STRING GET_INPUT( INTEGER C )
   EOF = FALSE
   ON ERROR GOTO 1650
   GET # C
   R = RECOUNT
   MOVE FROM #C , TEMP$ = R
   GET_INPUT = TEMP$
   EXIT DEF

1650 RESUME 1655

1655 EOF = TRUE
     END DEF

   DEF STRING GET_MSG
   ON ERROR GOTO 1750
   GET # MAIL_CHANNEL
   R = RECOUNT
   MOVE FROM # MAIL_CHANNEL , TEMP$ = R
   GET_MSG = TEMP$
   LINK_ERR = 0
   EXIT DEF

1750 RESUME

1755 LINK_ERR = ERR
     END DEF

Mail_Net_Error:
  RESUME 1900

1900 PRINT "%Network communications error."

Error_Done:

Mail_Done:
   IF Net_Link_Open THEN
     CLOSE MAIL_CHANNEL
   END IF

   END SUB
***********************************CUT HERE************************************
