Atozed Forums

Full Version: TIdHTTP and XML integration (API)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am not proficient with the Indy components.  Years ago I researched and struggled and finally got the following to work.  This code calls an API to get an authorization code.   Look at the code and then please continue reading the information following.

  HTTP := TIdHTTP.Create(nil);
  try
    SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
    // configure SSL options as needed...
    HTTP.IOHandler := SSL;
    FResponseText := Trim(HTTP.Get('https://evs.e2value.com/evs/remote_auth.asp?username=' + TIdURI.ParamsEncode(username)
      + '&password=' + TIdURI.ParamsEncode(password) + '&vusername=' + TIdURI.ParamsEncode(vusername)));

    (* Parse the document *)
    XMLDocument1.XML.Clear;
    XMLDocument1.XML.Add(Trim(FResponseText));
    XMLDocument1.Active := True;
    AuthId := XMLDocument1.DocumentElement.ChildNodes[0].Text;
    if Copy(AuthId, 1, 5) = 'Sorry' then
      raise Exception.Create('Unable to authenticate.  Bad username or password.')
    else
      if Copy(AuthId, 1, 14) = 'Please provide' then
        raise Exception.Create('Unable to authenticate.  Bad password.');
    AuthCode := XMLDocument1.DocumentElement.ChildNodes[1].Text;
  finally
    XMLDocument1.Active := False;
    SSL.Free;
    HTTP.Free;
  end;


The code no longer works.  It breaks on the line

    FResponseText := Trim(HTTP.Get('https://evs.e2value.com/evs/remote_auth.asp?username=' + TIdURI.ParamsEncode(username)
      + '&password=' + TIdURI.ParamsEncode(password) + '&vusername=' + TIdURI.ParamsEncode(vusername)));

and then of course jumps to the code within the "finally" section.  A couple of weeks ago I received the notice below from the owners of the API.  How do I change my code to make it work?  Can I make it work?  Any help you can provide will be greatly appreciated.


Effective October 1, 2018 we will no longer accept any HTTP requests via XML Integration, also known as API. We will only accept HTTPS requests.
 
Internet Security is a significant concern for us. To offer the best security we can, e2Value continually updates protocols. There have been a number of worldwide changes this year that seem to have caused disruptions for some clients.
 
Any steps we take are to protect ourselves—and more importantly—our customers. None of the security protocols we have instituted or will institute in the future are ones that e2Value decided independently. We were merely complying with the standards we are expected to maintain by and for our customers.
 
Among our recent updates is the requirement of Transport Layer Security (TLS) 1.2 communication with our servers, as the latest security guidelines recommend. TLS 1.2 encryption protocol helps keep data safe during its transmission over the internet.
 
We renew our SSL certificates annually.
 
SSL certificates are either valid or expired and they should be read by a customer’s server during the actual transaction—not stored on the customer’s servers.
 
Storing them on one’s server is typically done because the server has an HTTP connection versus an HTTPS connection. That HTTP connection is an unsecure link that will be blocked after September 30, 2018. To that end:
 
  1. Any HTTP connections will be severed starting October 1, 2018.
  2. If you have an HTTP connection in any postback, you may want to have a security review of your connections, e2Value’s and others, if applicable.
  3. We recommend no one store the SSL certificates.
  4. If a certificate is stored, note and diary the SSL expiration date. We will not be sending out future notices about expiring certificates.
 
These updates should only affect integrated accounts—Single Sign-on, Basic Portico, Advanced Portico and XML (API) integrations—not direct login accounts



Again any help will be greatly appreciated.

Randall H. Carpenter
(10-03-2018, 02:04 AM)rhcarpenter Wrote: [ -> ]Effective October 1, 2018 we will no longer accept any HTTP requests via XML Integration, also known as API. We will only accept HTTPS requests.

You are already using HTTPS.

(10-03-2018, 02:04 AM)rhcarpenter Wrote: [ -> ]Among our recent updates is the requirement of Transport Layer Security (TLS) 1.2 communication with our servers, as the latest security guidelines recommend.


This is the likely culprit.

By default, TIdSSLIOHandlerSocketOpenSSL enables only TLS 1.0. You can use its SSLOptions.SSLVersions property to enable TLS 1.2 instead. That falls under the "configure SSL options as needed" comment in the code you currently have.

Also, make sure you are using up-to-date versions of Indy (at least 10.6.2.5360) and OpenSSL (1.0.2) to support TLS 1.2. In particular, many TLS 1.2 web servers require the TLS SNI extension be used during the TLS handshake. Prior to 10.6.2.5321, Indy did not enable that TLS extension yet (a bug fix for SNI through a proxy was made in 10.6.2.5360).
(10-03-2018, 04:25 AM)rlebeau Wrote: [ -> ]
(10-03-2018, 02:04 AM)rhcarpenter Wrote: [ -> ]Effective October 1, 2018 we will no longer accept any HTTP requests via XML Integration, also known as API. We will only accept HTTPS requests.

