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:

GreenTools For G Suite (G4G) v12.00 Released With Base OAuth 2.0 Functionality GreenTools For G Suite (G4G) v12.00 Released With Base OAuth 2.0 Functionality
Posted by July 28, 2019
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
BVSTools Small Price Increase in 2020 BVSTools Small Price Increase in 2020
Posted by July 26, 2019
BVSTools >> BVSTools Announcements
GreenTools for Vertex Cloud (VTXCLOUD) Now Available GreenTools for Vertex Cloud (VTXCLOUD) Now Available
Posted by July 22, 2019
BVSTools >> BVSTools Announcements >> GreenTools for Vertex Cloud (VTXCLOUD) Specific Announcements
GreenTools for Google Apps (G4G) - Drive Addon Successfully Verified by Google GreenTools for Google Apps (G4G) - Drive Addon Successfully Verified by Google
Posted by July 22, 2019
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
Why I Cancelled my DynDNS Service and How I Replaced It with an IBM i Application Why I Cancelled my DynDNS Service and How I Replaced It with an IBM i Application
Posted by July 17, 2019
IBM Power Systems >> (QGPL) IBM i
Green Tools for G Suite (G4G) Product Updates (Licensing, Functionality, Base Product) Green Tools for G Suite (G4G) Product Updates (Licensing, Functionality, Base Product)
Posted by July 13, 2019
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
Reading JSON Data from Standard Input With YAJL and RPG Reading JSON Data from Standard Input With YAJL and RPG
Posted by July 12, 2019
Programming >> Proof of Concept (POC)
MAILTOOL Updated to Allow Use of IBM Global Security Kit (GSKIT) for SSL/TLS Communications MAILTOOL Updated to Allow Use of IBM Global Security Kit (GSKIT) for SSL/TLS Communications
Posted by June 19, 2019
BVSTools >> BVSTools Announcements >> eMail Tool (MAILTOOL) Specific Announcements
GETURI v10.00 Released Supporting IBM Global Security Kit (GSKIT) and Server Name Indication (SNI) GETURI v10.00 Released Supporting IBM Global Security Kit (GSKIT) and Server Name Indication (SNI)
Posted by June 11, 2019
BVSTools >> BVSTools Announcements >> Get URI (GETURI) Specific Announcements
BVSTools Now Offers Vertex Cloud Interface BVSTools Now Offers Vertex Cloud Interface
Posted by April 15, 2019
BVSTools >> BVSTools Announcements
Token Has an Invalid Signature Error for Office 365 Email Token Has an Invalid Signature Error for Office 365 Email
Posted by March 22, 2019
BVSTools >> BVSTools Software Discussion >> GreenTools for Microsoft Apps (G4MS) Specific Discussion
Resending Emails that have Errored Out with Updated Router or Authentication Information Resending Emails that have Errored Out with Updated Router or Authentication Information
Posted by March 1, 2019
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
BVSTools Offers Toolset to Work With HubSpot OAuth 2.0 APIs On Your IBM i BVSTools Offers Toolset to Work With HubSpot OAuth 2.0 APIs On Your IBM i
Posted by January 27, 2019
BVSTools >> BVSTools Announcements
G4MSDRV Currently Not Supported G4MSDRV Currently Not Supported
Posted by January 17, 2019
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
Removing Trailing Carriage Returns and/or Line Feeds from a String with RPG Removing Trailing Carriage Returns and/or Line Feeds from a String with RPG
Posted by December 26, 2018
Programming >> RPG Programming

Reply




Copyright 1983-2019 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).