Home   Package List   Routine Alphabetical List   Global Alphabetical List   FileMan Files List   FileMan Sub-Files List   Package Component Lists   Package-Namespace Mapping  
Routine: PSNOSKEY

PSNOSKEY.m

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