Source code of HPW routine I255607

Server program that runs on Host

 

*********************************************************************
*
*                                I255607
*
*                        TCP/IP Password Server
*
*             Written by William van den Heuvel, 1998
*
*             Update: 1998-11-10
*
*********************************************************************
*
* This module analyses the REQUEST message (input)
*
* The first word is expected to be the command code VERIFY
*
* The second word is expected to be the USERID
*
* The third word is expected to be the PASSWORD
*
* The fourth word is optional but if is there it is expected to
* the NEWPASSWORD
*
*....................................................................
*
* reply codes that may be send back to the client:
* 11 - USERID missing
* 12 - USERID longer than 8 bytes
* 13 - PASSWORD missing
* 14 - PASSWORD longer than 8 bytes
* 15 - NEWPASSWORD longer than 8 bytes
*
*********************************************************************
*
* on entry,
* register 1 points to the API parameters.
* 1.- pointer to REQUEST    input LL-string (request from client)
* 2.- pointer to REPLY     output LL-string (reply to client)
*
*......................................................................
*
* on completion,
* register 15 will contain a return code (RC):
*
* RC=0 - normal completion (always)
*
***********************************************************************




**********************************************************************
*
I255607  CSECT
I255607  AMODE ANY
I255607  RMODE ANY
*
R0       EQU   0
R1       EQU   1
R2       EQU   2
R3       EQU   3
R4       EQU   4
R5       EQU   5
R6       EQU   6
R7       EQU   7
R8       EQU   8
R9       EQU   9
R10      EQU   10   PARM - address of pointer to PARM-string)
R11      EQU   11   BASE - base register of this program
R12      EQU   12   CAA  - reserved for LE
R13      EQU   13   DSA  - Dynamic Storage Area
R14      EQU   14   return address
R15      EQU   15   entry point address
*
DSA      EQU   R13
CAA      EQU   R12
BASE     EQU   R11
PARM     EQU   R10        parameters passed caller
REQUEST  EQU   R9         request message
REPLY    EQU   R8         reply message
*
         USING PARM_DSECT,PARM
         USING DSA_DSECT,DSA
         USING REQUEST_DSECT,REQUEST
         USING REPLY_DSECT,REPLY
*
**********************************************************************



**********************************************************************
*
         LEMENTRY BASE=BASE,LENGTH=DSA_DSECT_LENGTH,PARAM=PARM TRACE=0
*
* note:
*        PARM -> PARM_DSECT
*        DSA  -> DSA_DSECT
*
***********************************************************************


         LEMTRACE 0,'I255607: entry'


***********************************************************************
*
*        get parameters pased by caller
         L     REQUEST,PARM_REQUEST        request message
         L     REPLY,PARM_REPLY            reply message
*
*......................................................................
*
*        get length/address of request message
         L     R3,REQUEST_LENGTH   R3 = length
         LA    R2,REQUEST_MESSAGE  R2 = address
         STM   R2,R3,DSA_REQUEST
*
***********************************************************************


         LEMTRACE 0,'I255607: REQUEST: ',((2),(3),X)


***********************************************************************
*
*        ensure first word of request message is "VERIFY"
*
A100     EQU   *
*
         LM    R2,R3,DSA_REQUEST
*
*......................................................................
*
*        skip over leading blanks
A110     EQU   *
         CLI   0(R2),C' '
         BNE   A111
         LA    R2,1(R2)
         BCT   R3,A110
         B     A130                nothing found
*
*        begin of first word found
A111     EQU   *
         STM   R2,R3,DSA_REQUEST
*
*......................................................................
*
*        Find end of first word
*        (the first word is terminated by a blank)
A120     EQU   *
         CLI   0(R2),C' '
         BE    A121
         LA    R2,1(R2)              R2 -> next byte in request message
         BCT   R3,A120
*
*        R2 -> beyond first word
*        R3 =  remaining length
*
*        copy first word to DSA_COMMAND
A121     EQU   *
         LM    R14,R15,DSA_REQUEST   R14/R15 = length/address of word
         SR    R15,R3                R15 = length of first word
         ICM   R15,B'1000',=C' '     padd with blanks
         LA    R0,DSA_COMMAND
         LA    R1,L'DSA_COMMAND
         MVCL  R0,R14
*
*        first word found
         STM   R2,R3,DSA_REQUEST
*
*......................................................................
*
*        turn all characters of word into capitels
         OC    DSA_COMMAND,=8X'40'
*
*        check if it is "VERIFY"
         CLC  DSA_COMMAND,=CL8'VERIFY'
         BE   B100         ok
*
*......................................................................
*
*        first word is not "VERIFY"
A130     EQU   *
         LEMTRACE 0,'I255607: COMMAND: ',(DSA_COMMAND,8,C)
