Jump to content

Remy Lebeau

Members
  • Content Count

    1135
  • Joined

  • Last visited

  • Days Won

    45

Remy Lebeau last won the day on September 22

Remy Lebeau had the most liked content!

Community Reputation

670 Excellent

Technical Information

  • Delphi-Version
    Delphi XE2

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Remy Lebeau

    combobox with custom drop down (treeview)

    The native VCL TComboBox does not support a custom drop down. There is nothing like that for the native VCL TComboBox, so you will have to use a 3rd party solution (for instance, TMS has a TAdvTreeComboBox component, and there is (an older) TreeComboBox available on Torry.net). Otherwise, you would have to write your own component. No.
  2. Indy doesn't care where the certificate files are stored, as long as the paths you supply to them are valid. Using absolute paths should have worked fine. Unless Indy is not the one using the certificate files to begin with...
  3. Remy Lebeau

    update indy to use tls 1.2 in c++builder 6?

    Not like it used to be. A few members are still lingering around the various forums. Several members have transitioned into MVPs, though some members (like me) haven't but are still recognized by a few Embarcadero employees to keep getting old TeamB perks (free versions, beta access, etc). Thanks, fixed.
  4. Yes, I do, and that is a VERY old version of OpenSSL, you need to upgrade. Indy currently supports up to 1.0.2u dated 21/12/2019, which you can find at https://github.com/IndySockets/OpenSSL-Binaries/ Work on supporting 1.1.x is in progress: https://github.com/IndySockets/Indy/pull/299 The Method property is deprecated, you should be using the SSLVersions property instead. TLS 1.0 has been (almost) completely phased out of modern servers. Most modern servers support, if not require, TLS 1.2, so that really should be your minimum going forward nowadays. You should also have TLS 1.1 enabled as a fallback, just in case, but even that is being phased out as well. To enable multiple TLS versions with the Method property, you would have to set it to sslvSSLv23, which will set the SSLVersions property to all SSL/TLS versions supported by Indy (including SSL 2.0, SSL 3.0, and TLS 1.x), but it is better to use the SSLVersions property directly (ie, don't enable SSL 2.0 and 3.0 anymore), eg: SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]; Having multiple TLS versions enabled at a time will allow OpenSSL to negotiate the highest version that both client and server support. That being said, on a side note, you do not need to assign ANY of the following SSLIOHandler properties, as Indy handles them internally for you: Setup the necessary Host/Port only in the client component, ie TIdIMAP4. The Connect() method will then copy them into the IOHandler as needed.
  5. Why? What is the actual problem with having them in an application folder?
  6. I'm assuming you are using OpenSSL, which version? Also, what version of the SSL/TLS protocol are you using? Then you should be able to debug it. For instance, using Wireshark, you can see the details of the actual SSL/TLS handshake (at least until the connection is encrypted. It takes a few back-and-forths to get that far). At what stage in the handshake is the server disconnecting? The error means that the IMAP server is closing its end of the TCP connection while the SSL/TLS handshake is still in progress. Typically, this happens if the server encounters something it doesn't like in the client's SSL/TLS handshake, and the server decides to bail out without first sending a TLS alert to explain what is wrong.
  7. Remy Lebeau

    update indy to use tls 1.2 in c++builder 6?

    <sigh> Fine, then let's go the long way around, using a full wrapper class, forget TMethod (even though it will technically work at runtime, despite the compiler warnings): // SOURCE #define BUILDING_DLL #include "mydll.h" class eventHandlers { public: OnWorkBeginFunc onWorkBegin; OnWorkEndFunc onWorkEnd; OnWorkFunc onWork; void __fastcall OnWorkBeginHandler(TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCountMax) { if (onWorkBegin) onWorkBegin((OnWorkMode)AWorkMode, AWorkCountMax); } void __fastcall OnWorkEndHandler(TObject *ASender, TWorkMode AWorkMode) { if (onWorkEnd) onWorkEnd((OnWorkMode)AWorkMode); } void __fastcall OnWorkHandler(TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCount) { if (onWork) onWork((OnWorkMode)AWorkMode, AWorkCount); } }; static bool sslPathSet = false; char* getdata(const char *url, OnWorkBeginFunc onWorkBegin, OnWorkEndFunc onWorkEnd, OnWorkFunc onWork) { char *result = NULL; try { if (!sslPathSet) { sslPathSet = true; IdOpenSSLSetLibPath(ExtractFilePath(ParamStr(0))); } TIdHTTP *http = new TIdHTTP; try { eventHandlers events; events.onWorkBegin = onWorkBegin; events.onWorkEnd = onWorkEnd; events.onWork = onWork; http->OnWorkBegin = &events.OnWorkBeginHandler; http->OnWorkEnd = &events.OnWorkEndHandler; http->OnWork = &events.OnWorkHandler; TIdSSLIOHandlerSocketOpenSSL *SSL = new TIdSSLIOHandlerSocketOpenSSL(http); SSL->SSLOptions->SSLVersions = TIdSSLVersions() << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2; http->IOHandler = SSL; http->ReadTimeout = 10000; UTF8String s = http->Get(url); result = new char[s.Length()+1]; memcpy(result, s.c_str(), s.Length()+1); } __finally { delete http; } } catch (...) { return NULL; } return result; } void freedata(char *data) { delete[] data; } Odd, they should be. Especially since OnWorkEnd can't be called if OnWorkBegin is not called first. No. Correct, because the event is expecting a class method, not a standalone procedure. Using TMethod is the way to get around that.
  8. Remy Lebeau

    update indy to use tls 1.2 in c++builder 6?

    <sigh> Try this: // SOURCE #define BUILDING_DLL #include "mydll.h" struct userFunctions { OnWorkBeginFunc onWorkBegin; OnWorkEndFunc onWorkEnd; OnWorkFunc onWork; }; static void __fastcall MyOnWorkBeginHandler(void *AData, TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCountMax) { userFunctions *funcs = static_cast<userFunctions*>(AData); funcs->onWorkBegin((OnWorkMode)AWorkMode, AWorkCountMax); } static void __fastcall MyOnWorkEndHandler(void *AData, TObject *ASender, TWorkMode AWorkMode) { userFunctions *funcs = static_cast<userFunctions*>(AData); funcs->onWorkEnd((OnWorkMode)AWorkMode); } static void __fastcall MyOnWorkHandler(void *AData, TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCount) { userFunctions *funcs = static_cast<userFunctions*>(AData); funcs->onWork((OnWorkMode)AWorkMode, AWorkCount); } template <typename EventType, typename HandlerType> static EventType makeEventHandler(void *data, HandlerType *handler) { TMethod m; m.Data = data; m.Code = handler; return reinterpret_cast<EventType&>(m); /* alternatively: EventType evt; TMethod &m = reinterpret_cast<TMethod&>(evt); m.Data = data; m.Code = handler; return evt; */ } static bool sslPathSet = false; char* getdata(const char *url, OnWorkBeginFunc onWorkBegin, OnWorkEndFunc onWorkEnd, OnWorkFunc onWork) { char *result = NULL; try { if (!sslPathSet) { sslPathSet = true; IdOpenSSLSetLibPath(ExtractFilePath(ParamStr(0))); } TIdHTTP *http = new TIdHTTP; try { userFunctions funcs; if (onWorkBegin) { funcs.onWorkBegin = onWorkBegin; http->OnWorkBegin = makeEventHandler<TWorkBeginEvent>(&funcs, &MyOnWorkBeginHandler); } if (onWorkEnd) { funcs.onWorkEnd = onWorkEnd; http->OnWorkEnd = makeEventHandler<TWorkEndEvent>(&funcs, &MyOnWorkEndHandler); } if (onWork) { funcs.onWork = onWork; http->OnWork = makeEventHandler<TWorkEvent>(&funcs, &MyOnWorkHandler); } TIdSSLIOHandlerSocketOpenSSL *SSL = new TIdSSLIOHandlerSocketOpenSSL(http); SSL->SSLOptions->SSLVersions = TIdSSLVersions() << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2; http->IOHandler = SSL; http->ReadTimeout = 10000; UTF8String s = http->Get(url); result = new char[s.Length()+1]; memcpy(result, s.c_str(), s.Length()+1); } __finally { delete http; } } catch (...) { return NULL; } return result; } void freedata(char *data) { delete[] data; }
  9. Remy Lebeau

    update indy to use tls 1.2 in c++builder 6?

    My bad, too many *s in the DLL's event handlers. Try this instead: static void __fastcall MyOnWorkBeginHandler(void *AData, TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCountMax) { OnWorkBeginFunc func = static_cast<OnWorkBeginFunc>(AData); func(AWorkMode, AWorkCountMax); } static void __fastcall MyOnWorkEndHandler(void *AData, TObject *ASender, TWorkMode AWorkMode) { OnWorkEndFunc func = static_cast<OnWorkEndFunc>(AData); func(AWorkMode); } static void __fastcall MyOnWorkHandler(void *AData, TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCount) { OnWorkFunc func = static_cast<OnWorkFunc>(AData); func(AWorkMode, AWorkCount); }
  10. Remy Lebeau

    update indy to use tls 1.2 in c++builder 6?

    Why not just install the latest Indy in C++Builder 6? No, not directly. Nor should you be trying to. What you should do instead is let the caller pass in its own function pointer(s), which your DLL then remembers, and can then call from inside its own OnWork event handler(s). For example, the following uses a little-known trick for assigning a standalone procedure as a VCL event handler, while also passing a user-defined parameter to it. There are other ways this could be implemented, but this is the most straight-forward way I can think of right now for your scenario: // HEADER #ifndef MY_DLL_H #define MY_DLL_H #ifdef __cplusplus extern "C" { #endif #ifdef BUILDING_DLL #define EXPORT __declspec(dllexport) #else #define EXPORT __declspec(dllimport) #endif enum OnWorkMode { WorkReading, WorkWriting }; typedef void (*OnWorkBeginFunc)(OnWorkMode AWorkMode, __int64 AWorkCountMax); typedef void (*OnWorkEndFunc)(OnWorkMode AWorkMode); typedef void (*OnWorkFunc)(OnWorkMode AWorkMode, __int64 AWorkCount); EXPORT char* getdata(const char *url, OnWorkBeginFunc onWorkBegin, OnWorkEndFunc onWorkEnd, OnWorkFunc onWork); EXPORT void freedata(char *data); #ifdef __cplusplus } #endif #endif // SOURCE #define BUILDING_DLL #include "mydll.h" static void __fastcall MyOnWorkBeginHandler(void *ASelf, TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCountMax) { OnWorkBeginFunc func = static_cast<OnWorkBeginFunc*>(ASelf); func(AWorkMode, AWorkCountMax); } static void __fastcall MyOnWorkEndHandler(void *ASelf, TObject *ASender, TWorkMode AWorkMode) { OnWorkEndFunc *func = static_cast<OnWorkEndFunc*>(ASelf); func(AWorkMode); } static void __fastcall MyOnWorkHandler(void *ASelf, TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCount) { OnWorkFunc *func = static_cast<OnWorkFunc*>(ASelf); func(AWorkMode, AWorkCount); } template <typename EventType, typename FuncType, typename HandlerType> static EventType makeEventHandler(FuncType *func, HandlerType *handler) { TMethod m; m.Data = func; m.Code = handler; return reinterpret_cast<EventType&>(m); /* alternatively: EventType evt; TMethod &m = reinterpret_cast<TMethod&>(evt); m.Data = func; m.Code = handler; return evt; */ } static bool sslPathSet = false; char* getdata(const char *url, OnWorkBeginFunc onWorkBegin, OnWorkEndFunc onWorkEnd, OnWorkFunc onWork) { char *result = NULL; try { if (!sslPathSet) { sslPathSet = true; IdOpenSSLSetLibPath(ExtractFilePath(ParamStr(0))); } TIdHTTP *http = new TIdHTTP; try { if (onWorkBegin) http->OnWorkBegin = makeEventHandler<TWorkBeginEvent>(onWorkBegin, &MyOnWorkBeginHandler); if (onWorkEnd) http->OnWorkEnd = makeEventHandler<TWorkEndEvent>(onWorkEnd, &MyOnWorkEndHandler); if (onWork) http->OnWork = makeEventHandler<TWorkEvent>(onWork, &MyOnWorkHandler); TIdSSLIOHandlerSocketOpenSSL *SSL = new TIdSSLIOHandlerSocketOpenSSL(http); SSL->SSLOptions->SSLVersions = TIdSSLVersions() << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2; http->IOHandler = SSL; http->ReadTimeout = 10000; UTF8String s = http->Get(url); result = new char[s.Length()+1]; memcpy(result, s.c_str(), s.Length()+1); } __finally { delete http; } } catch (...) { return NULL; } return result; } void freedata(char *data) { delete[] data; } And then you C++Builder 6 code can use it like this: #include "mydll.h" #pragma comment(lib, "mydll.lib") // or add the .lib file to your project void OnWorkBegin(OnWorkMode AWorkMode, __int64 AWorkCountMax) { //... } void OnWorkEnd(OnWorkMode AWorkMode) { //... } void OnWork(OnWorkMode AWorkMode, __int64 AWorkCount) { //... } char *data = getdata("url", &OnWorkBegin, &OnWorkEnd, &OnWork); if (data) { // ... freedata(data); } Yes, because System::String is an alias for System::UnicodeString in CB10.3, but is an alias for System::AnsiString in BCB6. Thus, you were indeed trying to pass a wchar_t* pointer to strcpy() rather than a char* pointer.
  11. Remy Lebeau

    Warning on depreciated symbol, Delphi 11

    Or you can use {$WARN SYMBOL_DEPRECATED OFF} in the code.
  12. Remy Lebeau

    Warning on depreciated symbol, Delphi 11

    Actually, several new ComponentPlatform enum values were introduced and old values were deprecated:
  13. Remy Lebeau

    update indy to use tls 1.2 in c++builder 6?

    That means the DLL itself failed to load into memory, before Indy could even try to access any of its functions. Such a failure is most commonly because the DLL itself, or one of its dependent DLLs or imports, can't be found by the OS. OpenSSL build numbers are represented as letters in the English alphabet. So, 1.0.2q is build 1.0.2.17, 1.0.2u is build 1.0.2.21, etc.
  14. Remy Lebeau

    Cyrillic characters in URL

    Yes. Delphi 11 shipped with the latest Indy that was available 3 months ago.
  15. Remy Lebeau

    Cyrillic characters in URL

    Actually, about 8 months ago, TIdHTTPServer was updated to now default to parsing input parameters using UTF-8 if no charset is specified in the Content-Type header. I have added that note to the StackOverflow post you linked to.
×