- INHVCRV ; JC Hrubovcak ; 22 Oct 1999 15:49 ;
- ;;3.01;BHL IHS Interfaces with GIS;;JUL 01, 2001
- ;COPYRIGHT 1991-2000 SAIC
- ; HL7/PWS logon utilities
- Q
- ;
- VALID(INV,INUIF,INOA,INODA) ; subroutine, VALIDate LoS logon request
- ; Input:
- ; INV array - (req) ZIL1=REQ, ZIL2=IP address, ZIL3=port, ZIL7=requested
- ; division, ZIL8=access code, ZIL9=verify code
- ; INUIF - (req) UNIVERSAL INTERFACE IEN
- ;
- ; Output:
- ; INOA array - (pbr) ZIL1=REQ, ZIL4=user, ZIL5=provider, ZIL6=timeout,
- ; ZIL10=ticket/key. These values are returned to
- ; the remote system.
- ; INODA array - (pbr) 1st subscript file#, 2nd subscript IEN. Not used.
- ;
- N B,INBPNAPS,INDSTP,INERR
- ; Initialization
- D RTNINIT S INOA("ZIL1")="REQ"
- S B=$$INPARMS^INHVCRL2(.INDSTP,.INPARMS,.INERR,INUIF) I B D LOGERR(.INERR),NACK Q
- S INBPNAPS=+$P($G(^INRHT(INPARMS(INDSTP,"TTIN"),0)),U,17) I INBPNAPS'>0 D LOGERR("Missing Application Process pointer for INTERFACE TRANSACTION TYPE, '"_INPARMS(INDSTP,"TTIN01")_"'"),NACK Q
- ; validate IP address
- S B=$$VALIDIP^INHULOG(INBPNAPS,@INV@("ZIL2")) I B D LOGERR("Invalid remote IP address '"_@INV@("ZIL2")_"': "_$P(B,U,2)),NACK Q
- ; validate user
- S B=$$LOGON(.INV,.INOA,.INODA) I B'>0 D LOGERR("Invalid LOGON: "_$P(B,U,2)),NACK Q
- ; create Application server (ApS)
- S B=$$NEWSVR^INHVCRV1(INBPNAPS,.INV,.INOA) I B D LOGERR("'Application Server creation' failed: "_B),NACK Q
- ;
- ; any additional validation would follow here
- ;
- D ACCEPT,CLEANUP ; successful logon
- Q
- ;
- REVALID(INV,INOA) ; subroutine, Validate ApS logon request
- ; Input:
- ; INV array - (req) ZIL1=ON, ZIL2=IP address, ZIL3=port, ZIL7=requested
- ; division, ZIL8=access code, ZIL9=verify code,
- ; ZIL11=scrambled,seeded key/ticket from remote sys
- ;
- ; Input passed from ApS (all required):
- ; INADDR = IP address of remote server to connect to as a TCP client,
- ; or null to open as a TCP server
- ; INBPN = BACKGROUND PROCESS CONTROL IEN for ApS
- ; INDUZ = USER IEN
- ; INPORT = IP port to open (client or server)
- ; INTICK = security ticket
- ;
- ; Output:
- ; INOA array - (pbr) No ZIL segment values are returned to the remote
- ; system (in the ApS Ack).
- ; INODA array - 1st subscript file#, 2nd subscript IEN. Not used.
- ;
- N B,INUSER
- ; Initialization
- D RTNINIT
- S INOA("~NOZIL")=1 ; boolean flag, no ZIL segments returned
- ; validate scrambled,seeded key/ticket from remote system
- S INTICK=$G(INTICK) I '$L(INTICK) D LOGERR("Logon ticket missing") Q
- S B=$P($G(^INTHPC(INBPN,7)),U,4) I '$L(B) D LOGERR("Missing Key Frame") Q
- I $$FRHASH(INTICK,B)'=@INV@("ZIL11") D LOGERR("Invalid framed ticket sent by remote system") Q
- ; validate remote IP address/port against values received from LoS
- I $G(INADDR)'=@INV@("ZIL2") D LOGERR("Remote IP address does not match IP address validated by CHCS Logon Server") Q
- I $G(INPORT)'=@INV@("ZIL3") D LOGERR("Remote port does not match port validated by CHCS Logon Server") Q
- ; validate user
- S INUSER=$$LOGON(.INV,.INOA,.INODA) K INOA("~NOZIL") I INUSER'>0 D LOGERR("Invalid LOGON: "_$P(INUSER,U,2)) Q
- ; validate remote user against values received from LoS
- I $G(INDUZ)'=INUSER D LOGERR("Remote user does not match user validated by CHCS Logon Server") Q
- ;
- ; any additional validation would follow here
- ;
- D ACCEPT,CLEANUP,LGNLOG^INHULOG(INUSER) ; successful logon
- Q
- ;
- LOGON(INV,INOA,INODA) ; $$function - Validate user, based on information sent
- ; by remote system (INV). Get information to return to remote system
- ; (INOA).
- ;
- ; Input:
- ; INV array - (req) ZIL7=requested division, ZIL8=access code,
- ; ZIL9=verify code. Note that validating a
- ; "requested" division is NOT currently implemented.
- ;
- ; Output:
- ; INOA array - (pbr) ZIL4=user, ZIL5=provider, ZIL6=timeout,
- ; ZIL10=ticket/key if LoS logon (not ApS logon).
- ; INODA array - (pbr) 1st subscript file#, 2nd subscript IEN.
- ;
- ; Function returns: USER IEN = successful user validation
- ; "0^Error msg" = failure
- ;
- ; Symbol table Input: - INANYONE 1 - Anyone can access,
- ; 0 - Provider access only
- ;
- N INH9,X,Y,Z,INHZERO
- D SETDT^UTDT
- ; access & verify code
- S INH9("AC")=$G(@INV@("ZIL8")),INH9("VC")=$G(@INV@("ZIL9"))
- ; requested divison
- S INH9("REQDIV")=$G(@INV@("ZIL7"))
- ; User's zero node is returned in Z
- S INH9("USER")=$$GETDUZ^INHULOG(INH9("AC"),INH9("VC"),.Z)
- ;
- I INH9("USER")'>0 Q "0^Invalid Access/Verify code"
- S X=$$DIVCHK^INHULOG(INH9("USER")) Q:'X "0^"_X ; validate division
- ; Determine if user is an authorized HCP
- S INH9("HCP")=$P($G(^DIC(3,INH9("USER"),8000)),"^") ; get provider
- ;;Folloing logic is specific to CHCS. Must be revised if used for IHS
- ;I '$G(INANYONE) S X=$$PWSPRO^ORGISPRO(INH9("USER")) Q:X "0^User '"_INH9("USER")_"' is not an authorized HCP"
- ; get remote system timeout value (used to determine if remote has
- ; disconnected w/out notifying connected system)
- S INH9("DTIME")=$$DTIME^INHULOG(INH9("USER"),900)
- S INHZERO=$G(^DIC(3,INH9("USER"),0))
- S INH9("FMACC")=$P(INHZERO,"^",4)
- S INH9("DEFDIV")=$P(INHZERO,"^",16)
- S INH9("MSIGN")=$P($G(^DIC(3,INH9("USER"),200)),"^",4)
- S INODA(3,INH9("USER"))="" S:'$G(INANYONE) INODA(6,INH9("HCP"))=""
- ; ZIL segment is returned in LoS Ack (not in ApS Ack)
- S:'$G(INOA("~NOZIL")) INOA("ZIL4")=INH9("USER"),INOA("ZIL5")=INH9("HCP"),INOA("ZIL6")=INH9("DTIME"),INOA("ZIL10")=$$TICKET^INHULOG,INOA("ZIL12")=INH9("FMACC"),INOA("ZIL13")=INH9("DEFDIV"),INOA("ZIL14")=INH9("MSIGN")
- ;
- Q INH9("USER") ; successful validation
- ;
- LOGOFF(INV,INOA) ; Lookup/Store call for ApS logoff msg
- S INOA("INACKTXT")="CHCS Logoff Error",INOA("INSTAT")="AE" ; in case of error
- ; note: logic derived from H^XUS, except no device calls are made
- S DUZ=+$G(DUZ) N A S A=$G(^ZUTL("XQ",$J,0)) I A,$D(^XUSEC(0,A,0)) L +^XUSEC(0,A,0):1 I D SETDT^UTDT S %=$P($H,",",2),$P(^XUSEC(0,A,0),U,4)=DT_(%\60#60/100+(%\3600)+(%#60/10000)/100) L -^XUSEC(0,A,0)
- K:$L($G(DUZ)) ^XMB7(DUZ,100,$$DEVID^%ZTOS),^($I),^($P) ; indicates where currently logged on
- D CLRSTOR^INHULOG ; clear scratch storage
- ; the application cleanup (see APPERR^ZU) would go here, if needed
- D ACCEPT ; Application Accept
- Q
- ;
- RTNINIT ; init return values, INOA & INODA array, error message into INOA
- K INOA,INODA S INODA="",INOA("INSTAT")="AE",INOA("INACKTXT")="Invalid CHCS Logon Attempt",INOA("INORIGID")=@INV@("MSH10")
- Q
- ;
- ACCEPT ; set "INSTAT" to Application Accept, KILL the error text
- K INOA("INACKTXT") S INOA("INSTAT")="AA"
- Q
- ;
- CLEANUP ; Cleanup following "successful" validation of logon message.
- ; Input: INUIF=UIF IEN of inbound msg
- ; Output: None.
- ;
- ; Delete information from ZIL segment(s) in inbound msg (security).
- L +^INTHU(INUIF,0):0 I D
- . N A,B,J M A=^INTHU(INUIF,3) S (B,J)=0 F S J=$O(A(J)) Q:'J I $E($G(A(J,0)),1,3)="ZIL" S A(J,0)="ZIL^<SEGMENT CLEARED>|CR|",B=1
- . I B K ^INTHU(INUIF,3) M ^INTHU(INUIF,3)=A
- . L -^INTHU(INUIF,0)
- Q
- ;
- FRHASH(INTICKET,INFRAME) ; $$function - frame the ticket, encrypt, return
- N H,L,X S L=$L(INFRAME),H=L+1\2,X=$E(INFRAME,1,H)_INTICKET_$E(INFRAME,H+1,L)
- D ^XUSHSH Q X
- ;
- NACK ; negative acknowledgement
- N % F %="ZIL4","ZIL5","ZIL6","ZIL10" S INOA(%)=""
- Q
- ;
- LOGERR(E) ; log error message E
- S INSTERR=$G(INSTERR) D ERROR^INHS(E,2)
- Q
- ;
- INHVCRV ; JC Hrubovcak ; 22 Oct 1999 15:49 ;
- +1 ;;3.01;BHL IHS Interfaces with GIS;;JUL 01, 2001
- +2 ;COPYRIGHT 1991-2000 SAIC
- +3 ; HL7/PWS logon utilities
- +4 QUIT
- +5 ;
- VALID(INV,INUIF,INOA,INODA) ; subroutine, VALIDate LoS logon request
- +1 ; Input:
- +2 ; INV array - (req) ZIL1=REQ, ZIL2=IP address, ZIL3=port, ZIL7=requested
- +3 ; division, ZIL8=access code, ZIL9=verify code
- +4 ; INUIF - (req) UNIVERSAL INTERFACE IEN
- +5 ;
- +6 ; Output:
- +7 ; INOA array - (pbr) ZIL1=REQ, ZIL4=user, ZIL5=provider, ZIL6=timeout,
- +8 ; ZIL10=ticket/key. These values are returned to
- +9 ; the remote system.
- +10 ; INODA array - (pbr) 1st subscript file#, 2nd subscript IEN. Not used.
- +11 ;
- +12 NEW B,INBPNAPS,INDSTP,INERR
- +13 ; Initialization
- +14 DO RTNINIT
- SET INOA("ZIL1")="REQ"
- +15 SET B=$$INPARMS^INHVCRL2(.INDSTP,.INPARMS,.INERR,INUIF)
- IF B
- DO LOGERR(.INERR)
- DO NACK
- QUIT
- +16 SET INBPNAPS=+$PIECE($GET(^INRHT(INPARMS(INDSTP,"TTIN"),0)),U,17)
- IF INBPNAPS'>0
- DO LOGERR("Missing Application Process pointer for INTERFACE TRANSACTION TYPE, '"_INPARMS(INDSTP,"TTIN01")_"'")
- DO NACK
- QUIT
- +17 ; validate IP address
- +18 SET B=$$VALIDIP^INHULOG(INBPNAPS,@INV@("ZIL2"))
- IF B
- DO LOGERR("Invalid remote IP address '"_@INV@("ZIL2")_"': "_$PIECE(B,U,2))
- DO NACK
- QUIT
- +19 ; validate user
- +20 SET B=$$LOGON(.INV,.INOA,.INODA)
- IF B'>0
- DO LOGERR("Invalid LOGON: "_$PIECE(B,U,2))
- DO NACK
- QUIT
- +21 ; create Application server (ApS)
- +22 SET B=$$NEWSVR^INHVCRV1(INBPNAPS,.INV,.INOA)
- IF B
- DO LOGERR("'Application Server creation' failed: "_B)
- DO NACK
- QUIT
- +23 ;
- +24 ; any additional validation would follow here
- +25 ;
- +26 ; successful logon
- DO ACCEPT
- DO CLEANUP
- +27 QUIT
- +28 ;
- REVALID(INV,INOA) ; subroutine, Validate ApS logon request
- +1 ; Input:
- +2 ; INV array - (req) ZIL1=ON, ZIL2=IP address, ZIL3=port, ZIL7=requested
- +3 ; division, ZIL8=access code, ZIL9=verify code,
- +4 ; ZIL11=scrambled,seeded key/ticket from remote sys
- +5 ;
- +6 ; Input passed from ApS (all required):
- +7 ; INADDR = IP address of remote server to connect to as a TCP client,
- +8 ; or null to open as a TCP server
- +9 ; INBPN = BACKGROUND PROCESS CONTROL IEN for ApS
- +10 ; INDUZ = USER IEN
- +11 ; INPORT = IP port to open (client or server)
- +12 ; INTICK = security ticket
- +13 ;
- +14 ; Output:
- +15 ; INOA array - (pbr) No ZIL segment values are returned to the remote
- +16 ; system (in the ApS Ack).
- +17 ; INODA array - 1st subscript file#, 2nd subscript IEN. Not used.
- +18 ;
- +19 NEW B,INUSER
- +20 ; Initialization
- +21 DO RTNINIT
- +22 ; boolean flag, no ZIL segments returned
- SET INOA("~NOZIL")=1
- +23 ; validate scrambled,seeded key/ticket from remote system
- +24 SET INTICK=$GET(INTICK)
- IF '$LENGTH(INTICK)
- DO LOGERR("Logon ticket missing")
- QUIT
- +25 SET B=$PIECE($GET(^INTHPC(INBPN,7)),U,4)
- IF '$LENGTH(B)
- DO LOGERR("Missing Key Frame")
- QUIT
- +26 IF $$FRHASH(INTICK,B)'=@INV@("ZIL11")
- DO LOGERR("Invalid framed ticket sent by remote system")
- QUIT
- +27 ; validate remote IP address/port against values received from LoS
- +28 IF $GET(INADDR)'=@INV@("ZIL2")
- DO LOGERR("Remote IP address does not match IP address validated by CHCS Logon Server")
- QUIT
- +29 IF $GET(INPORT)'=@INV@("ZIL3")
- DO LOGERR("Remote port does not match port validated by CHCS Logon Server")
- QUIT
- +30 ; validate user
- +31 SET INUSER=$$LOGON(.INV,.INOA,.INODA)
- KILL INOA("~NOZIL")
- IF INUSER'>0
- DO LOGERR("Invalid LOGON: "_$PIECE(INUSER,U,2))
- QUIT
- +32 ; validate remote user against values received from LoS
- +33 IF $GET(INDUZ)'=INUSER
- DO LOGERR("Remote user does not match user validated by CHCS Logon Server")
- QUIT
- +34 ;
- +35 ; any additional validation would follow here
- +36 ;
- +37 ; successful logon
- DO ACCEPT
- DO CLEANUP
- DO LGNLOG^INHULOG(INUSER)
- +38 QUIT
- +39 ;
- LOGON(INV,INOA,INODA) ; $$function - Validate user, based on information sent
- +1 ; by remote system (INV). Get information to return to remote system
- +2 ; (INOA).
- +3 ;
- +4 ; Input:
- +5 ; INV array - (req) ZIL7=requested division, ZIL8=access code,
- +6 ; ZIL9=verify code. Note that validating a
- +7 ; "requested" division is NOT currently implemented.
- +8 ;
- +9 ; Output:
- +10 ; INOA array - (pbr) ZIL4=user, ZIL5=provider, ZIL6=timeout,
- +11 ; ZIL10=ticket/key if LoS logon (not ApS logon).
- +12 ; INODA array - (pbr) 1st subscript file#, 2nd subscript IEN.
- +13 ;
- +14 ; Function returns: USER IEN = successful user validation
- +15 ; "0^Error msg" = failure
- +16 ;
- +17 ; Symbol table Input: - INANYONE 1 - Anyone can access,
- +18 ; 0 - Provider access only
- +19 ;
- +20 NEW INH9,X,Y,Z,INHZERO
- +21 DO SETDT^UTDT
- +22 ; access & verify code
- +23 SET INH9("AC")=$GET(@INV@("ZIL8"))
- SET INH9("VC")=$GET(@INV@("ZIL9"))
- +24 ; requested divison
- +25 SET INH9("REQDIV")=$GET(@INV@("ZIL7"))
- +26 ; User's zero node is returned in Z
- +27 SET INH9("USER")=$$GETDUZ^INHULOG(INH9("AC"),INH9("VC"),.Z)
- +28 ;
- +29 IF INH9("USER")'>0
- QUIT "0^Invalid Access/Verify code"
- +30 ; validate division
- SET X=$$DIVCHK^INHULOG(INH9("USER"))
- IF 'X
- QUIT "0^"_X
- +31 ; Determine if user is an authorized HCP
- +32 ; get provider
- SET INH9("HCP")=$PIECE($GET(^DIC(3,INH9("USER"),8000)),"^")
- +33 ;;Folloing logic is specific to CHCS. Must be revised if used for IHS
- +34 ;I '$G(INANYONE) S X=$$PWSPRO^ORGISPRO(INH9("USER")) Q:X "0^User '"_INH9("USER")_"' is not an authorized HCP"
- +35 ; get remote system timeout value (used to determine if remote has
- +36 ; disconnected w/out notifying connected system)
- +37 SET INH9("DTIME")=$$DTIME^INHULOG(INH9("USER"),900)
- +38 SET INHZERO=$GET(^DIC(3,INH9("USER"),0))
- +39 SET INH9("FMACC")=$PIECE(INHZERO,"^",4)
- +40 SET INH9("DEFDIV")=$PIECE(INHZERO,"^",16)
- +41 SET INH9("MSIGN")=$PIECE($GET(^DIC(3,INH9("USER"),200)),"^",4)
- +42 SET INODA(3,INH9("USER"))=""
- IF '$GET(INANYONE)
- SET INODA(6,INH9("HCP"))=""
- +43 ; ZIL segment is returned in LoS Ack (not in ApS Ack)
- +44 IF '$GET(INOA("~NOZIL"))
- SET INOA("ZIL4")=INH9("USER")
- SET INOA("ZIL5")=INH9("HCP")
- SET INOA("ZIL6")=INH9("DTIME")
- SET INOA("ZIL10")=$$TICKET^INHULOG
- SET INOA("ZIL12")=INH9("FMACC")
- SET INOA("ZIL13")=INH9("DEFDIV")
- SET INOA("ZIL14")=INH9("MSIGN")
- +45 ;
- +46 ; successful validation
- QUIT INH9("USER")
- +47 ;
- LOGOFF(INV,INOA) ; Lookup/Store call for ApS logoff msg
- +1 ; in case of error
- SET INOA("INACKTXT")="CHCS Logoff Error"
- SET INOA("INSTAT")="AE"
- +2 ; note: logic derived from H^XUS, except no device calls are made
- +3 SET DUZ=+$GET(DUZ)
- NEW A
- SET A=$GET(^ZUTL("XQ",$JOB,0))
- IF A
- IF $DATA(^XUSEC(0,A,0))
- LOCK +^XUSEC(0,A,0):1
- IF $TEST
- DO SETDT^UTDT
- SET %=$PIECE($HOROLOG,",",2)
- SET $PIECE(^XUSEC(0,A,0),U,4)=DT_(%\60#60/100+(%\3600)+(%#60/10000)/100)
- LOCK -^XUSEC(0,A,0)
- +4 ; indicates where currently logged on
- IF $LENGTH($GET(DUZ))
- KILL ^XMB7(DUZ,100,$$DEVID^%ZTOS),^($IO),^($PRINCIPAL)
- +5 ; clear scratch storage
- DO CLRSTOR^INHULOG
- +6 ; the application cleanup (see APPERR^ZU) would go here, if needed
- +7 ; Application Accept
- DO ACCEPT
- +8 QUIT
- +9 ;
- RTNINIT ; init return values, INOA & INODA array, error message into INOA
- +1 KILL INOA,INODA
- SET INODA=""
- SET INOA("INSTAT")="AE"
- SET INOA("INACKTXT")="Invalid CHCS Logon Attempt"
- SET INOA("INORIGID")=@INV@("MSH10")
- +2 QUIT
- +3 ;
- ACCEPT ; set "INSTAT" to Application Accept, KILL the error text
- +1 KILL INOA("INACKTXT")
- SET INOA("INSTAT")="AA"
- +2 QUIT
- +3 ;
- CLEANUP ; Cleanup following "successful" validation of logon message.
- +1 ; Input: INUIF=UIF IEN of inbound msg
- +2 ; Output: None.
- +3 ;
- +4 ; Delete information from ZIL segment(s) in inbound msg (security).
- +5 LOCK +^INTHU(INUIF,0):0
- IF $TEST
- Begin DoDot:1
- +6 NEW A,B,J
- MERGE A=^INTHU(INUIF,3)
- SET (B,J)=0
- FOR
- SET J=$ORDER(A(J))
- IF 'J
- QUIT
- IF $EXTRACT($GET(A(J,0)),1,3)="ZIL"
- SET A(J,0)="ZIL^<SEGMENT CLEARED>|CR|"
- SET B=1
- +7 IF B
- KILL ^INTHU(INUIF,3)
- MERGE ^INTHU(INUIF,3)=A
- +8 LOCK -^INTHU(INUIF,0)
- End DoDot:1
- +9 QUIT
- +10 ;
- FRHASH(INTICKET,INFRAME) ; $$function - frame the ticket, encrypt, return
- +1 NEW H,L,X
- SET L=$LENGTH(INFRAME)
- SET H=L+1\2
- SET X=$EXTRACT(INFRAME,1,H)_INTICKET_$EXTRACT(INFRAME,H+1,L)
- +2 DO ^XUSHSH
- QUIT X
- +3 ;
- NACK ; negative acknowledgement
- +1 NEW %
- FOR %="ZIL4","ZIL5","ZIL6","ZIL10"
- SET INOA(%)=""
- +2 QUIT
- +3 ;
- LOGERR(E) ; log error message E
- +1 SET INSTERR=$GET(INSTERR)
- DO ERROR^INHS(E,2)
- +2 QUIT
- +3 ;