From:	SMTP%"RELAY-INFO-VAX@CRVAX.SRI.COM" 27-MAY-1993 13:41:12.79
To:	EVERHART
CC:	
Subj:	Re: MACRO source examples for $GETUAI and $HASH_PASSWORD

X-Newsgroups: comp.os.vms
Subject: Re: MACRO source examples for $GETUAI and $HASH_PASSWORD
Message-ID: <1993May27.135242.87488@embl-heidelberg.de>
From: omond@embl-heidelberg.de (Roy Omond)
Date: 27 May 93 13:52:42 +0100
Distribution: world
Organization: EMBL, European Molecular Biology Laboratory
Lines: 207
To: Info-VAX@KL.SRI.COM
X-Gateway-Source-Info: USENET

In article <1u1kpj$r85@DIALix.oz.au>, leonardi@DIALix.oz.au (Ian Leonard) writes:
> 
> Hi,
> 
> I am trying to find some source code examples for a MACRO
> program that will find the UAI$_ENCRYPT value from the UAF (given a
> username) and then calling $HASH_PASSWORD to check to see if the password
> they have typed in is correct.
> 
> The reason for this is to enable some generic accounts to be logged into
> without a password, and then it will ask the user for their personal 
> username and password, and check them.  I tried but have not had much
> success due to my lack of Macro programming knowledge.  This is the only
> compiler available otherwise I would do it in Fortran.
> 
> Any examples (or even if it has already been done) would be greatly
> appreciated.
> 
> Please mail responses to leonardi@DIALix.oz.au
> Thanks
> Ian Leonard
> Denver Technology, Perth, Western Australia.


Yes, I know it's not in Macro, but it's short enough, and probably might be
of use to others who want to do a similar thing.  We use it to identify
"real" users using a turnkey system written on the assumption that all
users use the same username (*sigh* ...).  It's run as the first part of
a captive account, so I'm pretty sure it's robust.

