Getting Indy call to work with Paypal IPN post "Poodle" changes - delphi

I have a web app that utilizes PayPal's IPN. On October 15th PayPal made some modifications because of the Poodle security flaw:
Venture Beat: paypal-says-its-poodle-security-flaw-fix-may-break-the-service-for-some-users-merchants
At this point my calls to https://www.paypal.com/cgi-bin/webscr started returning SSL3_READ_BYTES:sslv3 alert handshake failure
There seems to be fixes out there for php: PHP Fix
I am looking for a solution to fix this for Indy. My code below:
IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocketOpenSSL.create(nil);
try
with IdSSLIOHandlerSocket1 do begin
SSLOptions.Method := sslvSSLv3;
SSLOptions.Mode := sslmUnassigned;
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 2;
end;
IdHTTP1 := TIdHTTP.create(nil);
with IdHTTP1 do begin
IOHandler := IdSSLIOHandlerSocket1;
ReadTimeout := 0;
AllowCookies := True;
ProxyParams.BasicAuthentication := False;
ProxyParams.ProxyPort := 0;
Request.ContentLength := -1;
Request.ContentRangeEnd := 0;
Request.ContentRangeStart := 0;
Request.ContentType := 'text/html';
Request.Accept := 'text/html, */*';
Request.BasicAuthentication := False;
Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
HTTPOptions := [hoForceEncodeParams];
end;
ss := TStringList.Create;
ss.Add('cmd=_notify-validate');
for i:= 0 to ARequestInfo.Params.count -1 do begin
ss.Add(ARequestInfo.Params[i]);
end;
mPayPalServer := 'https://www.paypal.com/cgi-bin/webscr';
mResult := HTTPDecode(IdHTTP1.Post(mPayPalServer, ss));
I have tried replacing the SSLOptions.Method with:
SSLOptions.Method := sslvTLSv1;
But this still does not work.

Your code explicitly configures the SSL handler to use SSL 3 with this line:
SSLOptions.Method := sslvSSLv3;
From https://stackoverflow.com/a/26513369/80901:
PayPal disabled SSLv3 in response to the "POODLE" vunerability. Read
about in here: PayPal Response, so your Indy client will not be
able to connect.
To connect, check which newer protocols are supported (TLS 1.0, 1.1 or 1.2) and configure the SSL handler to use this protocol.
For example to use TLS specify the allowed TLS versions:
SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];

Related

Error connecting with ssl. Eof was observed that violates the protocol

