Hi everyone, I wanted to manipulate data in transit over a TIdMappedPortTCP based connection.
Client <-> TIdMappedPortTCP <--> TIdMappedPortTCP <-> server
Ultimately the purpose is to encrypt the connection between the two TIdMappedPortTCP components.
The best way to handle that is to have the connection between the two
TIdMappedPortTCPs using appropriate
TIdSSLIOHandlerSocketBase-derived classes on both ends that know how to encrypt/decrypt how you want.
For the outgoing
TIdMappedPortTCP #1, in its
TIdMappedPortTCP.OnConnect event, which is fired before the TCP connection is opened to the next server, you can assign an appropriate
TIdSSLIOHandlerSocketBase-derived object to the
TIdMappedPortContext(AContext).OutboundClient.IOHandler property. Make sure its
PassThrough property is set to False before you need to exchange any encrypted data. You can do that immediately in the
OnConnect event, or if you want to send a STARTTLS-style command first then you can set
PassThrough=False in the
TIdMappedPortTCP.OnOutboundConnect event instead, which is fired immediately after the
OutboundClient is connected.
For the incoming
TIdMappedPortTCP #2, assign an appropriate
TIdServerIOHandlerSSLBase-derived object to the
TIdMappedPortTCP.IOHandler property before activating the server, and make sure it overrides
Accept() to return an appropriate
TIdSSLIOHandlerSocketBase-derived object. Make sure its
PassThrough property is set to False before you need to exchange any encrypted data.
Accept() can set
PassThrough=False immediately, or for STARTTLS-style handling you can use the
TIdMappedPortTCP.OnBeforeConnect event, which is fired after a new TCP client is accepted and before
TIdMappedPortTCP tries to connect to the next server. Type-cast the
AContext.Connection.IOHandler property to
TIdSSLIOHandlerSocketBase to access its
PassThrough property.
I don't want to use OpenSSL, I want to use Xor-El user's cryptographic components, so as not to depend on external dlls.
OpenSSL is simply Indy's default implementation of SSL/TLS, but Indy is not dependent on OpenSSL specifically (at least in this situation). The
SSLIOHandler architecture is abstract enough that you can write your own
SSLIOHandler classes for any SSL/TLS engine you want, and then you can assign those classes to Indy at runtime.
Someone explain to me how I can manipulate the data passing between the two components?
If you don't want to go the
SSLIOHandler route,
TIdMappedPortTCP does offer an alternative:
- for data flowing from a connected client to the associated outbound connection, you can modify raw bytes stored in the
TIdMappedPortContext(AContext).NetData property in the
TIdMappedPortTCP.OnExecute event. Whatever data is left in the
NetData when the event handler exits will be sent to the next server.
- for data flowing from an outbound connection to the associated connected client, you can modify raw bytes stored in the
TIdMappedPortContext(AContext).NetData property in the
TIdMappedPortTCP.OnOutboundData event. Whatever data is left in the
NetData when the event handler exits will be sent to the client.
So, in your example,
TIdMappedPortTCP #1 would encrypt in
OnExecute and decrypt in
OnOutboundData, whereas
TIdMappedPortTCP #2 would decrypt in
OnExecute and encrypt in
OnOutboundData.
Just note that
NetData is whatever arbitrary bytes are available at the time the event is fired. You can't assume anything about the message structure of the bytes. If you need that, you have to buffer the bytes yourself and then parse out whole messages from your buffer as needed.
I tried in the IdMappedPortTCP1Execute event
...
But they don't work
Why are you using strings to handle encrypted data? Why are you reversing those strings? That is certainly not any kind of encryption at all.
In any case, you are just reading and reversing arbitrary bytes (and without any regard to charset encodings). In order for the receiver to be able to re-reverse that data properly, your event handlers would have to add a custom header to each
NetData to indicate how many bytes are being reversed per event. The receiver could then read a header, read the indicated number of bytes and reverse them, then repeat...
messages are delayed by one sending. Can anyone help me?
Meaning what exactly?