You are already using HTTPS.

(10-03-2018, 02:04 AM)rhcarpenter Wrote: [ -> ]Among our recent updates is the requirement of Transport Layer Security (TLS) 1.2 communication with our servers, as the latest security guidelines recommend.


This is the likely culprit.

By default, TIdSSLIOHandlerSocketOpenSSL enables only TLS 1.0.  You can use its SSLOptions.SSLVersions property to enable TLS 1.2 instead. That falls under the "configure SSL options as needed" comment in the code you currently have.

Also, make sure you are using up-to-date versions of Indy (at least 10.6.2.5360) and OpenSSL (1.0.2) to support TLS 1.2.  In particular, many TLS 1.2 web servers require the TLS SNI extension be used during the TLS handshake. Prior to 10.6.2.5321, Indy did not enable that TLS extension yet (a bug fix for SNI through a proxy was made in 10.6.2.5360).



OK.  Thanks for this info.  I do not have the latest versions of Indy.  How do I go about upgrading to the latest version?

I do not know how to determine the OpenSSL version.  Embarassingly, I do not know how to determine if OpenSSL is installed.  Can you tell me how to determine which version I'm using and how to update it if needed?

I really appreciate your help.

Randall H. Carpenter
(10-03-2018, 09:03 PM)rhcarpenter Wrote: [ -> ]I do not have the latest versions of Indy.  How do I go about upgrading to the latest version?

http://www.indyproject.org/Sockets/Docs/...on.EN.aspx

(10-03-2018, 09:03 PM)rhcarpenter Wrote: [ -> ]I do not know how to determine the OpenSSL version.

Just look at the DLL's properties.

Or, you can call Indy's OpenSSLVersion() function (in the IdSSLOpenSSL unit) at runtime.

(10-03-2018, 09:03 PM)rhcarpenter Wrote: [ -> ]Embarassingly, I do not know how to determine if OpenSSL is installed.

Typically, you are responsible for deploying the two OpenSSL libs (ssleay32 and libeay32) with your app. Unless you are deploying your app to a system that has the libs provided by the Operating System for you.

(10-03-2018, 09:03 PM)rhcarpenter Wrote: [ -> ]Can you tell me how to determine which version I'm using

See above.

(10-03-2018, 09:03 PM)rhcarpenter Wrote: [ -> ]and how to update it if needed?

OpenSSL libs that are compatible with Indy are available at https://indy.fulgan.com/SSL/
Thanks so much for this information.

So now you see how little I know about using these components.  I did not realize when you spoke of OpenSSL it was synonymous with the ssleay32 and libeay32 dll files.  I am deploying these files with my application.  I probably need to update them.   Thanks again.  This is some very useful info I can work with to hopefully fix my problem.

Randall H. Carpenter
Thanks so much for the information.  I downloaded v 1.0.2.16 of the OpenSSL dlls I needed (ssleay32.dll and libeay32.dll) and replaced the old versions of these files.  I was able to download, compile, and install Indy v 10.6.2.0.   I set the SSLOptions.SSLVersions property to [sslvTLSv1_2].  I then recompiled my program and the call to the web page was successful.

Thanks so much for helping me fix this issue.

 I hope you can help me now on an issue I have with another of my programs using INDY.  Since installing the Indy v 10.6.2.0 I am receiving the following when attempting to open a new form on which I have dropped a TIdFTP component.

ERROR: Error reading FTPClient.ConnectTimeout:  Property ConnectTimeout does not exist

yet when I look in the object inspector, ConnectTimeout is a valid property set to zero.

Thanks,
Randall H. Carpenter
(10-10-2018, 11:50 PM)rhcarpenter Wrote: [ -> ]I hope you can help me now on an issue I have with another of my programs using INDY.

You should have started a new discussion thread for that.

(10-10-2018, 11:50 PM)rhcarpenter Wrote: [ -> ]Since installing the Indy v 10.6.2.0 I am receiving the following when attempting to open a new form on which I have dropped a TIdFTP component.

ERROR: Error reading FTPClient.ConnectTimeout:  Property ConnectTimeout does not exist

yet when I look in the object inspector, ConnectTimeout is a valid property set to zero.

You most likely have multiple Indy versions installed on your dev machine.  ConnectTimeout is definitely in TIdFTP in Indy 10, but it does not exist in Indy 9 and earlier.  You are clearly using Indy 10 within the IDE, which is why the Object Inspector sees the property, but the compiler is likely finding the other version during compiling/linking, causing the DFM streaming error at runtime.