PROGRAM UAI_EXAMPLE
C+
C
C ABSTRACT:
C
C Example showing use of $GETUAI and $HASH_PASSWORD
C
C FUNCTIONAL DESCRIPTION:
C
C This example demonstrates the use of the $GETUAI and $HASH_PASSWORD
C OpenVMS System Services. It prompts the user for the current password
C and compares it to that user's hashed password as stored in the
C system SYSUAF.DAT file. Other routines used are LIB$GETJPI and
C SMG$READ_STRING
C
C AUTHOR(S):
C
C Steve Lionel, Digital Equipment Corporation
C
C CREATION DATE:
C
C 31-Jan-1996
C
C-
IMPLICIT NONE
INCLUDE '($SYSSRVNAM)' ! System service names
INCLUDE '($JPIDEF)' ! $GETJPI definitions
INCLUDE '($UAIDEF)' ! $GETUAI definitions
INCLUDE '($TRMDEF)' ! TRM$ (terminal) definitions
INCLUDE '(LIB$ROUTINES)' ! LIB$ routine names
INCLUDE '(SMG$ROUTINES)' ! SMG$ routine names
CHARACTER*12 USERNAME ! Current username
BYTE ENCRYPT_METHOD ! Password encryption method
INTEGER*4 CURRENT_PWD(2) ! Hashed current password
INTEGER*4 USER_PWD(2) ! Hashed user-entered password
INTEGER*2 SALT ! Salt value used to encrypt password
CHARACTER*32 PASSWORD ! Password as entered by user
INTEGER*2 PASSWORD_LEN ! Length of entered password
INTEGER*4 KEYBOARD_ID ! SMG$ virtual keyboard ID
INTEGER*4 STATUS ! Return status value
STRUCTURE /ITEM_LIST_3/
INTEGER*2 BUFFER_LENGTH ! Length of buffer
INTEGER*2 ITEM_CODE ! Item code
INTEGER*4 BUFFER_ADDRESS ! Address of buffer
INTEGER*4 RETLEN_ADDRESS ! Returned length address
END STRUCTURE
RECORD /ITEM_LIST_3/ UAI_ITEMLIST(4) ! Item list for $GETUAI
! Get current username
!
STATUS = LIB$GETJPI(JPI$_USERNAME,,,,USERNAME)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Create virtual keyboard for password inquiry
!
STATUS = SMG$CREATE_VIRTUAL_KEYBOARD(KEYBOARD_ID)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Fill in itemlist for $GETUAI call
!
UAI_ITEMLIST(1).BUFFER_LENGTH = SIZEOF(ENCRYPT_METHOD)
UAI_ITEMLIST(1).ITEM_CODE = UAI$_ENCRYPT
UAI_ITEMLIST(1).BUFFER_ADDRESS = %LOC(ENCRYPT_METHOD)
UAI_ITEMLIST(1).RETLEN_ADDRESS = 0
UAI_ITEMLIST(2).BUFFER_LENGTH = SIZEOF(CURRENT_PWD)
UAI_ITEMLIST(2).ITEM_CODE = UAI$_PWD
UAI_ITEMLIST(2).BUFFER_ADDRESS = %LOC(CURRENT_PWD)
UAI_ITEMLIST(2).RETLEN_ADDRESS = 0
UAI_ITEMLIST(3).BUFFER_LENGTH = SIZEOF(SALT)
UAI_ITEMLIST(3).ITEM_CODE = UAI$_SALT
UAI_ITEMLIST(3).BUFFER_ADDRESS = %LOC(SALT)
UAI_ITEMLIST(3).RETLEN_ADDRESS = 0
UAI_ITEMLIST(4).BUFFER_LENGTH = 0 ! End of list
UAI_ITEMLIST(4).ITEM_CODE = 0
UAI_ITEMLIST(4).BUFFER_ADDRESS = 0
UAI_ITEMLIST(4).RETLEN_ADDRESS = 0
! Call $GETUAI to retrieve information
!
STATUS = SYS$GETUAI(,,USERNAME,UAI_ITEMLIST,,,)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Prompt user for password - note that conversion to
! uppercase is required, as is knowing the length of
! the entered string.
!
WRITE (*,101) USERNAME
101 FORMAT ($,' Enter password for user ',A,': ')
STATUS = SMG$READ_STRING(KEYBOARD_ID,PASSWORD,,,
1 TRM$M_TM_NOECHO .OR. TRM$M_TM_CVTLOW,,,PASSWORD_LEN)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Call $HASH_PASSWORD to hash user-entered password
!
STATUS = SYS$HASH_PASSWORD(PASSWORD(1:PASSWORD_LEN),
1 %VAL(ENCRYPT_METHOD),%VAL(SALT),USERNAME,USER_PWD)
! Compare hashed passwords
!
IF ((CURRENT_PWD(1) .EQ. USER_PWD(1)) .AND.
1 (CURRENT_PWD(2) .EQ. USER_PWD(2))) THEN
WRITE (*,'(/A)') ' Password matches'
ELSE
WRITE (*,'(/A)') ' Password does not match'
END IF
! Clean up
!
STATUS = SMG$DELETE_VIRTUAL_KEYBOARD(KEYBOARD_ID)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
END