bvstone

Creating a Reverse SSL Proxy Using RPG on the IBM i

Posted:

Creating a Reverse SSL Proxy Using RPG on the IBM i

Update:  Be sure to check out Part 2 of this article for updated source: Creating a Reverse SSL Proxy Using RPG on the IBM i - Part 2

Last night I was contacted by one of my clients.  Apparently their Credit Card Payment process had quit working.  Why?  For the most part it is because they were still on V5R4.

As most know, SSL/TLS has gone through a lot of changes and updates (for the better).  While this is good from a security standpoint, IBM i customers who are on an unsupported version of the OS (sometimes through no fault of their own) are unable to use the new SSL updates and fixes that are available.

The application used by the client is a 3rd party portal-type credit card processing system.  This means that in the credit card payment process control is passed to this 3rd party to handle the bulk of the credit card processing.  During this process there are a couple callbacks that are made to my client's server.  Mainly this is so they know if the transaction went through ok, but also for security.  Unique processing IDs are used as a sort of "fingerprint" for the transaction so both parties know the data they are working with is valid.

Now, back to the issue.  In this case the credit card company had updated their SSL requirements to SHA-2.  This means any communications between their servers and other customers need to use at least SHA-2 algorithm.  So, the back end communications between the credit card company and my client were impossible as they only could install a SHA-1 certificate because of the outdated OS version.

Home-Made Reverse Proxy to the Rescue

Having worked with reverse proxies before I thought it may be possible for me to set up my V7R3 machine which runs our BVSTools website (with an SSL option) to be a proxy between the credit card processing company and my client.

At first I started looking into a reverse proxy using the Apache server on the IBM i, but noticed that when SSL is used, it becomes a lot more complicated than when it's just plain HTTP traffic.  

I then realized I had all the tools I needed to create my own custom SSL Reverse Proxy in the form of our eRPG SDK and GETURI software.  So, I contacted the credit card processing company and had them review my SSL website to see if it met their standards, which it did.  

The first step was to have the credit card processing company update the callback programs that were being used by changing the host name from my client's to https://www.bvstools.com.  

Next I created the program necessary to accept the request from the credit card processing company, pass that request on to my client (using GETURI), and then report the results from my client back to the credit card processing company.  With my web site acting as a proxy, the credit card processing company was only concerned about the security of my site, not my client's.

It ended up working very well and because of the great support from the credit card processing company we were able to get this up and going in less than an hour.

The resulting code is as follows:
 

 H DFTACTGRP(*NO) BNDDIR('ERPGSDK')                                    
  ****************************************************************     
  * Prototypes                                                   *     
  ****************************************************************     
  /COPY QCOPYSRC,P.ERPGSDK                                             
  /COPY QCOPYSRC,P.HTTPSTD                                             
  /COPY QCOPYSRC,P.LIBL                                                
  /COPY QCOPYSRC,GETURICOPY                                            
  ****************************************************************         
 D GetUriRG        pr                  extpgm('GETURIRG')                  
 D   G_In                              like(GetUri_In)                     
 D   G_Out                             like(GetUri_Out)                    
 D   G_Head                            like(GetUri_Head)                   
 D   G_Data                            like(GetUri_Data)                   
 D   G_MsgCd                           like(GetUri_MsgCd)                  
 D   G_Msg                             like(GetUri_Msg)                    
  ****************************************************************         
  * Data read in from page                                                 
 D postData        S          65535                                        
  ****************************************************************         
  /free                                                                    
                                                                           
   postData = #RdStin();                                                   
   #pushLib('GETURI');                                                     
                                                                           
   Clear GetUri_In;                                                        
   GI_URI = 'online.myclient.com/cgi-bin/ccpgm';                  
   GI_ReqMeth = 'POST';   
   GI_Data = postData;                                     
   GI_Port = 443;                                          
   GI_SSL = '*YES';                                        
   GI_OutType = '*RETURN';                                 
   GI_SprHead = '*YES';                                    
                                                           
   GetUriRG(GetUri_In:GetUri_Out:GetUri_Head:GetUri_Data:  
            GetUri_MsgCd:GetUri_Msg);   
                                                       
   #popLib('GETURI');                                  
                                                       
   #startUp();                                         
   #setImmediate(*ON);                                 
   #writeTemplate('stdhtmlheader.erpg');               
   #WrStout(Geturi_Out);                               
   #cleanUp();
                                
   *INLR = *ON;                                                                             
                                                                                                            

