I am working with D5 ( thats a fact ). I have Indy9 installed.
I'm trying to receive data of IdMappedPortTCP on port 8041 (SSL) and redirect the data to a Tserversocket on port 8040. So I will have support of SSL over Tserversocket.
I use the following code:
var
masterdir:String;
begin
masterdir:=Extractfilepath(paramstr(0));
IdMappedPortTCP1.Active:=false;
datamodule2.IdMappedPortTCP1.MappedHost:='192.168.0.3';
datamodule2.IdMappedPortTCP1.MappedPort:=8041;
datamodule2.IdMappedPortTCP1.DefaultPort:=8040;
IdServerIOHandlerSSL1.SSLOptions.RootCertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.CertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.KeyFile:=masterdir+'key.pem';
IdMappedPortTCP1.IOHandler:=IdServerIOHandlerSSL1;
IdMappedPortTCP1.Active:=true;
end;
If I don't use SSL everything is fine. But when I use SSL teh request never comes to the port 8040 encrypted and I need it not encrypted so I can proccess it.
It is not clear from your description whether
TServerSocketis using SSL on port 8040 or not. It makes a big difference in how you set upTIdMappedPortTCP. However, from your description, you have theMappedPortandDefaultPortproperty assignments backwards, at least.DefaultPortis the port thatTIdMappedPortTCPlistens on, so it should be 8041.MappedPortis the port thatTIdMappedPortTCPconnects to, so it should be 8040.It is not common to have unencrypted and encrypted connections on the same port. Most protocols use separate ports. Is that the case here? Is port 8040 unencrypted, and port 8041 encrypted?
If you want
TIdMappedPortTCPto accept encrypted and unencrypted clients on separate ports, you need to add 2 entries to theTIdMappedPortTCP.Bindingscollection, one for each port, and not use theDefaultPortproperty at all. In theTIdMappedPortTCP.OnConnectevent, you can detect which port the client connected to, and then configure theAThread.OutboundClientaccordingly before it connects toTServerSocket.It is not wise to have unencrypted and encrypted clients connect to the same port. In that scenario, you have to sniff the first few bytes to know if the client is sending an SSL handshake or not, and then act accordingly. It is easier to just use separate ports instead. However, some protocols do allow a client to connect to an unencrypted port and then send a command to activate encryption when needed. In that scenario, you would only need 1 port in
TIdMappedPortTCP, so you can either define 1Bindingor useDefaultPort.TIdMappedPortTCPis primarily intended to be a straight passthrough of raw bytes back and forth between the client and the target server. IfTServerSocketis using SSL and you want the client to talk toTServerSocketusing SSL properly, you should not be usingTIdServerIOHandlerSSLat all. LetTIdMappedPortTCPpass the client's raw encrypted data as-is toTServerSocket, and vice versa. They should establish a secure session with each other, not with you. This is especially important if either one of them performs peer identity validation.If you need to process encrypted data that is being exchanged between the client and
TServerSocket, you have to decrypt and re-encrypt the data as it passes throughTIdMappedPortTCP(which means you are acting as a man-in-the-middle attacker, which peer validation is meant to prevent). To do that, you have to establish separate SSL sessions between the client andTIdMappedPortTCP, and betweenTIdMappedPortTCPandTServerSocket. Assigning aTIdServerIOHandlerSSLtoTIdMappedPortTCPonly facilitates the session with the client. You have to manually setup a session withTServerSocket. To do that, you have to manually assign a newTIdSSLIOHandlerSocketobject to theAThread.OutboundClient.IOHandlerproperty in theOnConnectevent.TIdMappedPortTCPwill not handle that for you.If, however,
TServerSocketis not using SSL, and you are usingTIdMappedPortTCPas an SSL gateway intoTServerSocket, then you can skip theOutboundClient.IOHandlerassignment, since you would only need 1 SSL session, betweenTIdMappedPortTCPand the client.Now, with that said, there are some problems in Indy 9. The
TIdSSLIOHandlerOpenSSL.PassThroughproperty is False by default (thus assuming encryption is initially active), andTIdServerIOHandlerSSLassumes that every accepted client connection is using SSL, even if it really is not. If an unencrypted client connects toTIdMappedPortTCPwithTIdServerIOHandlerSSLassigned, the client will not be handled correctly. These issues were fixed in Indy 10. But in Indy 9, you will not be able to handle encrypted and unencrypted clients in the sameTIdMappedPortTCPcomponent. If you are only dealing with encrypted clients though, you won't run into a problem. Otherwise, create 2TIdMappedPortTCPcomponents, one listening on an unencrypted port, the other listening on an encrypted port. They can share the same event handlers. If needed, you can use theAThread.Connection.Socket.Binding.Portproperty to know which port the client is connected to.