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:

JOBWATCH 5.10 Released with New Feature to Monitor CPU Percentages JOBWATCH 5.10 Released with New Feature to Monitor CPU Percentages
Posted by May 10, 2021
BVSTools >> BVSTools Announcements >> Job Watch (JOBWATCH) Specific Announcements
Iseries Access data transfer Iseries Access data transfer
Posted by April 29, 2021
IBM Power Systems >> (QGPL) IBM i
YAJL - Parsing YAJL - Parsing
Posted by April 4, 2021
Programming >> RPG Programming
Create LPAR partition and install OS Create LPAR partition and install OS
Posted by March 24, 2021
IBM Power Systems >> (QGPL) IBM i
G4MS Now Allows User/Password Authentication Option G4MS Now Allows User/Password Authentication Option
Posted by March 16, 2021
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
IPDS printer file using CHRSIZ IPDS printer file using CHRSIZ
Posted by February 25, 2021
Programming >> RPG Programming
How to Correctly Send the Display Machine Information (DSPMCHINF) Data to BVSTools for Key Generation How to Correctly Send the Display Machine Information (DSPMCHINF) Data to BVSTools for Key Generation
Posted by February 9, 2021
BVSTools >> BVSTools Software Discussion
G4MS Updated to v7.10 - Required Update for All G4MS Users G4MS Updated to v7.10 - Required Update for All G4MS Users
Posted by November 12, 2020
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
MAILTOOL Errors with Microsoft Office 365 (2020) MAILTOOL Errors with Microsoft Office 365 (2020)
Posted by September 3, 2020
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Using MAILTOOL With Office 365 and Two Factor Authentication (2FA or MFA) Using MAILTOOL With Office 365 and Two Factor Authentication (2FA or MFA)
Posted by August 17, 2020
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Updating DNS With Dynamic IP Addresses After a Router Reboot/Power Outage Updating DNS With Dynamic IP Addresses After a Router Reboot/Power Outage
Posted by August 16, 2020
Programming >> Proof of Concept (POC)
GETURI v10.10 Released with New ILE Functions GETURI v10.10 Released with New ILE Functions
Posted by August 12, 2020
BVSTools >> BVSTools Announcements >> Get URI (GETURI) Specific Announcements
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

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).