The steps involved are as follows:

  1. Read the data Standard Input "POST"ed to the website using the QtmhRdStin API (in this case it's the #RdStin subprocedure which is a wrapper for the API).
  2. Take the Standard Input data and use GETURI to make a POST to my client's webserver.  Using the Standard Input read from the original request means that this is basically mirroring the request to my client's server.
  3. When GETURI completes it will have the results that would have been generated by my client's server if they would have originally been used on the call in the variable GetUri_Out.  This data is then mirrored back to the credit card processing company.

All in all it was a pretty simple band-aid.  My client has already made a request to be updated to V7R3 and that is underway.  Once that is done, all that will be required is a new SSL certificate for their website that meets the credit card companies criteria and we can have them change their callback information back to my client's servers.

UPDATE:

I ran into an issue with ASCII to EBCDIC conversions for this.  When a system would send the @ sign escaped as %40, because my Apache server is set up with CGIConvMode as %%EBCDIC/EBCDIC%% it would convert that %40 to %7C, the EBCDIC representation of @ which in ASCII is | (a bar).

To remedy this I added a LocationMatch container for the proxy programs to set the CGIConvMode to %%MIXED/MIXED%% so that it would convert data from EBCDIC to ASCII but leave any of the escaped data as it is.

<LocationMatch /cgi-bin/(proxypgm1|proxypgm2)>
   CGIConvMode %%MIXED/MIXED%%
</LocationMatch>

This seems to have solved the issue.  I wonder if the IBM i will ever have the option to become an ASCII machine.  Boy, wouldn't that be nice!


Last edited 03/29/2018 at 15:11:09



Latest Posts:

MAILTOOL Updated to Allow G4GSMAIL as Option in Routers File MAILTOOL Updated to Allow G4GSMAIL as Option in Routers File
Posted by June 28, 2020
BVSTools >> BVSTools Announcements >> eMail Tool (MAILTOOL) Specific Announcements
BVSTools Now Offers Interface with Infor's ION APIs BVSTools Now Offers Interface with Infor's ION APIs
Posted by May 15, 2020
BVSTools >> BVSTools Announcements
More V7R4 IFS File CCSID Issues and The Fix More V7R4 IFS File CCSID Issues and The Fix
Posted by March 4, 2020
IBM Power Systems >> (QGPL) IBM i
Error Retrieving IP Address by Name Error Retrieving IP Address by Name
Posted by February 25, 2020
BVSTools >> BVSTools Software Discussion
Logging jobs that hit an outq Logging jobs that hit an outq
Posted by February 13, 2020
Programming >> CL Programming
GreenTools for Google Apps (G4G) v12.60 Released with Shared Drive Features and More... GreenTools for Google Apps (G4G) v12.60 Released with Shared Drive Features and More...
Posted by February 4, 2020
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
Allowing Requests over Port 80 For SSL Validation (ie, Namecheap, etc) Allowing Requests over Port 80 For SSL Validation (ie, Namecheap, etc)
Posted by January 31, 2020
Programming >> Web Programming
GreenTools for Slack (G4SLK) v3.00 Released GreenTools for Slack (G4SLK) v3.00 Released
Posted by January 17, 2020
BVSTools >> BVSTools Announcements >> GreenTools for Slack (G4SLK) Specific Announcements
Calling a QSH Command from RPG Calling a QSH Command from RPG
Posted by December 26, 2019
Programming >> RPG Programming
SPLTOOL Print Range (PRTRNG) Function Updated to Handle Spooled Files up to 999,999,999 Pages SPLTOOL Print Range (PRTRNG) Function Updated to Handle Spooled Files up to 999,999,999 Pages
Posted by December 14, 2019
BVSTools >> BVSTools Announcements >> Spooled File Tools (SPLTOOL) Specific Announcements
GreenTools for Microsoft Apps (G4MS) Updated to v6.00 - Now Uses Microsoft Graph APIs GreenTools for Microsoft Apps (G4MS) Updated to v6.00 - Now Uses Microsoft Graph APIs
Posted by November 24, 2019
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
V7R4 Changes CCSID of Compressed File Using PASE JAR Command - Here's The Fix V7R4 Changes CCSID of Compressed File Using PASE JAR Command - Here's The Fix
Posted by November 21, 2019
IBM Power Systems >> (QGPL) IBM i
Using GETURI to Make OAuth 2.0 Requests - Custom Headers for Access Tokens Using GETURI to Make OAuth 2.0 Requests - Custom Headers for Access Tokens
Posted by November 11, 2019
BVSTools >> BVSTools Software Discussion >> Get URI (GETURI) Specific Discussion
GreenTools for Microsoft Apps (G4MS) v5.00 Released with Updated OneDrive Support and 3rd Party Functionality GreenTools for Microsoft Apps (G4MS) v5.00 Released with Updated OneDrive Support and 3rd Party Functionality
Posted by October 20, 2019
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
BVSTools is Now Running V7R4M0 BVSTools is Now Running V7R4M0
Posted by September 28, 2019
BVSTools >> BVSTools Announcements

Reply




Copyright 1983-2020 BVSTools
GreenBoard(v3) Powered by the eRPG SDK, MAILTOOL Plus!, GreenTools for Google Apps, jQuery, jQuery UI, BlockUI, CKEditor and running on the IBM i (AKA AS/400, iSeries, System i).