*
*        echo request message
         MVC   REPLY_LENGTH,REQUEST_LENGTH
         MVC   REPLY_MESSAGE,REQUEST_MESSAGE
*
*        return to caller
         B     X100
*
***********************************************************************




***********************************************************************
*
*        USERID
*
*        the second word is expected to be the userid
*
B100     EQU   *
*
*......................................................................
*
*        init USERID
*
         MVI   DSA_USERID,0           1-byte length of USERID
         MVC   DSA_USERID+1(8),=CL8' '
*
*......................................................................
*
*        restart scan beyond command code "VERIFY"
         LM    R2,R3,DSA_REQUEST
         LTR   R3,R3
         BZ    B130            nothing left
*
*......................................................................
*
*        skip over leading blanks
B110     EQU   *
         CLI   0(R2),C' '
         BNE   B111
         LA    R2,1(R2)
         BCT   R3,B110
         B     B130                   nothing found
*
*        begin of USERID found
B111     EQU   *
         STM   R2,R3,DSA_REQUEST
*
*......................................................................
*
*        Find end of USERID
*        (the USERID is terminated by a blank)
B120     EQU   *
         CLI   0(R2),C' '
         BE    B121                  end of word found
         LA    R2,1(R2)              R2 -> next byte in request message
         BCT   R3,B120
*
*        R2 -> beyond second word
*        R3 =  remaining length
*
*        copy second word to DSA_USERID
*        the first byte of DSA_USERID is a 1-byte length field
*        the remaining 8 bytes is for the userid
B121     EQU   *
         LM    R14,R15,DSA_REQUEST   R14/R15 = length/address of word
         SR    R15,R3                R15 = length of first word
         STC   R15,DSA_USERID        1-byte length of USERID
         ICM   R15,B'1000',=C' '     padd with blanks
         LA    R0,DSA_USERID+1
         LA    R1,8
         MVCL  R0,R14
*
*        USERID found
         STM   R2,R3,DSA_REQUEST
*
*......................................................................
*
*        check minimum length of USERID (1 byte)
*
B130     EQU   *
         CLI   DSA_USERID,1
         BNL   B140
*
*        USERID missing
         MVC   REPLY_LENGTH,=F'02'
         MVC   REPLY_MESSAGE,=C'11'     Benutzer-ID fehlt
*
*        return to caller
         B     X100
*
*......................................................................
*
*        check maximum length of USERID (8 bytes)
B140     EQU   *
*
         CLI   DSA_USERID,8
         BNH   B150
*
*        USERID too long
         MVC   REPLY_LENGTH,=F'02'
         MVC   REPLY_MESSAGE,=C'12'  Benutzer-ID falsch (zu lange)
*
         XR    2,2
         IC    2,DSA_USERID
         LA    2,1(2)
         LEMTRACE 0,'I255607: USERID: ',(DSA_USERID,(2),X)
*
*        return to caller
         B     X100
*
*......................................................................
*
*        translate USERID to uppercase
B150     EQU   *
         XR    R1,R1
         ICM   R1,B'0001',DSA_USERID
         BZ    B152
         EX    R1,B151             execute TR instruction
         B     B152
*
*        the length of the first operand is supplied in R1
B151     TR    DSA_USERID+1(0),UPPERCASE
B152     EQU   *
         LEMTRACE 0,'I255607: USERID: ',(DSA_USERID,(2),X)
*
***********************************************************************





***********************************************************************
*
*        PASSWORD
*
*        the third word is expected to be the password
*
C100     EQU   *
*
*......................................................................
*
*        init PASSWORD
*
         MVI   DSA_PASSWORD,0           1-byte length of PASSWORD
         MVC   DSA_PASSWORD+1(8),=CL8' '
*
*......................................................................
*
*        restart scan beyond USERID
         LM    R2,R3,DSA_REQUEST
         LTR   R3,R3
         BZ    C130            nothing left
*
*......................................................................
*
*        skip over leading blanks
C110     EQU   *
         CLI   0(R2),C' '
         BNE   C111
         LA    R2,1(R2)
         BCT   R3,C110
         B     C130                   nothing found
*
*        begin of PASSWORD found
C111     EQU   *
         STM   R2,R3,DSA_REQUEST
*
*......................................................................
*
*        Find end of PASSWORD
*        (the PASSWORD is terminated by a blank)
C120     EQU   *
         CLI   0(R2),C' '
         BE    C121                  end of word found
         LA    R2,1(R2)              R2 -> next byte in request message
         BCT   R3,C120
