- PSNOSKEY ;BIR/SJA-PPS-N SSH Key Management ;09/16/2016
- ;;4.0;NATIONAL DRUG FILE;**513,563,575**; 30 Oct 98;Build 22
- ;
- ;SAC EXEMPTION 202402221226-01: Allows the use of the $ZF(-100) function
- ;
- ; taken mostly from: PSOSPMKY - State Prescription Monitoring Program - SSH Key Management
- ;
- EN ; -- Entry point
- N X,Y,PSNOS,LOCALDIR,X1,DIR,ENCRBITS,PSNDSA
- ;
- ACTION ; -- SSH Key Action
- K DIR S DIR("A")="Action"
- S DIR(0)="S^V:View Public SSH Key;C:Create New SSH Key Pair;D:Delete SSH Key Pair;H:Help with SSH Keys",DIR("B")="V"
- D ^DIR
- I $D(DUOUT)!($D(DIRUT)) G END
- I Y="C"!(Y="D"),'$D(^XUSEC("PSN PPS COORD",DUZ)) D G ACTION
- .W !!,"The PSN PPS COORD security key is required for this action.",$C(7)
- K ^TMP("PSNPUBKY",$J) D RETRIEVE("PUB")
- I Y="V"!(Y="D"),'$D(^TMP("PSNPUBKY",$J)) D G ACTION
- .W !!,"[No SSH Key Pair found]",$C(7) D PAUSE
- I Y="C"!(Y="D") D SIG^XUSESIG I X="^"!($G(X1)="") W:$G(X1)="" " SIGNATURE NOT VERIFIED",$C(7) G ACTION
- ;
- ; -- View Public SSH Key
- I Y="V" W ! D VIEW,PAUSE G ACTION
- ;
- ; -- Create New SSH Key Pair
- I Y="C" D G ACTION
- .I '$$ASK() W !!,"No action taken!",$C(7) Q
- .S PSNOS=$$ENDOS()
- .S LOCALDIR=$$GET1^DIQ(57.23,1,$S(PSNOS["VMS":1,1:3))
- .I LOCALDIR="" D Q
- ..W !!,"The ",$S(PSNOS["VMS":"OPEN VMS",1:"UNIX/LINUX")," LOCAL DIRECTORY parameter is missing. Please, update it in"
- ..W !,"the 'PPS-N Site Parameters (Enter/Edit)' option and try again.",$C(7) D PAUSE
- .K DIR S DIR("A")="SSH Key Encryption Type",DIR("?")="^D HELP1^PSNOSKEY"
- .;PSN*4*575 Add ECDSA
- .S PSNDSA=$$GET1^DIQ(57.23,1,11,"I")
- .I 'PSNDSA S DIR(0)="S^RSA:Rivest, Shamir & Adleman (RSA)"
- .I PSNDSA S DIR(0)="S^RSA:Rivest, Shamir & Adleman (RSA);ECDSA:Elliptic Curve Digital Signature Algorithm (ECDSA)"
- .S DIR("B")="RSA" D ^DIR I $D(DUOUT)!($D(DIRUT)) Q
- .S ENCRTYPE=Y
- . ;p575 prompt for bit size for ECDSA
- . I ENCRTYPE="ECDSA" D I $D(DUOUT)!($D(DIRUT)) Q
- . . K DIR S DIR("A")="ECDSA encryption key size (bit size)",DIR("?")="Available key sizes are 256 bits, 384 bits, or 521 bits. Also referred to as key length."
- . . S DIR(0)="S^256:256 bits;384:384 bits;521:521 bits"
- . . S DIR("B")="256" D ^DIR
- . S ENCRBITS=$S(ENCRTYPE="ECDSA":Y,1:"")
- .I $D(^TMP("PSNPUBKY",$J)) D
- ..W !!,$G(IOBON),"WARNING:",$G(IOBOFF)," You may be overwriting SSH Keys that are currently in use.",$C(7)
- .K DIR S DIR("A")="Confirm Creation of SSH Keys",DIR(0)="Y",DIR("B")="NO"
- .W ! D ^DIR I $D(DIRUT)!$D(DUOUT)!'Y Q
- .;
- .; -- Deleting Existing SSH Key
- .I $D(^TMP("PSNPUBKY",$J)) D DELETE
- .W !!,"Creating New SSH Keys, please wait..."
- . ;p575 removing the task off logic, unnecessary
- .;N ZTRTN,ZTIO,ZTDESC,ZTDTH,ZTSK
- .;S ZTRTN="NEWKEY^PSNOSKEY("""_ENCRTYPE_""")",ZTIO="",ZTDESC="SSH Key Generation",ZTDTH=$$NOW^XLFDT()
- .;D ^%ZTLOAD K ZTSK,^TMP("PSNPUBKY",$J)
- .;F I=1:1:30 D RETRIEVE("PUB") Q:$D(^TMP("PSNPUBKY",$J)) H 1
- .; -- If unable to create the key via Taskman after 30 seconds, creates them in the foreground
- .;I '$D(^TMP("PSNPUBKY",$J)) D
- .D NEWKEY(ENCRTYPE),RETRIEVE("PUB")
- .I '$D(^TMP("PSNPUBKY",$J)) D
- ..W !!,"There was a problem with the generation of the new SSH Key Pair."
- ..W !,"Please try again and if the problem persists contact IT Support.",$C(7) D PAUSE
- .E W "Done",$C(7)
- ;
- ; -- Delete SSH Key Pair
- I Y="D" D G ACTION
- .D RETRIEVE("PUB")
- .I '$D(^TMP("PSNPUBKY",$J)) W !!,"[No SSH Key Pair found]",$C(7) Q
- .W !!,$G(IOBON),"WARNING:",$G(IOBOFF)," You may be deleting SSH Keys that are currently in use.",$C(7)
- .K DIR S DIR("A")="Confirm Deletion of SSH Keys",DIR(0)="Y",DIR("B")="NO"
- .W ! D ^DIR I $D(DIRUT)!$D(DUOUT)!'Y Q
- .W !!,"Deleting SSH Keys..." D DELETE H 1 W "Done",$C(7)
- ; SSH Key Help
- I Y="H" D HELP G ACTION
- G ACTION
- ;
- END ;
- Q
- ;
- NEWKEY(ENCRTYPE) ; Generate and store a pair of SSH keys
- ; Input: (o) ENCRTYPE - SSH Encryption Type (DSA/RSA) (Default: RSA)
- ;
- N LOCALDIR,DTE,PSNOS,KEYFILE,PV,FILE2DEL,LN,OVFLN,PSNSPC,KYTXT,SAVEKEY,DIE,DR,DA
- S PSNOS=$$OS^%ZOSV()
- S LOCALDIR=$$GET1^DIQ(57.23,1,$S(PSNOS["VMS":1,1:3)) I LOCALDIR="" Q ;Error: Missing directory
- ;PSN*4*575 handle ECDSA
- ;I $G(ENCRTYPE)'="RSA" S ENCRTYPE="DSA"
- S ENCRTYPE=$S($G(ENCRTYPE)="ECDSA":"ECDSA",1:"RSA")
- ; -- LOCK to avoid OS files overwrite
- F S DTE=+$$FMTHL7^XLFDT($$HTFM^XLFDT($H)) S KEYFILE="KY"_DTE L +@KEYFILE:0 Q:$T H 2
- ; -- Deleting existing SSH Keys first
- D DELETE
- ;
- ; -- OpenVMS SSH Key Generation
- I PSNOS["VMS" D
- .N COMFILE S COMFILE="COM"_DTE_".COM"
- .D OPEN^%ZISH("COMFILE",LOCALDIR,COMFILE,"W")
- .D USE^%ZISUTL("COMFILE")
- .W "SSH_KEYGEN == ""$SYS$SYSTEM:TCPIP$SSH_SSH-KEYGEN2.EXE""",!
- .W "SSH_KEYGEN -t "_$$LOW^XLFSTR($G(ENCRTYPE))_" -""P"" "_LOCALDIR_KEYFILE,!
- .D CLOSE^%ZISH("COMFILE")
- .X "S PV=$ZF(-1,""@"_LOCALDIR_COMFILE_""")"
- .S FILE2DEL(COMFILE)="",FILE2DEL(KEYFILE_".")="",FILE2DEL(KEYFILE_".PUB")=""
- ;
- ; -- Linux/Unix SSH Key Generation
- I PSNOS["UNIX" D
- .I '$$DIREXIST^PSNFTP2(LOCALDIR) D MAKEDIR^PSNFTP2(LOCALDIR)
- . S ENCRBITS=$S($G(ENCRBITS):ENCRBITS,1:"")
- . S ENCRTYPE=$$LOW^XLFSTR($G(ENCRTYPE))
- . I ($P($$VERSION^%ZOSV(1),"/",1)[("Cache")) D
- . . S:ENCRBITS ENCRBITS=" -b "_ENCRBITS
- . . X "S PV=$ZF(-1,""ssh-keygen -q -N '' -C '' -t "_$$LOW^XLFSTR($G(ENCRTYPE))_" -f "_LOCALDIR_KEYFILE_ENCRBITS_""")"
- . I $P($$VERSION^%ZOSV(1),"/",1)'[("Cache") D
- . . I ENCRBITS S PV=$ZF(-100,"","ssh-keygen","-q","-t",ENCRTYPE,"-b",ENCRBITS,"-f",LOCALDIR_KEYFILE,"-N","","-C","")
- . . I ENCRBITS="" S PV=$ZF(-100,"","ssh-keygen","-q","-t",ENCRTYPE,"-f",LOCALDIR_KEYFILE,"-N","","-C","")
- .S FILE2DEL(KEYFILE)="",FILE2DEL(KEYFILE_".pub")=""
- ;
- K ^TMP("PSNPRVKY",$J),^TMP("PSNPUBKY",$J)
- ; -- Retrieving SSH Private Key Content
- S X=$$FTG^%ZISH(LOCALDIR,KEYFILE_$S(PSNOS["VMS":".",1:""),$NAME(^TMP("PSNPRVKY",$J,1)),3)
- I '$D(^TMP("PSNPRVKY",$J,1)) Q
- ; -- Retrieving SSH Public Key Content
- S X=$$FTG^%ZISH(LOCALDIR,KEYFILE_$S(PSNOS["VMS":".PUB",1:".pub"),$NAME(^TMP("PSNPUBKY",$J,1)),3)
- I '$D(^TMP("PSNPUBKY",$J,1)) Q
- ;
- ; -- Deleting temporary files used to generate the keys
- D DEL^%ZISH(LOCALDIR,"FILE2DEL")
- ;
- ; -- Saving new SSH Keys content in the PPS-N UPDATE CONTROL file (#57.23)
- F PSNSPC="PSNPRVKY","PSNPUBKY" D
- .K KYTXT,SAVEKEY
- .F LN=1:1 Q:'$D(^TMP(PSNSPC,$J,LN)) D
- ..; Unix/Linux Public SSH Key has no line-feed
- ..I PSNOS["UNIX",PSNSPC="PSNPUBKY" D Q
- ...S KYTXT(1)=^TMP(PSNSPC,$J,LN)
- ...F OVFLN=1:1 Q:'$D(^TMP(PSNSPC,$J,LN,"OVF",OVFLN)) D
- ....S KYTXT(1)=$G(KYTXT(1))_^TMP(PSNSPC,$J,LN,"OVF",OVFLN)
- ..S KYTXT(LN)=$$ENCRYP^XUSRB1(^TMP(PSNSPC,$J,LN))
- .I PSNOS["UNIX",PSNSPC="PSNPUBKY" S KYTXT(1)=$$ENCRYP^XUSRB1(KYTXT(1))
- .S SAVEKEY(57.23,"1,",$S(PSNSPC="PSNPRVKY":33,1:34))="KYTXT"
- .D UPDATE^DIE("","SAVEKEY")
- .K ^TMP(PSNSPC,$J)
- ;
- ; -- Saving SSH Key Format (SSH2/OpenSSH) and Encryption Type (DSA/RSA) fields
- K DIE S DIE="^PS(57.23,",DA=1
- S DR="39///"_$S(PSNOS["VMS":"SSH2",1:"OSSH")_";41///"_ENCRTYPE D ^DIE
- L -@KEYFILE
- Q
- ;
- RETRIEVE(KTYPE) ; Retrieve the SSH Key into the ^TMP global
- ; (o) KTYPE - SSH Key Type (PUB - Public/PRV - PRivate) (Default: Public)
- ;Output: ^TMP("PSN[PUB/PRV]KY",$J,0)="SSH Key Format (SSH2/OpenSSH)^Encryption Type (DSA/RSA)"
- ; ^TMP("PSN[PUB/PRV]KY",$J,1-N)=[SSH Key Content]
- ;
- N X,LN,KYTXT,PSNSPC
- I $G(KTYPE)'="PRV" S KTYPE="PUB"
- S X=$$GET1^DIQ(57.23,"1,",$S(KTYPE="PRV":33,1:34),,"KYTXT")
- S PSNSPC=$S(KTYPE="PRV":"PSNPRVKY",1:"PSNPUBKY")
- K ^TMP(PSNSPC,$J)
- F LN=1:1 Q:'$D(KYTXT(LN)) S ^TMP(PSNSPC,$J,LN)=$$DECRYP^XUSRB1(KYTXT(LN))
- I $D(^TMP(PSNSPC,$J)) D
- .S ^TMP(PSNSPC,$J,0)=$$GET1^DIQ(57.23,1,39,"I")_"^"_$$GET1^DIQ(57.23,1,41,"I")
- Q
- ;
- VIEW ; Displays the SSH Public Key
- ; ^TMP("PSNPUBKY",$J,0)="SSH Key Format (SSH2/OpenSSH)^Encryption Type (DSA/RSA)"
- ; ^TMP("PSNPUBKY",$J,1-N)=[SSH Key Content]
- N SSHKEY,DASHLN
- S $P(DASHLN,"-",81)="",SSHKEY=$$OPENSSH()
- W !,"Public SSH Key (",$P($G(^TMP("PSNPUBKY",$J,0)),"^",2),") content (does not include dash lines):"
- W !,DASHLN
- F Q:$L(SSHKEY)=0 W !,$E(SSHKEY,1,80) S SSHKEY=$E(SSHKEY,81,9999)
- W !,DASHLN
- Q
- ;
- DELETE ; Delete Both SSH Keys associated
- N DIE,DA,DR
- S DIE="^PS(57.23,",DA=1,DR="39///@;41///@;33///@;34///@" D ^DIE
- K ^TMP("PSNPRVKY",$J),^TMP("PSNPUBKY",$J)
- Q
- ;
- OPENSSH() ; Returns the SSH Public Key in OpenSSH Format (Converts if necessary)
- ;Input: ^TMP("PSNPUBKY",$J,0)="SSH Key Format (SSH2/OpenSSH)^Encryption Type (DSA/RSA)"
- ; ^TMP("PSNPUBKY",$J,1-N)=[SSH Key Content]
- ;
- N OPENSSH,ENCRTYPE,LN
- S OPENSSH=""
- I $P($G(^TMP("PSNPUBKY",$J,0)),"^")="SSH2" D
- .S ENCRTYPE=$P($G(^TMP("PSNPUBKY",$J,0)),"^",2),OPENSSH=""
- .F LN=5:1 Q:'$D(^TMP("PSNPUBKY",$J,LN)) D
- ..I $G(^TMP("PSNPUBKY",$J,LN))["---- END" Q
- ..S OPENSSH=OPENSSH_$G(^TMP("PSNPUBKY",$J,LN))
- .S OPENSSH=$S(ENCRTYPE="RSA":"ssh-rsa",1:"ssh-dss")_" "_OPENSSH
- E D
- .F LN=1:1 Q:'$D(^TMP("PSNPUBKY",$J,LN)) D
- ..S OPENSSH=OPENSSH_$G(^TMP("PSNPUBKY",$J,LN))
- Q OPENSSH
- ;
- ENDOS() ; Returns the Backend Server Operating System (OS)
- ;Output: Backend Operating System (e.,g., "VMS", "UNIX")
- ;
- N ENDOS,ZTRTN,ZTIO,ZTDESC,ZTDTH,ZTSK,I
- K ^XTMP("PSNKEY",$J,"OS")
- S ENDOS="",ZTRTN="SETOS^PSNOSKEY("_$J_")",ZTIO=""
- S ZTDESC="Backend Server OS Check"
- S ZTDTH=$$NOW^XLFDT() D ^%ZTLOAD
- F I=1:1:5 S ENDOS=$G(^XTMP("PSNKEY",$J,"OS")) Q:ENDOS'="" H 1
- K ^XTMP("PSNKEY",$J,"OS")
- Q $S(ENDOS'="":ENDOS,1:$$OS^%ZOSV())
- ;
- SETOS(JOB) ; Sets the Operating Systems in ^XTMP("PSNKEY",$J,"OS") (Called via Taskman)
- ;Input: JOB - $Job value from calling process
- S ^XTMP("PSNKEY",JOB,"OS")=$$OS^%ZOSV()
- Q
- ;
- ;PSN*4*575 UPDATE HELP TEXT WORDING FOR ECDSA
- HELP ; Encryption Type Help
- W !!,"Secure SHell (SSH) Encryption Keys are used to allow data file download."
- W !,"Follow the steps below to successfully setup data file download from Austin "
- W !,"server to VistA sites:",!
- W !,"Step 1: Select the 'C' (Create New SSH Key Pair) Action and follow the prompts"
- W !," to create a new pair of SSH keys. If you already have an existing SSH"
- W !," Key Pair you can skip this step."
- W !," You can check whether you already have an existing SSH Key Pair"
- W !," through the 'V' (View Public SSH Key) Action."
- W !,""
- D HELP1,PAUSE
- W !!,"Step 2: Share the Public SSH Key content with the PPS-N SFTP server (Austin)."
- W !," In order to successfully establish the data download files, the SFTP "
- W !," server at Austin needs to install/configure the new SSH Key created in"
- W !," step 1 for the user id they assigned to your site. Use the 'V' (View "
- W !," Public SSH Key) Action to retrieve the content of the Public SSH key."
- W !," The Public SSH Key should not contain line-feed characters, therefore "
- W !," after you copy & paste it from the terminal emulator into an email or "
- W !," text editor make sure it contains only one line of text (no wrapping)."
- Q
- ;
- HELP1 ; Encryption Type Help
- W !," Encryption Type: RSA or ECDSA?"
- W !," -----------------------------------"
- W !," Rivest, Shamir & Adleman (RSA) has been one of the most common"
- W !," encryption algorithms used by the IT industry for securely sharing data."
- W !,""
- W !," Elliptic Curve Digital Signature Algorithm (ECDSA) is a more complex"
- W !," public key cryptography encryption algorithm that is now supported by"
- W !," the VA. If ECDSA is selected you will be prompted to enter the Bit size."
- W !," Valid selections are 256, 384 or 521."
- W !,""
- W !," You will need to contact the Austin SFTP server support to determine"
- W !," which type to select."
- Q
- PAUSE ; Pauses screen until user hits Return
- W ! K DIR S DIR("A")="Press Return to continue",DIR(0)="E" D ^DIR
- Q
- ;
- ASK() ; confirm creating new pair
- N Y S Y=0 Q:'$D(^TMP("PSNPUBKY",$J)) 1
- K DIRUT,DUOUT,DIR,X,Y S DIR(0)="Y",DIR("?")="Please enter Y or N."
- S DIR("A")="Do you want to delete existing key pair and create new pair" W !!
- S DIR("B")="NO" D ^DIR
- Q Y
- --- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HPSNOSKEY 12146 printed Mar 13, 2025@21:29:11 Page 2
- PSNOSKEY ;BIR/SJA-PPS-N SSH Key Management ;09/16/2016
- +1 ;;4.0;NATIONAL DRUG FILE;**513,563,575**; 30 Oct 98;Build 22
- +2 ;
- +3 ;SAC EXEMPTION 202402221226-01: Allows the use of the $ZF(-100) function
- +4 ;
- +5 ; taken mostly from: PSOSPMKY - State Prescription Monitoring Program - SSH Key Management
- +6 ;
- EN ; -- Entry point
- +1 NEW X,Y,PSNOS,LOCALDIR,X1,DIR,ENCRBITS,PSNDSA
- +2 ;
- ACTION ; -- SSH Key Action
- +1 KILL DIR
- SET DIR("A")="Action"
- +2 SET DIR(0)="S^V:View Public SSH Key;C:Create New SSH Key Pair;D:Delete SSH Key Pair;H:Help with SSH Keys"
- SET DIR("B")="V"
- +3 DO ^DIR
- +4 IF $DATA(DUOUT)!($DATA(DIRUT))
- GOTO END
- +5 IF Y="C"!(Y="D")
- IF '$DATA(^XUSEC("PSN PPS COORD",DUZ))
- Begin DoDot:1
- +6 WRITE !!,"The PSN PPS COORD security key is required for this action.",$CHAR(7)
- End DoDot:1
- GOTO ACTION
- +7 KILL ^TMP("PSNPUBKY",$JOB)
- DO RETRIEVE("PUB")
- +8 IF Y="V"!(Y="D")
- IF '$DATA(^TMP("PSNPUBKY",$JOB))
- Begin DoDot:1
- +9 WRITE !!,"[No SSH Key Pair found]",$CHAR(7)
- DO PAUSE
- End DoDot:1
- GOTO ACTION
- +10 IF Y="C"!(Y="D")
- DO SIG^XUSESIG
- IF X="^"!($GET(X1)="")
- if $GET(X1)=""
- WRITE " SIGNATURE NOT VERIFIED",$CHAR(7)
- GOTO ACTION
- +11 ;
- +12 ; -- View Public SSH Key
- +13 IF Y="V"
- WRITE !
- DO VIEW
- DO PAUSE
- GOTO ACTION
- +14 ;
- +15 ; -- Create New SSH Key Pair
- +16 IF Y="C"
- Begin DoDot:1
- +17 IF '$$ASK()
- WRITE !!,"No action taken!",$CHAR(7)
- QUIT
- +18 SET PSNOS=$$ENDOS()
- +19 SET LOCALDIR=$$GET1^DIQ(57.23,1,$SELECT(PSNOS["VMS":1,1:3))
- +20 IF LOCALDIR=""
- Begin DoDot:2
- +21 WRITE !!,"The ",$SELECT(PSNOS["VMS":"OPEN VMS",1:"UNIX/LINUX")," LOCAL DIRECTORY parameter is missing. Please, update it in"
- +22 WRITE !,"the 'PPS-N Site Parameters (Enter/Edit)' option and try again.",$CHAR(7)
- DO PAUSE
- End DoDot:2
- QUIT
- +23 KILL DIR
- SET DIR("A")="SSH Key Encryption Type"
- SET DIR("?")="^D HELP1^PSNOSKEY"
- +24 ;PSN*4*575 Add ECDSA
- +25 SET PSNDSA=$$GET1^DIQ(57.23,1,11,"I")
- +26 IF 'PSNDSA
- SET DIR(0)="S^RSA:Rivest, Shamir & Adleman (RSA)"
- +27 IF PSNDSA
- SET DIR(0)="S^RSA:Rivest, Shamir & Adleman (RSA);ECDSA:Elliptic Curve Digital Signature Algorithm (ECDSA)"
- +28 SET DIR("B")="RSA"
- DO ^DIR
- IF $DATA(DUOUT)!($DATA(DIRUT))
- QUIT
- +29 SET ENCRTYPE=Y
- +30 ;p575 prompt for bit size for ECDSA
- +31 IF ENCRTYPE="ECDSA"
- Begin DoDot:2
- +32 KILL DIR
- SET DIR("A")="ECDSA encryption key size (bit size)"
- SET DIR("?")="Available key sizes are 256 bits, 384 bits, or 521 bits. Also referred to as key length."
- +33 SET DIR(0)="S^256:256 bits;384:384 bits;521:521 bits"
- +34 SET DIR("B")="256"
- DO ^DIR
- End DoDot:2
- IF $DATA(DUOUT)!($DATA(DIRUT))
- QUIT
- +35 SET ENCRBITS=$SELECT(ENCRTYPE="ECDSA":Y,1:"")
- +36 IF $DATA(^TMP("PSNPUBKY",$JOB))
- Begin DoDot:2
- +37 WRITE !!,$GET(IOBON),"WARNING:",$GET(IOBOFF)," You may be overwriting SSH Keys that are currently in use.",$CHAR(7)
- End DoDot:2
- +38 KILL DIR
- SET DIR("A")="Confirm Creation of SSH Keys"
- SET DIR(0)="Y"
- SET DIR("B")="NO"
- +39 WRITE !
- DO ^DIR
- IF $DATA(DIRUT)!$DATA(DUOUT)!'Y
- QUIT
- +40 ;
- +41 ; -- Deleting Existing SSH Key
- +42 IF $DATA(^TMP("PSNPUBKY",$JOB))
- DO DELETE
- +43 WRITE !!,"Creating New SSH Keys, please wait..."
- +44 ;p575 removing the task off logic, unnecessary
- +45 ;N ZTRTN,ZTIO,ZTDESC,ZTDTH,ZTSK
- +46 ;S ZTRTN="NEWKEY^PSNOSKEY("""_ENCRTYPE_""")",ZTIO="",ZTDESC="SSH Key Generation",ZTDTH=$$NOW^XLFDT()
- +47 ;D ^%ZTLOAD K ZTSK,^TMP("PSNPUBKY",$J)
- +48 ;F I=1:1:30 D RETRIEVE("PUB") Q:$D(^TMP("PSNPUBKY",$J)) H 1
- +49 ; -- If unable to create the key via Taskman after 30 seconds, creates them in the foreground
- +50 ;I '$D(^TMP("PSNPUBKY",$J)) D
- +51 DO NEWKEY(ENCRTYPE)
- DO RETRIEVE("PUB")
- +52 IF '$DATA(^TMP("PSNPUBKY",$JOB))
- Begin DoDot:2
- +53 WRITE !!,"There was a problem with the generation of the new SSH Key Pair."
- +54 WRITE !,"Please try again and if the problem persists contact IT Support.",$CHAR(7)
- DO PAUSE
- End DoDot:2
- +55 IF '$TEST
- WRITE "Done",$CHAR(7)
- End DoDot:1
- GOTO ACTION
- +56 ;
- +57 ; -- Delete SSH Key Pair
- +58 IF Y="D"
- Begin DoDot:1
- +59 DO RETRIEVE("PUB")
- +60 IF '$DATA(^TMP("PSNPUBKY",$JOB))
- WRITE !!,"[No SSH Key Pair found]",$CHAR(7)
- QUIT
- +61 WRITE !!,$GET(IOBON),"WARNING:",$GET(IOBOFF)," You may be deleting SSH Keys that are currently in use.",$CHAR(7)
- +62 KILL DIR
- SET DIR("A")="Confirm Deletion of SSH Keys"
- SET DIR(0)="Y"
- SET DIR("B")="NO"
- +63 WRITE !
- DO ^DIR
- IF $DATA(DIRUT)!$DATA(DUOUT)!'Y
- QUIT
- +64 WRITE !!,"Deleting SSH Keys..."
- DO DELETE
- HANG 1
- WRITE "Done",$CHAR(7)
- End DoDot:1
- GOTO ACTION
- +65 ; SSH Key Help
- +66 IF Y="H"
- DO HELP
- GOTO ACTION
- +67 GOTO ACTION
- +68 ;
- END ;
- +1 QUIT
- +2 ;
- NEWKEY(ENCRTYPE) ; Generate and store a pair of SSH keys
- +1 ; Input: (o) ENCRTYPE - SSH Encryption Type (DSA/RSA) (Default: RSA)
- +2 ;
- +3 NEW LOCALDIR,DTE,PSNOS,KEYFILE,PV,FILE2DEL,LN,OVFLN,PSNSPC,KYTXT,SAVEKEY,DIE,DR,DA
- +4 SET PSNOS=$$OS^%ZOSV()
- +5 ;Error: Missing directory
- SET LOCALDIR=$$GET1^DIQ(57.23,1,$SELECT(PSNOS["VMS":1,1:3))
- IF LOCALDIR=""
- QUIT
- +6 ;PSN*4*575 handle ECDSA
- +7 ;I $G(ENCRTYPE)'="RSA" S ENCRTYPE="DSA"
- +8 SET ENCRTYPE=$SELECT($GET(ENCRTYPE)="ECDSA":"ECDSA",1:"RSA")
- +9 ; -- LOCK to avoid OS files overwrite
- +10 FOR
- SET DTE=+$$FMTHL7^XLFDT($$HTFM^XLFDT($HOROLOG))
- SET KEYFILE="KY"_DTE
- LOCK +@KEYFILE:0
- if $TEST
- QUIT
- HANG 2
- +11 ; -- Deleting existing SSH Keys first
- +12 DO DELETE
- +13 ;
- +14 ; -- OpenVMS SSH Key Generation
- +15 IF PSNOS["VMS"
- Begin DoDot:1
- +16 NEW COMFILE
- SET COMFILE="COM"_DTE_".COM"
- +17 DO OPEN^%ZISH("COMFILE",LOCALDIR,COMFILE,"W")
- +18 DO USE^%ZISUTL("COMFILE")
- +19 WRITE "SSH_KEYGEN == ""$SYS$SYSTEM:TCPIP$SSH_SSH-KEYGEN2.EXE""",!
- +20 WRITE "SSH_KEYGEN -t "_$$LOW^XLFSTR($GET(ENCRTYPE))_" -""P"" "_LOCALDIR_KEYFILE,!
- +21 DO CLOSE^%ZISH("COMFILE")
- +22 XECUTE "S PV=$ZF(-1,""@"_LOCALDIR_COMFILE_""")"
- +23 SET FILE2DEL(COMFILE)=""
- SET FILE2DEL(KEYFILE_".")=""
- SET FILE2DEL(KEYFILE_".PUB")=""
- End DoDot:1
- +24 ;
- +25 ; -- Linux/Unix SSH Key Generation
- +26 IF PSNOS["UNIX"
- Begin DoDot:1
- +27 IF '$$DIREXIST^PSNFTP2(LOCALDIR)
- DO MAKEDIR^PSNFTP2(LOCALDIR)
- +28 SET ENCRBITS=$SELECT($GET(ENCRBITS):ENCRBITS,1:"")
- +29 SET ENCRTYPE=$$LOW^XLFSTR($GET(ENCRTYPE))
- +30 IF ($PIECE($$VERSION^%ZOSV(1),"/",1)[("Cache"))
- Begin DoDot:2
- +31 if ENCRBITS
- SET ENCRBITS=" -b "_ENCRBITS
- +32 XECUTE "S PV=$ZF(-1,""ssh-keygen -q -N '' -C '' -t "_$$LOW^XLFSTR($GET(ENCRTYPE))_" -f "_LOCALDIR_KEYFILE_ENCRBITS_""")"
- End DoDot:2
- +33 IF $PIECE($$VERSION^%ZOSV(1),"/",1)'[("Cache")
- Begin DoDot:2
- +34 IF ENCRBITS
- SET PV=$ZF(-100,"","ssh-keygen","-q","-t",ENCRTYPE,"-b",ENCRBITS,"-f",LOCALDIR_KEYFILE,"-N","","-C","")
- +35 IF ENCRBITS=""
- SET PV=$ZF(-100,"","ssh-keygen","-q","-t",ENCRTYPE,"-f",LOCALDIR_KEYFILE,"-N","","-C","")
- End DoDot:2
- +36 SET FILE2DEL(KEYFILE)=""
- SET FILE2DEL(KEYFILE_".pub")=""
- End DoDot:1
- +37 ;
- +38 KILL ^TMP("PSNPRVKY",$JOB),^TMP("PSNPUBKY",$JOB)
- +39 ; -- Retrieving SSH Private Key Content
- +40 SET X=$$FTG^%ZISH(LOCALDIR,KEYFILE_$SELECT(PSNOS["VMS":".",1:""),$NAME(^TMP("PSNPRVKY",$JOB,1)),3)
- +41 IF '$DATA(^TMP("PSNPRVKY",$JOB,1))
- QUIT
- +42 ; -- Retrieving SSH Public Key Content
- +43 SET X=$$FTG^%ZISH(LOCALDIR,KEYFILE_$SELECT(PSNOS["VMS":".PUB",1:".pub"),$NAME(^TMP("PSNPUBKY",$JOB,1)),3)
- +44 IF '$DATA(^TMP("PSNPUBKY",$JOB,1))
- QUIT
- +45 ;
- +46 ; -- Deleting temporary files used to generate the keys
- +47 DO DEL^%ZISH(LOCALDIR,"FILE2DEL")
- +48 ;
- +49 ; -- Saving new SSH Keys content in the PPS-N UPDATE CONTROL file (#57.23)
- +50 FOR PSNSPC="PSNPRVKY","PSNPUBKY"
- Begin DoDot:1
- +51 KILL KYTXT,SAVEKEY
- +52 FOR LN=1:1
- if '$DATA(^TMP(PSNSPC,$JOB,LN))
- QUIT
- Begin DoDot:2
- +53 ; Unix/Linux Public SSH Key has no line-feed
- +54 IF PSNOS["UNIX"
- IF PSNSPC="PSNPUBKY"
- Begin DoDot:3
- +55 SET KYTXT(1)=^TMP(PSNSPC,$JOB,LN)
- +56 FOR OVFLN=1:1
- if '$DATA(^TMP(PSNSPC,$JOB,LN,"OVF",OVFLN))
- QUIT
- Begin DoDot:4
- +57 SET KYTXT(1)=$GET(KYTXT(1))_^TMP(PSNSPC,$JOB,LN,"OVF",OVFLN)
- End DoDot:4
- End DoDot:3
- QUIT
- +58 SET KYTXT(LN)=$$ENCRYP^XUSRB1(^TMP(PSNSPC,$JOB,LN))
- End DoDot:2
- +59 IF PSNOS["UNIX"
- IF PSNSPC="PSNPUBKY"
- SET KYTXT(1)=$$ENCRYP^XUSRB1(KYTXT(1))
- +60 SET SAVEKEY(57.23,"1,",$SELECT(PSNSPC="PSNPRVKY":33,1:34))="KYTXT"
- +61 DO UPDATE^DIE("","SAVEKEY")
- +62 KILL ^TMP(PSNSPC,$JOB)
- End DoDot:1
- +63 ;
- +64 ; -- Saving SSH Key Format (SSH2/OpenSSH) and Encryption Type (DSA/RSA) fields
- +65 KILL DIE
- SET DIE="^PS(57.23,"
- SET DA=1
- +66 SET DR="39///"_$SELECT(PSNOS["VMS":"SSH2",1:"OSSH")_";41///"_ENCRTYPE
- DO ^DIE
- +67 LOCK -@KEYFILE
- +68 QUIT
- +69 ;
- RETRIEVE(KTYPE) ; Retrieve the SSH Key into the ^TMP global
- +1 ; (o) KTYPE - SSH Key Type (PUB - Public/PRV - PRivate) (Default: Public)
- +2 ;Output: ^TMP("PSN[PUB/PRV]KY",$J,0)="SSH Key Format (SSH2/OpenSSH)^Encryption Type (DSA/RSA)"
- +3 ; ^TMP("PSN[PUB/PRV]KY",$J,1-N)=[SSH Key Content]
- +4 ;
- +5 NEW X,LN,KYTXT,PSNSPC
- +6 IF $GET(KTYPE)'="PRV"
- SET KTYPE="PUB"
- +7 SET X=$$GET1^DIQ(57.23,"1,",$SELECT(KTYPE="PRV":33,1:34),,"KYTXT")
- +8 SET PSNSPC=$SELECT(KTYPE="PRV":"PSNPRVKY",1:"PSNPUBKY")
- +9 KILL ^TMP(PSNSPC,$JOB)
- +10 FOR LN=1:1
- if '$DATA(KYTXT(LN))
- QUIT
- SET ^TMP(PSNSPC,$JOB,LN)=$$DECRYP^XUSRB1(KYTXT(LN))
- +11 IF $DATA(^TMP(PSNSPC,$JOB))
- Begin DoDot:1
- +12 SET ^TMP(PSNSPC,$JOB,0)=$$GET1^DIQ(57.23,1,39,"I")_"^"_$$GET1^DIQ(57.23,1,41,"I")
- End DoDot:1
- +13 QUIT
- +14 ;
- VIEW ; Displays the SSH Public Key
- +1 ; ^TMP("PSNPUBKY",$J,0)="SSH Key Format (SSH2/OpenSSH)^Encryption Type (DSA/RSA)"
- +2 ; ^TMP("PSNPUBKY",$J,1-N)=[SSH Key Content]
- +3 NEW SSHKEY,DASHLN
- +4 SET $PIECE(DASHLN,"-",81)=""
- SET SSHKEY=$$OPENSSH()
- +5 WRITE !,"Public SSH Key (",$PIECE($GET(^TMP("PSNPUBKY",$JOB,0)),"^",2),") content (does not include dash lines):"
- +6 WRITE !,DASHLN
- +7 FOR
- if $LENGTH(SSHKEY)=0
- QUIT
- WRITE !,$EXTRACT(SSHKEY,1,80)
- SET SSHKEY=$EXTRACT(SSHKEY,81,9999)
- +8 WRITE !,DASHLN
- +9 QUIT
- +10 ;
- DELETE ; Delete Both SSH Keys associated
- +1 NEW DIE,DA,DR
- +2 SET DIE="^PS(57.23,"
- SET DA=1
- SET DR="39///@;41///@;33///@;34///@"
- DO ^DIE
- +3 KILL ^TMP("PSNPRVKY",$JOB),^TMP("PSNPUBKY",$JOB)
- +4 QUIT
- +5 ;
- OPENSSH() ; Returns the SSH Public Key in OpenSSH Format (Converts if necessary)
- +1 ;Input: ^TMP("PSNPUBKY",$J,0)="SSH Key Format (SSH2/OpenSSH)^Encryption Type (DSA/RSA)"
- +2 ; ^TMP("PSNPUBKY",$J,1-N)=[SSH Key Content]
- +3 ;
- +4 NEW OPENSSH,ENCRTYPE,LN
- +5 SET OPENSSH=""
- +6 IF $PIECE($GET(^TMP("PSNPUBKY",$JOB,0)),"^")="SSH2"
- Begin DoDot:1
- +7 SET ENCRTYPE=$PIECE($GET(^TMP("PSNPUBKY",$JOB,0)),"^",2)
- SET OPENSSH=""
- +8 FOR LN=5:1
- if '$DATA(^TMP("PSNPUBKY",$JOB,LN))
- QUIT
- Begin DoDot:2
- +9 IF $GET(^TMP("PSNPUBKY",$JOB,LN))["---- END"
- QUIT
- +10 SET OPENSSH=OPENSSH_$GET(^TMP("PSNPUBKY",$JOB,LN))
- End DoDot:2
- +11 SET OPENSSH=$SELECT(ENCRTYPE="RSA":"ssh-rsa",1:"ssh-dss")_" "_OPENSSH
- End DoDot:1
- +12 IF '$TEST
- Begin DoDot:1
- +13 FOR LN=1:1
- if '$DATA(^TMP("PSNPUBKY",$JOB,LN))
- QUIT
- Begin DoDot:2
- +14 SET OPENSSH=OPENSSH_$GET(^TMP("PSNPUBKY",$JOB,LN))
- End DoDot:2
- End DoDot:1
- +15 QUIT OPENSSH
- +16 ;
- ENDOS() ; Returns the Backend Server Operating System (OS)
- +1 ;Output: Backend Operating System (e.,g., "VMS", "UNIX")
- +2 ;
- +3 NEW ENDOS,ZTRTN,ZTIO,ZTDESC,ZTDTH,ZTSK,I
- +4 KILL ^XTMP("PSNKEY",$JOB,"OS")
- +5 SET ENDOS=""
- SET ZTRTN="SETOS^PSNOSKEY("_$JOB_")"
- SET ZTIO=""
- +6 SET ZTDESC="Backend Server OS Check"
- +7 SET ZTDTH=$$NOW^XLFDT()
- DO ^%ZTLOAD
- +8 FOR I=1:1:5
- SET ENDOS=$GET(^XTMP("PSNKEY",$JOB,"OS"))
- if ENDOS'=""
- QUIT
- HANG 1
- +9 KILL ^XTMP("PSNKEY",$JOB,"OS")
- +10 QUIT $SELECT(ENDOS'="":ENDOS,1:$$OS^%ZOSV())
- +11 ;
- SETOS(JOB) ; Sets the Operating Systems in ^XTMP("PSNKEY",$J,"OS") (Called via Taskman)
- +1 ;Input: JOB - $Job value from calling process
- +2 SET ^XTMP("PSNKEY",JOB,"OS")=$$OS^%ZOSV()
- +3 QUIT
- +4 ;
- +5 ;PSN*4*575 UPDATE HELP TEXT WORDING FOR ECDSA
- HELP ; Encryption Type Help
- +1 WRITE !!,"Secure SHell (SSH) Encryption Keys are used to allow data file download."
- +2 WRITE !,"Follow the steps below to successfully setup data file download from Austin "
- +3 WRITE !,"server to VistA sites:",!
- +4 WRITE !,"Step 1: Select the 'C' (Create New SSH Key Pair) Action and follow the prompts"
- +5 WRITE !," to create a new pair of SSH keys. If you already have an existing SSH"
- +6 WRITE !," Key Pair you can skip this step."
- +7 WRITE !," You can check whether you already have an existing SSH Key Pair"
- +8 WRITE !," through the 'V' (View Public SSH Key) Action."
- +9 WRITE !,""
- +10 DO HELP1
- DO PAUSE
- +11 WRITE !!,"Step 2: Share the Public SSH Key content with the PPS-N SFTP server (Austin)."
- +12 WRITE !," In order to successfully establish the data download files, the SFTP "
- +13 WRITE !," server at Austin needs to install/configure the new SSH Key created in"
- +14 WRITE !," step 1 for the user id they assigned to your site. Use the 'V' (View "
- +15 WRITE !," Public SSH Key) Action to retrieve the content of the Public SSH key."
- +16 WRITE !," The Public SSH Key should not contain line-feed characters, therefore "
- +17 WRITE !," after you copy & paste it from the terminal emulator into an email or "
- +18 WRITE !," text editor make sure it contains only one line of text (no wrapping)."
- +19 QUIT
- +20 ;
- HELP1 ; Encryption Type Help
- +1 WRITE !," Encryption Type: RSA or ECDSA?"
- +2 WRITE !," -----------------------------------"
- +3 WRITE !," Rivest, Shamir & Adleman (RSA) has been one of the most common"
- +4 WRITE !," encryption algorithms used by the IT industry for securely sharing data."
- +5 WRITE !,""
- +6 WRITE !," Elliptic Curve Digital Signature Algorithm (ECDSA) is a more complex"
- +7 WRITE !," public key cryptography encryption algorithm that is now supported by"
- +8 WRITE !," the VA. If ECDSA is selected you will be prompted to enter the Bit size."
- +9 WRITE !," Valid selections are 256, 384 or 521."
- +10 WRITE !,""
- +11 WRITE !," You will need to contact the Austin SFTP server support to determine"
- +12 WRITE !," which type to select."
- +13 QUIT
- PAUSE ; Pauses screen until user hits Return
- +1 WRITE !
- KILL DIR
- SET DIR("A")="Press Return to continue"
- SET DIR(0)="E"
- DO ^DIR
- +2 QUIT
- +3 ;
- ASK() ; confirm creating new pair
- +1 NEW Y
- SET Y=0
- if '$DATA(^TMP("PSNPUBKY",$JOB))
- QUIT 1
- +2 KILL DIRUT,DUOUT,DIR,X,Y
- SET DIR(0)="Y"
- SET DIR("?")="Please enter Y or N."
- +3 SET DIR("A")="Do you want to delete existing key pair and create new pair"
- WRITE !!
- +4 SET DIR("B")="NO"
- DO ^DIR
- +5 QUIT Y