As is often the case, a particular technology becomes the de facto industry standard. This can be seen to be true with Windows as a PC operating system, Java as a programming language, and, at one time, Lotus as a spreadsheet application. In the case of network communications protocols, TCP/IP has become the de facto industry standard. And, why not? It was already widely used on the Internet. It is very simple to use: All you have to do is specify a destination address and put your file to that address using FTP.
A typical FTP interactive session consists of specifying the remote host you want to communicate with, the user profile you use to gain access with, the user profiles associated password, and the instruction to put or get a particular file. And, in an interactive session, that is no problem because the password specified is not displayed. For a one-off file transfer, FTP used interactively is fine and causes no significant security exposure.
For a regular periodic transfer of data between two hosts, interactive FTP transfer is not practical. A better method is to store the FTP script in a file and execute the script in batch mode. For more information on using batch FTP, check out Bradley V. Stones article, The ABCs of FTP, in the September 2000 issue of MC.
The problem with using a batch transfer mode is that the AS/400 user profile and password is stored in plain text within the source member. If you have access to one AS/400 that uses batch FTP transfers to other hosts, you can find the associated script files and thereby the user profile and password to the remote hosts. You can then sign on to these remote hosts and repeat the search for FTP script files ad infinitum until you have collected a veritable bevy of user profiles and passwords. In fact, its very easy to find user profiles and passwords stored in this manner. Heres how.
Finding Hidden Passwords
There is a file called QADBXATR in library QSYS that contains a complete inventory of all physical files on the system. QADBXATR can be queried to find all source files. Using the underlying search command provided in the PDM, Find String PDM (FNDSTRPDM), its possible to find every occurrence of the word QUIT and, thereby, every source member that contains an FTP script. Let me add a warning here. Just because you can do something, doesnt mean you should.
So now you have this dichotomy: The AS/400, that for so long has been the standard bearer of secure processors, now has this communication protocol integrated into its operating system which leaves passwords lying around for everyone to see. Obviously this is a security exposure. So should you not use FTP script files? Perhaps. One solution is to avoid storing user profiles and passwords in FTP scripts by writing them on-the-fly into a file in QTEMP instead. The beauty of this approach is that the work file exists only for the duration of the file transfer itself. The parameters for the script could be provided through a user-defined command that uses an encrypted password that is decrypted during execution for inclusion in the FTP script and destroyed after use.
DSPINPUT(*NO)
OS/400 provides a command parameter definition called Display Input (DSPINPUT), which you can use to hide the text that a user types into the commands parameter. DSPINPUT is available for use on any input parameter you define for any command you create. Heres one way you might use it to hide passwords during an FTP session. Say that you wrote a user-defined command that executes FTP, and that you used DSPINPUT(*NO) to conceal the password. That should do it, right? Well, not exactly. Figure 1 (page 120) lists the command definition source code of a command that will execute FTPs with secure passwords. While it is true that you do not see what is input to a command parameter that has the DSPINPUT(*NO) specified when executed interactively and while you also do not see the value specified in the job log, there is a problem when you use this command in a CL program. In this case, the command parameter value is displayed in plain view.
What you can do to get around this problem is to have two commands: @FTP and @FTPB. One will execute interactively and the other only from within a program. In the latter case, you will use encrypted passwords, and, in the former, you will rely on the DSPINPUT(*NO) parameter keyword to conceal passwords. The command processing programs (CPPs) for the two commands can be the same, but the program would need to know whether it was passed an encrypted password or not. This is achieved by defining a constant parameter indicating this information. The keyword MODE in the command is set to I indicating that the command operates interactively and that the password is not encrypted. To ensure that the command is not used in a program, specify ALLOW(*INTERACT *BATCH) when creating the command. Ive written a utility that you can download from MC at www.midrangecomptuing. com, which shows how to use the techniques discussed here.
The @FTP Command
The @FTP command uses the parameters to build an FTP script file, execute the script, and then delete it. All FTP execution and error messages are captured and displayed back to the user (on-screen or via the job log) in the event that the FTP did not complete successfully. The @FTP command can also be used to communicate with other non- AS/400 hosts. In fact, I recommend that the @FTP command be used to facilitate transfers between two non-AS/400 hosts to avail yourself of the commands password security capabilities. This can be achieved by relaying an FTP through the AS/400, for example, performing an @FTP *GET from a PC server and an @FTP *PUT to a UNIX box. Before you can create the CL programs, you will need to create a source physical file in QTEMP named QFTPLOG, with a length of 112. This is required to compile the CL programs and can be deleted once the programs have been created.
Executing FTPs in a CL Program
To protect the integrity of passwords from within CL programs, it is necessary to create a slight variation of the @FTP command. I created a new command called @FTPB with
essentially the same parameter definitions as the @FTP command. Basically what it entails is adding another parameter, MODE, which tells the CPP that the PASWRD parameter is an encrypted value and should be decrypted before inserting into the FTP script.
Of course, you now have to create a password encrypting routine, and this is very easy to do. There is a little-known feature in SEU that, when operating on source of type CL, will execute a commands validity-checking program (VCP) right then and there! The @FTPB command uses this feature to enable password encryption while entering the command into a CL source member. Typically, a VCP is used to validate a commands parameters before executing the CPP. A VCP is attached to a command during compilation and must contain the same parameters as the CPP.
Figure 2 shows a snippet of code from @FTPBVCP. You can easily fill in the rest of the code you might want to add for a fully functioning VCP CL program. The default value for the PASWRD parameter is *PROMPT which causes the VCP to execute a command that will prompt the user to enter a password into a nondisplayable field as illustrated in Figure 3. The program will then return the encrypted form of the password. If you are attached to your AS/400 via a PC, you can copy the encrypted password and paste it into the @FTPB command when control is returned to SEU.
Additional Functionality
The @FTP and @FTPB commands can be used as the foundation for a functionally rich utility. For instance, additional commands could be written that would use @FTP and @FTPB to transmit individual source file members, objects, save files and entire libraries.
Helping You Feel Secure
The current incarnation of FTP, as implemented on the AS/400, poses an unacceptable security exposure. If you are to use FTP on the AS/400, it is incumbent upon you to provide a layer of security software around the FTP command to protect the integrity of user profiles and their passwords. I hope the techniques detailed in this article and the attendant code will enable you to secure your FTP transfers.
CMD PROMPT(FTP with Secure Passwords)
PARM KWD(ACTION) TYPE(*CHAR) LEN(7) RSTD(*YES) +
VALUES(*PUT *GET *MPUT *MGET *APPEND +
*DEL) SPCVAL((*PUT PUT) (*GET GET) (*MPUT +
MPUT) (*DEL DEL) (*MGET MGET) (*APPEND +
APPEND)) MIN(1) PROMPT(FTP Action:)
PARM KWD(FROMFILE) TYPE(*CHAR) LEN(32) MIN(1) +
EXPR(*YES) PROMPT(From File:)
PARM KWD(TOFILE) TYPE(*CHAR) LEN(32) MIN(1) +
EXPR(*YES) PROMPT(To File:)
PARM KWD(RMTSYS) TYPE(*CHAR) LEN(32) MIN(1) +
PROMPT(Remote System:)
PARM KWD(USERID) TYPE(*CHAR) LEN(10) MIN(1) +
PROMPT(User Id on Remote Server:)
PARM KWD(PASWRD) TYPE(*CHAR) LEN(10) MIN(1) +
DSPINPUT(*NO) PROMPT(Password:)
PARM KWD(FROMDIR) TYPE(*CHAR) LEN(75) DFT(*NONE) +
SPCVAL((*NONE) (*FROMFILE)) MIN(0) +
PMTCTL(*PMTRQS) PROMPT(From File +
Directory:)
PARM KWD(TODIR) TYPE(*CHAR) LEN(75) DFT(*NONE) +
SPCVAL((*NONE) (*TOFILE)) MIN(0) +
PMTCTL(*PMTRQS) PROMPT(To File Directory:)
PARM KWD(CONVERSION) TYPE(*CHAR) LEN(7) +
RSTD(*YES) DFT(*NONE) VALUES(*NONE *ASCII +
*BINARY) PMTCTL(*PMTRQS) +
PROMPT(Conversion required:)
PARM KWD(MODE) TYPE(*CHAR) LEN(1) CONSTANT(I)
Figure 1: The @FTP command definition will execute FTPs with secure passwords.
. . . . . . . . . . . . . . . . . . . . . . . . . . .
DCLF FILE(@DSPENCPW)
. . . . . . . . . . . . . . . . . . . . . . . . . . .
/* Prompt for Password */
IF COND(&PASWRD = *PROMPT) THEN(DO)
REDISPLAY: SNDRCVF RCDFMT(FTPPWF)
IF COND(&IN03) THEN(RETURN)
IF COND(&IN12) THEN(DO)
CHGVAR VAR(&PASSWRD) VALUE( )
CHGVAR VAR(&ENCPWD) VALUE( )
GOTO CMDLBL(REDISPLAY)
ENDDO
@ENCFTPPWD PWDIN(&PASSWRD) PWDOUT(&ENCPWD)
GOTO CMDLBL(REDISPLAY)
ENDDO
RETURN
. . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 2: Heres a code snippet from the @FTPBVCP validity checking program.
Figure 3: This encrypted password entry window helps protect your FTP password.
LATEST COMMENTS
MC Press Online