Title : VAX/VMS Fake Mail
Author : Jack T. Tab
==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************************************