(Oh yeah, it's written in Fortran)

Roy Omond
System Manager/PostMaster etc. etc.
European Molecular Biology Laboratory
Heidelberg, Germany.

--- cut here ---

	Program		Check Password

	Implicit	None

	Character*80	UserName,Password
	Character*20	U_Prompt
	Character*18	P_Prompt

	Integer		Status,Sys$Assign,Sys$QioW,Function,TT_Chan
	Integer		Sys$GetUAI,Lib$Set_Symbol,Sys$Hash_Password
	Integer		L_UserName,L_Password
	Integer*2	IOSB(4),Attempts
	Integer		HashedPassword(2)

	Parameter	TIMEOUT=30		! give users 30 seconds
	Parameter	MAXIMUM ATTEMPTS=3	! and 3 attempts to get it right
	Parameter	CR=13
	Parameter	LF=10
	Parameter	ESC=27

	Include		'($IOdef)'
	Include		'($UAIdef)'
	Include		'($LIBCLIdef)'

	Structure /ItemList/	!---------------------------------------+
				Integer*2 Buff_Length			!
				Integer*2 Item_Code			!
				Integer	  Buff_Address			!
				Integer	  Ret_Length			!
	End Structure		!---------------------------------------+

	Record	/ItemList/	Item(4)		! For GetUAI info

	Byte		UAF_Encrypt
	Integer*2	UAF_Salt
	Integer		UAF_Password(2)


	Status=Sys$Assign('TT:',		! Terminal
	1		TT_Chan,		! Channel
	2		,			! Access mode
	3		)
	If (.not.Status) Call Stop(Status)

	U_Prompt	='xxx[1mUsername: x[0m'
	U_Prompt(1:1)	=Char(CR)
	U_Prompt(2:2)	=Char(LF)
	U_Prompt(3:3)	=Char(ESC)
	U_Prompt(17:17)	=Char(ESC)

	P_Prompt	='x[1mPassword: x[0m'
	P_Prompt(1:1)	=Char(ESC)
	P_Prompt(15:15)	=Char(ESC)

10	UserName=' '
	Password=' '
	Function=IO$_READPROMPT+IO$M_CVTLOW+IO$M_TIMED

						! Read request
	Status=Sys$QioW(,			! efn
	1		%Val(TT_Chan),		! Terminal channel
	2		%Val(Function),		! Function : read
	3		IOSB,			! IOSB
	4		,			! AST address
	5		,			! AST parameter
	6		%Ref(UserName),		! P1 Buffer
	7		%Val(80),		! P2 Buffer size
	8		%Val(TIMEOUT),		! P3 Timeout seconds
	9		,			! P4 Terminator (standard)
	9		%Ref(U_Prompt),		! P5 Prompt string
	9		%Val(20))		! P6 Length of prompt

	If (.not.Status)  Call Stop(Status)
	If (.not.IOSB(1)) Call Stop(IOSB(1))

	Function=IO$_READPROMPT+IO$M_CVTLOW+IO$M_TIMED+IO$M_NOECHO
						! Read request
	Status=Sys$QioW(,			! efn
	1		%Val(TT_Chan),		! Terminal channel
	2		%Val(Function),		! Function : read
	3		IOSB,			! IOSB
	4		,			! AST address
	5		,			! AST parameter
	6		%Ref(Password),		! P1 Buffer
	7		%Val(80),		! P2 Buffer size
	8		%Val(TIMEOUT),		! P3 Timeout seconds
	9		,			! P4 Terminator (standard)
	9		%Ref(P_Prompt),		! P5 Prompt string
	9		%Val(18))		! P6 Length of prompt

	If (.not.Status)  Call Stop(Status)
	If (.not.IOSB(1)) Call Stop(IOSB(1))

	Call Str$Trim(Username,Username,L_Username)
	Call Str$Trim(Password,Password,L_Password)

	L_Username=L_Username-1		! strip off terminator from
	L_Password=L_Password-1		! input strings

	Item(1).Buff_Length=1
	Item(1).Item_Code=UAI$_ENCRYPT
	Item(1).Buff_Address=%Loc(UAF_Encrypt)
	Item(1).Ret_Length=0

	Item(2).Buff_Length=2
	Item(2).Item_Code=UAI$_SALT
	Item(2).Buff_Address=%Loc(UAF_Salt)
	Item(2).Ret_Length=0

	Item(3).Buff_Length=8
	Item(3).Item_Code=UAI$_PWD
	Item(3).Buff_Address=%Loc(UAF_Password)
	Item(3).Ret_Length=0

	Item(4).Buff_Length=0
	Item(4).Item_Code=0
	Item(4).Buff_Address=0
	Item(4).Ret_Length=0

	Status=Sys$GetUAI(,,			! null arguments
	1		UserName(1:L_Username),	! username
	2		Item,			! item list
	3		,,)			! null arguments
	If (.not.Status) Then

	   Attempts=Attempts+1
	   If (Attempts.ge.MAXIMUM ATTEMPTS) Call Stop(8888)
	   Goto 10

	EndIf

	Status=Sys$Hash_Password(Password(1:L_Password),! password to check
	1		%Val(UAF_Encrypt),	! encryption method
	2		%Val(UAF_Salt),		! random salt
	3		UserName(1:L_UserName),	! username
	4		HashedPassword)		! returned hashed password
	If (.not.Status) Then

	   Attempts=Attempts+1
	   If (Attempts.ge.MAXIMUM ATTEMPTS) Call Stop(8888)
	   Goto 10

	EndIf

	If (	HashedPassword(1).ne.UAF_Password(1)
	1 .or.	HashedPassword(2).ne.UAF_Password(2)) Then

	   Attempts=Attempts+1
	   If (Attempts.ge.MAXIMUM ATTEMPTS) Call Stop(8888)
	   Goto 10

	EndIf

	Status=Lib$Set_Symbol('USERNAME',UserName(1:L_UserName),
	1	LIB$K_CLI_GLOBAL_SYM)

	End


	Subroutine Stop(Status)

	Integer		Status,Lib$Do_Command

	Status=Lib$Do_Command('Stop/Id=0')	! hara kiri
	Status=Lib$Stop(%Val(Status))

	Return					! no can reach
	End