I want to get data from the site https://exergy.skmenergy.com. I use TIdHttp.
My settings
FHttp := TIdHTTP.Create(nil);
FSSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
FSSLIOHandler.MaxLineAction := maException;
FSSLIOHandler.SSLOptions.Method := sslvSSLv23;
FSSLIOHandler.SSLOptions.Mode := sslmUnassigned;
FSSLIOHandler.SSLOptions.SSLVersions := [sslvSSLv2, sslvSSLv3, sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
FCookie := TIdCookieManager.Create(nil);
with FHttp do
begin
IOHandler := FSSLIOHandler;
CookieManager := FCookie;
AllowCookies := True;
HandleRedirects := True;
Request.BasicAuthentication := True;
if StrToBoolDef(FParam.Items['ProxyUse'], True) = True then
begin
ProxyParams.ProxyPort := StrToInt(FParam.Items['Port']);
ProxyParams.ProxyServer := FParam.Items['Server'];
ProxyParams.ProxyUsername := FParam.Items['Login'];
ProxyParams.ProxyPassword := FParam.Items['ProxyPassword'];
end;
ReadTimeout := 100000000;
end;
But in code i call from thread
FHTTP.Get('https://exergy.skmenergy.com);
I get an error
Error connecting with ssl. eof was observed that violates the protocol delphi.
UPD
Files libeay32.dll and ssleay32.dll include in project. Version 1.1.0.1
I use Embarcadero® RAD Studio 10.2 Version 25.0.29039.2004
Indy does not support OpenSSL 1.1.xx.
Need to use OpenSSL version 1.0.2 https://github.com/IndySockets/OpenSSL-Binaries

error connecting with ssl delphi 2007 indy 10

I am new to Delphi and I am assigned with a Delphi 2007 desktop application and have been asked to enable https in that application current it uses Indy 10.1.5.
Below is the code which I have written but could not get expected output.
I am not sure if the DLLs that I use are compatible with it or not.
Error I get is "error connecting with ssl"
var
IdHTTP: TIdHTTP;
Id_HandlerSocket : TIdSSLIOHandlerSocketOpenSSL;
begin
IdHTTP := TIdHTTP.Create;
try
with IdHTTP do
begin
Name := 'IdHTTP';
AllowCookies := True;
RedirectMaximum := 25;
ProxyParams.BasicAuthentication := False;
ProxyParams.ProxyPort := 0;
Request.ContentLength := -1;
Request.Accept := 'text/html, */*';
Request.BasicAuthentication := False;
Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
HTTPOptions := [hoForceEncodeParams];
end;
Id_HandlerSocket := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
Id_HandlerSocket.SSLOptions.Method := sslvSSLv23;
Id_HandlerSocket.SSLOptions.Mode := sslmClient;
// Id_HandlerSocket.Port:= 443 ;
IdHTTP.IOHandler := Id_HandlerSocket;
try
Result := IdHTTP.Get('https://'+WebServer+'/myfol/test_file.txt'); // this is the place where I get error
except on E : Exception do
Begin
Result := E.Message +' || '+E.ClassName ;
End
end;
finally
IdHTTP.Free;
end;

Send e-mail to gmail with INDY - Delphi xe7

IdMessage1.Clear;
IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlersocketopenSSL.Create(nil);
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode := sslmUnassigned;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyMode := [];
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyDepth := 0;
IdSSLIOHandlerSocketOpenSSL1.Host := 'smtp.gmail.com';
IdSSLIOHandlerSocketOpenSSL1.Port := 587;
IdSMTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
IdSMTP1.UseTLS := utUseExplicitTLS;
IdMessage1.Body.Append('h');
IdMessage1.From.Name := '******';
IdMessage1.From.Address := '****';
IdMessage1.Recipients.EMailAddresses :='*****';
IdMessage1.Subject := 'POWIADOMIENIE';
IdSMTP1.UserName := '*******';
IdSMTP1.Password := '*******';
IdSMTP1.Host :='smtp.gmail.com';
IdSMTP1.Port := 587 ;
//IdSMTP1.AuthType := satDefault;
// IdSMTP1.Authenticate;
IdSMTP1.Connect;
IdSMTP1.Send(IdMessage1);
IdSMTP1.Disconnect;
//idSMTP1.Authenticate;
end;
Hello, trying to send email to gmail using INDY and Delphi XE7 . Unfortunately, I get the error
"SSL in not availaible on this server "
screen from Wireshark
Changing libeay32.dll and ssleay32.dll to the current Version solves the problem!

share data to LinkedIn api User’s Profile for status update

I am working on a program which share data to LinkedIn User’s Profile. I am using Delphi XE2, OAuth and LinkedIn API for the same. I am able to get Access token. Then I want to update status. So my code is
procedure TForm1.Button2Click(Sender: TObject);
var
IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL ;
Url,sign : String;
Response : TStringStream;
slist : TStringList;
str : WideString;
Arequest1 : TOAuthRequest;
AuthHeader : WideString;
begin
with http do
Begin
IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSOcketOpenSSL.Create(nil);
with idSSLIOHandlerSocketOpenSSL1 do
begin
SSLOptions.Method := sslvTLSv1;
SSLOptions.SSLVersions := [sslvTLSv1];
SSLOptions.Mode := sslmBoth;
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 0;
host := '';
end;
IOHandler := IdSSLIOHandlerSocketOpenSSL1;
AllowCookies := True;
Request.ContentRangeEnd := 0;
Request.ContentRangeStart := 0;
Request.ContentType := 'application/xml';
Request.ContentEncoding := 'utf-8';
Request.BasicAuthentication := False;
Request.Connection := 'Keep-Alive';
request.host := 'api.linkedin.com';
Request.Accept := 'text/xml, */*';
Request.UserAgent := 'Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0' ;
HTTPOptions := [hoForceEncodeParams];
end;
Url := 'https://api.linkedin.com/v1/people/~/shares';
Consumer := nil;
Consumer := TOAuthConsumer.Create(ConsumerKey, ConsumerSecret);
Arequest1 := TOAuthRequest.Create(Url);
sign := HMAC.build_signature(Arequest1,Consumer,Token);
sign := TOAuthUtil.urlEncodeRFC3986(sign);
http.Request.CustomHeaders.Clear;
AuthHeader := 'OAuth '+ 'oauth_nonce="'+Arequest1.GenerateNonce+'",'+ 'oauth_signature_method="'+HMAC.get_name+'",'+ 'oauth_timestamp="'+Timestamp+'",'+ 'oauth_consumer_key="'+Consumer.Key+'",'+ 'oauth_token="'+Token.Key+'",'+ 'oauth_signature="'+sign+'",'+ 'oauth_version="1.0"';
http.Request.CustomHeaders.Add(AuthHeader);
slist := TStringList.Create;
slist.Text := '<?xml version="1.0" encoding="UTF-8"?><share><comment>Posting from the API using XML</comment>'+
'<content><title>A title for your share</title><submitted-url>http://developer.linkedin.com</submitted-url>'+
'<submitted-image-url>http://lnkd.in/Vjc5ec</submitted-image-url></content><visibility>'+
'<code>anyone</code></visibility></share>';
Response := TStringStream.Create;
http.Request.ContentLength := length(slist.Text);
try
http.post(Url,slist,Response);
Finally
ShowMessage(Response.DataString);
http.Free;
ARequest.Free;
end;
end;
I am facing 401 unauthorized. Please check my ques #A1rPun. Please help me
Thank you for providing a full code sample. I've seen you commented on your previous question that you use indy 10 in Delphi XE2.
The problem could be that there is something wrong with the SSL authentication within indy 10. Full explanation here What you can do is trying to get a stable version of the indy components.
The code seem to have no errors except for a couple of resources that could have been freed ;).
I really hope when updating your indy your problem will solve.

Google OAuth with Indy in Delphi

I am using Indy10 with Delphi and trying to get Google's OAuth to work. The first step is to make a request to the OAuthGetRequestToken method. The code below returns a 400 error. Any help would be greatly appreciated.
procedure TForm1.Button1Click(Sender: TObject);
var
IdHTTP: TIdHTTP;
IdSSLIOHandlerSocket1: TIdSSLIOHandlerSocketOpenSSL;
Params: TStringList;
mString: String;
begin
Params := tstringlist.create;
IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocketOpenSSL.create(nil);
IdHTTP := TIdHTTP.create(nil);
with IdSSLIOHandlerSocket1 do begin
SSLOptions.Method := sslvSSLv3;
SSLOptions.Mode := sslmUnassigned;
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 2;
end;
with IdHTTP do begin
IOHandler := IdSSLIOHandlerSocket1;
ReadTimeout := 0;
AllowCookies := True;
ProxyParams.BasicAuthentication := False;
ProxyParams.ProxyPort := 0;
Request.ContentLength := -1;
Request.ContentRangeEnd := 0;
Request.ContentRangeStart := 0;
Request.ContentType := 'application/x-www-form-urlencoded';
request.host := 'https://www.google.com';
Request.Accept := 'text/html, */*';
Request.BasicAuthentication := False;
Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
HTTPOptions := [hoForceEncodeParams];
end;
Params.Add('scope=https://www.google.com/analytics/feeds/');
Params.Add('oauth_consumer_key=anonymous');
Params.Add('oauth_signature_method=HMAC-SHA1');
Params.Add('oauth_signature=wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D');
Params.Add('oauth_timestamp=137131200');
Params.Add('oauth_nonce=4572616e48616d6d65724c61686176');
showmessage(HTTPDecode(IdHTTP.Post('https://www.google.com/accounts/OAuthGetRequestToken',Params)));
end;
Look at the response DataString (where the Exception is raised), it will give you a more detail reason for the problem.
For instance, trying with your code, I first got a "timestamp too far from current time", then after updating the oauth_timestamp, I got an "Invalid Signature"...
Check if you get a return message in the response header, too, besides the 400. Most web services provide some kind of textual description on what is going wrong.
Also verify that the OpenSSL library is actually loaded, otherwise Indy might fallback to unencoded communication, which the server might not accept.
Try routing your request through HTTP Fiddler.
I found that to be an excellent tool to trace what goes wrong on http/https level.
--jeroen

Resources