*
*        R2 -> beyond third word
*        R3 =  remaining length
*
*        copy third word to DSA_PASSWORD
*        the first byte of DSA_PASSWORD is a 1-byte length field
*        the remaining 8 bytes is for the password
C121     EQU   *
         LM    R14,R15,DSA_REQUEST   R14/R15 = length/address of word
         SR    R15,R3                R15 = length of word
         STC   R15,DSA_PASSWORD      1-byte length of PASSWORD
         ICM   R15,B'1000',=C' '     padd with blanks
         LA    R0,DSA_PASSWORD+1
         LA    R1,8
         MVCL  R0,R14
*
*        PASSWORD found
         STM   R2,R3,DSA_REQUEST
*
*......................................................................
*
*        check minimum length of PASSWORD (1 byte)
*
C130     EQU   *
         CLI   DSA_PASSWORD,1
         BNL   C140
*
*        PASSWORD missing
         MVC   REPLY_LENGTH,=F'02'
         MVC   REPLY_MESSAGE,=C'13'      Passwort fehlt
*
*        return to caller
         B     X100
*
*......................................................................
*
*        check maximum length of PASSWORD (8 bytes)
C140     EQU   *
*
         CLI   DSA_PASSWORD,8
         BNH   C150
*
*        PASSWORD too long
         MVC   REPLY_LENGTH,=F'02'
         MVC   REPLY_MESSAGE,=C'14'     Passwort falsch (zu lange)
*
         XR    2,2
         IC    2,DSA_PASSWORD
         LA    2,1(2)
         LEMTRACE 0,'I255607: PASSWORD: ',(DSA_PASSWORD,(2),X)
*
*        return to caller
         B     X100
*
*......................................................................
*
*        translate PASSWORD to uppercase
C150     EQU   *
         XR    R1,R1
         ICM   R1,B'0001',DSA_PASSWORD
         BZ    C152
         EX    R1,C151             execute TR instruction
         B     C152
*
*        the length of the first operand is supplied in R1
C151     TR    DSA_PASSWORD+1(0),UPPERCASE
C152     EQU   *
         LEMTRACE 0,'I255607: PASSWORD: ',(DSA_PASSWORD,(2),X)
*
***********************************************************************





***********************************************************************
*
*        NEWPASSWORD
*
*        the fourth word is optional but if it is specified
*        then it is expected to be the new password
*
D100     EQU   *
*
*......................................................................
*
*        init NEWPASSWORD
*
         MVI   DSA_NEWPASSWORD,0           1-byte length of NEWPASSWORD
         MVC   DSA_NEWPASSWORD+1(8),=CL8' '
*
*......................................................................
*
*        restart scan beyond PASSWORD
         LM    R2,R3,DSA_REQUEST
         LTR   R3,R3
         BZ    D130            nothing left
*
*......................................................................
*
*        skip over leading blanks
D110     EQU   *
         CLI   0(R2),C' '
         BNE   D111
         LA    R2,1(R2)
         BCT   R3,D110
         B     D130                   nothing found
*
*        begin of PASSWORD found
D111     EQU   *
         STM   R2,R3,DSA_REQUEST
*
*......................................................................
*
*        Find end of PASSWORD
*        (the PASSWORD is terminated by a blank)
D120     EQU   *
         CLI   0(R2),C' '
         BE    D121                  end of word found
         LA    R2,1(R2)              R2 -> next byte in request message
         BCT   R3,D120
*
*        R2 -> beyond word
*        R3 =  remaining length
*
*        copy word to DSA_NEWPASSWORD
*        the first byte of DSA_NEWPASSWORD is a 1-byte length field
*        the remaining 8 bytes is for the new password
D121     EQU   *
         LM    R14,R15,DSA_REQUEST   R14/R15 = length/address of word
         SR    R15,R3                R15 = length of word
         STC   R15,DSA_NEWPASSWORD   1-byte length of NEWPASSWORD
         ICM   R15,B'1000',=C' '     padd with blanks
         LA    R0,DSA_NEWPASSWORD+1
         LA    R1,8
         MVCL  R0,R14
*
*        NEWPASSWORD found
         STM   R2,R3,DSA_REQUEST
*
*......................................................................
*
*        check maximum length of NEWPASSWORD (8 bytes)
D130     EQU   *
*
         CLI   DSA_NEWPASSWORD,8
         BNH   D140
*
*        NEWPASSWORD too long
         MVC   REPLY_LENGTH,=F'02'
         MVC   REPLY_MESSAGE,=C'15'   neues Passwort falsch (zu lange)
*
         XR    2,2
         IC    2,DSA_NEWPASSWORD
         LA    2,1(2)
         LEMTRACE 0,'I255607: NEWPASSWORD: ',(DSA_NEWPASSWORD,(2),X)
*
*        return to caller
         B     X100
*
*......................................................................
*
D140     EQU   *
         XR    2,2
         IC    2,DSA_NEWPASSWORD
         LA    2,1(2)
         LEMTRACE 0,'I255607: NEWPASSWORD: ',(DSA_NEWPASSWORD,(2),X)
*
*......................................................................
*
*        translate NEWPASSWORD to uppercase
D150     EQU   *
         XR    R1,R1
         ICM   R1,B'0001',DSA_NEWPASSWORD
         BZ    D152
         EX    R1,D151             execute TR instruction
         B     D152
*
*        the length of the first operand is supplied in R1
D151     TR    DSA_NEWPASSWORD+1(0),UPPERCASE
D152     EQU   *
         LEMTRACE 0,'I255607: NEWPASSWORD: ',(DSA_NEWPASSWORD,(2),X)
*
***********************************************************************




***********************************************************************
*
*        call I255608 to let RACF do the work
*
*        make parameter list
         LA    R0,DSA_USERID
         ST    R0,DSA_I255608_USERID
         LA    R0,DSA_PASSWORD
         ST    R0,DSA_I255608_PASSWORD
         LA    R0,DSA_NEWPASSWORD
         ST    R0,DSA_I255608_NEWPASSWORD
         LA    R0,REPLY_DSECT
         ST    R0,DSA_I255608_REPLY
*
*        call
         LA    R1,DSA_I255608
         L     R15,=V(I255608)
         BASR  R14,R15
*
***********************************************************************





**********************************************************************
*
*        return to caller
X100     EQU *
         LEMTRACE 0,'I255607: exit'
*
         LEMEXIT RC=(15)
*
*********************************************************************




**********************************************************************
*
* translation table from lower case EBCDIC to upper case EBCDIC
*
UPPERCASE  EQU  *
*                 .0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F
           DC   X'000102030405060708090A0B0C0D0E0F'  0.
           DC   X'101112131415161718191A1B1C1D1E1F'  1.
           DC   X'202122232425262728292A2B2C2D2E2F'  2.
           DC   X'303132333435363738393A3B3C3D3E3F'  3.
           DC   X'404142434445464748494A4B4C4D4E4F'  4.
           DC   X'505152535455565758595A5B5C5D5E5F'  5.
           DC   X'606162636465666768696A6B6C6D6E6F'  6.
           DC   X'707172737475767778797A7B7C7D7E7F'  7.
           DC   X'80C1C2C3C4C5C6C7C8C98A8B8C8D8E8F'  8.
           DC   X'90D1D2D3D4D5D6D7D8D99A9B9C9D9E9F'  9.
           DC   X'A0A1E2E3E4E5E6E7E8E9AAABACADAEAF'  A.
           DC   X'B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'  B.
           DC   X'C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF'  C.
           DC   X'D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF'  D.
           DC   X'E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF'  E.
           DC   X'F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF'  F.
*                 .0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F
*
*********************************************************************





***********************************************************************
*
* DSA - Dynamic Storage Area (pointed to by register 13)
*
DSA_DSECT     LEMDSA
*
*......................................................................
*
DSA_REQUEST   DS   F,A     length/address
*
*......................................................................
*
DSA_COMMAND     DS     CL8 command code "VERIFY"
DSA_USERID      DS AL1,CL8 1-byte length followed by 8-byte userid
DSA_PASSWORD    DS AL1,CL8 1-byte length followed by 8-byte password
DSA_NEWPASSWORD DS AL1,CL8 1-byte length followed by 8-byte newpassword
*
*......................................................................
*
DSA_I255608             DS 0D
DSA_I255608_USERID      DS A         pointer to DSA_USERID
DSA_I255608_PASSWORD    DS A         pointer to DSA_PASSWORD
DSA_I255608_NEWPASSWORD DS A         pointer to DSA_NEWPASSWORD
DSA_I255608_REPLY       DS A         pointer to REPLY
*
*......................................................................
*
              DS   0D   D-align what follows
DSA_DSECT_LENGTH EQU  *-DSA_DSECT
*
***********************************************************************




***********************************************************************
*
* PARM - parameters passed by caller via register 1
*
PARM_DSECT    DSECT
PARM_REQUEST  DS   A  pointer to REQUEST
PARM_REPLY    DS   A  pointer to REPLY
*
***********************************************************************
*
* REQUEST - request message pointed to by PARM_REQUEST
*
REQUEST_DSECT    DSECT
REQUEST_LENGTH   DS  F       length of request message (maximum 80)
REQUEST_MESSAGE  DS  CL80    request message
*
***********************************************************************
*
* REPLY - reply message pointed to by PARM_REPLY
*
REPLY_DSECT    DSECT
REPLY_LENGTH   DS  F       length of reply message (maximum 80)
REPLY_MESSAGE  DS  CL80    reply message
*
***********************************************************************
        END