Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libfilezilla for openSUSE:Factory checked in at 2023-06-04 00:13:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libfilezilla (Old) and /work/SRC/openSUSE:Factory/.libfilezilla.new.15902 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libfilezilla" Sun Jun 4 00:13:25 2023 rev:52 rq:1090630 version:0.42.2 Changes: -------- --- /work/SRC/openSUSE:Factory/libfilezilla/libfilezilla.changes 2023-06-01 17:20:07.790377141 +0200 +++ /work/SRC/openSUSE:Factory/.libfilezilla.new.15902/libfilezilla.changes 2023-06-04 00:13:29.785854643 +0200 @@ -2 +2 @@ -Mon May 29 08:27:38 UTC 2023 - Paolo Stivanin <i...@paolostivanin.com> +Sat Jun 3 09:23:21 UTC 2023 - ecsos <ec...@opensuse.org> @@ -4,6 +4,16 @@ -- Update to 0.43.0: - * Added fz::tls_layer::generate_cert_from_csr - * fz::event_loop performance improvements when timers are in use - * Further HTTP client fixes - * Small HTTP client improvements to force IPv4/IPv6 for new connections, - add a header count limit, and to make abuffer pool optional +- Update to 0.42.2 + * Bugfixes and minor changes: + - Further HTTP client fixes +- Changes from 0.42.1 + * Bugfixes and minor changes: + - Small HTTP client improvements to force IPv4/IPv6 for new + connections, add a header count limit, and to make abuffer + pool optional +- Changes from 0.42.0 + * New features: + - Added an HTTP client + * Bugfixes and minor changes: + - Sources are now distributed in a .tar.xz + - buffer_writer now clears the buffer when opened + - Fixes and performance improvements for fz::xml::parser + - *nix: fz::file::size() now returns -1 on character devices Old: ---- libfilezilla-0.43.0.tar.xz New: ---- libfilezilla-0.42.2.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libfilezilla.spec ++++++ --- /var/tmp/diff_new_pack.ZBo5if/_old 2023-06-04 00:13:30.401858326 +0200 +++ /var/tmp/diff_new_pack.ZBo5if/_new 2023-06-04 00:13:30.405858350 +0200 @@ -16,11 +16,11 @@ # -%define major 39 +%define major 36 %define libname %{name}%{major} %define develname %{name}-devel Name: libfilezilla -Version: 0.43.0 +Version: 0.42.2 Release: 0 Summary: C++ library for filezilla License: GPL-2.0-or-later @@ -32,6 +32,11 @@ BuildRequires: automake BuildRequires: doxygen BuildRequires: fdupes +%if 0%{?suse_version} > 1500 +BuildRequires: gcc-c++ +%else +BuildRequires: gcc8-c++ +%endif BuildRequires: graphviz BuildRequires: libtool BuildRequires: pkgconfig @@ -41,11 +46,6 @@ BuildRequires: pkgconfig(hogweed) >= 3.1 BuildRequires: pkgconfig(nettle) >= 3.1 Recommends: %{name}-lang -%if 0%{?suse_version} > 1500 -BuildRequires: gcc-c++ -%else -BuildRequires: gcc8-c++ -%endif %description libfilezilla is C++ library, offering some basic functionality to @@ -79,6 +79,11 @@ Files needed for development with %{name}. + + + + + # Need %%lang_package expanded for an extra conflict with an old library package %package lang # FIXME: consider using %%lang_package macro ++++++ libfilezilla-0.43.0.tar.xz -> libfilezilla-0.42.2.tar.xz ++++++ ++++ 17095 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/NEWS new/libfilezilla-0.42.2/NEWS --- old/libfilezilla-0.43.0/NEWS 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/NEWS 2023-04-25 15:24:26.000000000 +0200 @@ -1,15 +1,10 @@ -0.43.0 (2023-05-26) - -+ Added fz::tls_layer::generate_cert_from_csr -- fz::event_loop performance improvements when timers are in use - 0.42.2 (2023-04-25) - Further HTTP client fixes 0.42.1 (2023-04-21) -- Small HTTP client improvements to force IPv4/IPv6 for new connections, add a header count limit, and to make a buffer pool optional +- Small HTTP client improvements to force IPv4/IPv6 for new connections, add a header count limit, and to make abuffer pool optional 0.42.0 (2023-04-12) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/config/config.hpp.in new/libfilezilla-0.42.2/config/config.hpp.in --- old/libfilezilla-0.43.0/config/config.hpp.in 2023-05-26 09:44:55.000000000 +0200 +++ new/libfilezilla-0.42.2/config/config.hpp.in 2023-04-25 15:05:07.000000000 +0200 @@ -53,6 +53,9 @@ /* Define if MEMFD_CREATE is supported */ #undef HAVE_MEMFD_CREATE +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + /* Define if thread_local isn't supported */ #undef HAVE_NO_THREAD_LOCAL @@ -65,9 +68,6 @@ /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H -/* Define to 1 if you have the <stdio.h> header file. */ -#undef HAVE_STDIO_H - /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H @@ -120,9 +120,7 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* Define to 1 if all of the C90 standard headers exist (not just the ones - required in a freestanding environment). This macro is provided for - backward compatibility; new code need not use it. */ +/* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Build system under which the program was compiled on. */ @@ -140,6 +138,11 @@ /* Version number of package */ #undef VERSION +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/configure.ac new/libfilezilla-0.42.2/configure.ac --- old/libfilezilla-0.43.0/configure.ac 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/configure.ac 2023-04-25 15:04:25.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT([libfilezilla],[0.43.0],[tim.ko...@filezilla-project.org],[],[https://lib.filezilla-project.org/]) +AC_INIT([libfilezilla],[0.42.2],[tim.ko...@filezilla-project.org],[],[https://lib.filezilla-project.org/]) # Update the version information only immediately before a public release of your software # If the library source code has changed at all since the last update, then increment revision (âc:r:aâ becomes âc:r+1:aâ). @@ -6,7 +6,7 @@ # If any interfaces have been added since the last public release, then increment age. # If any interfaces have been removed or changed since the last public release, then set age to 0. # CURRENT:REVISION:AGE -LIBRARY_VERSION=39:0:0 +LIBRARY_VERSION=38:0:2 AC_CONFIG_HEADERS([config/config.hpp]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/aio/aio.cpp new/libfilezilla-0.42.2/lib/aio/aio.cpp --- old/libfilezilla-0.43.0/lib/aio/aio.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/aio/aio.cpp 2023-02-22 11:16:15.000000000 +0100 @@ -79,15 +79,18 @@ } namespace { -void remove_pending_events(event_handler& handler, aio_waitable & w) +void remove_pending_events(event_handler& h, aio_waitable & w) { - auto event_filter = [&](event_base& ev) -> bool { - if (ev.derived_type() == aio_buffer_event::type()) { - return std::get<0>(static_cast<aio_buffer_event const&>(ev).v_) == &w; + auto event_filter = [&](event_loop::Events::value_type const& ev) -> bool { + if (ev.first != &h) { + return false; + } + else if (ev.second->derived_type() == aio_buffer_event::type()) { + return std::get<0>(static_cast<aio_buffer_event const&>(*ev.second).v_) == &w; } return false; }; - handler.filter_events(event_filter); + h.event_loop_.filter_events(event_filter); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/aio/xml_writer.cpp new/libfilezilla-0.42.2/lib/aio/xml_writer.cpp --- old/libfilezilla-0.43.0/lib/aio/xml_writer.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/aio/xml_writer.cpp 2023-01-12 10:41:17.000000000 +0100 @@ -21,9 +21,7 @@ aio_result xml_parser_writer::do_add_buffer(scoped_lock &, buffer_lease && b) { - bool ret = parser_.parse(b->to_view()); - b.release(); - if (!ret) { + if (!parser_.parse(b->to_view())) { auto error = parser_.get_error(); if (!error.empty()) { buffer_pool_.logger().log(logmsg::error, "Could not parse XML: %s", error); @@ -60,9 +58,7 @@ aio_result xml_namespace_parser_writer::do_add_buffer(scoped_lock &, buffer_lease && b) { - bool ret = parser_.parse(b->to_view()); - b.release(); - if (!ret) { + if (!parser_.parse(b->to_view())) { auto error = parser_.get_error(); if (!error.empty()) { buffer_pool_.logger().log(logmsg::error, "Could not parse XML: %s", error); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/event_loop.cpp new/libfilezilla-0.42.2/lib/event_loop.cpp --- old/libfilezilla-0.43.0/lib/event_loop.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/event_loop.cpp 2022-07-08 15:18:44.000000000 +0200 @@ -17,24 +17,19 @@ event_loop::event_loop() : sync_(false) , thread_(std::make_unique<thread>()) - , timer_thread_(std::make_unique<thread>()) { thread_->run([this] { entry(); }); - timer_thread_->run([this] { timer_entry(); }); } event_loop::event_loop(thread_pool & pool) : sync_(false) { task_ = std::make_unique<async_task>(pool.spawn([this] { entry(); })); - timer_task_ = std::make_unique<async_task>(pool.spawn([this] { timer_entry(); })); } event_loop::event_loop(event_loop::loop_option) : sync_(false) - , timer_thread_(std::make_unique<thread>()) { - timer_thread_->run([this] { timer_entry(); }); } event_loop::~event_loop() @@ -48,7 +43,7 @@ return task_ || thread_ || threadless_; } -void event_loop::send_event(event_handler* handler, event_base* evt, bool deletable) +void event_loop::send_event(event_handler* handler, event_base* evt) { event_assert(handler); event_assert(evt); @@ -56,17 +51,15 @@ { scoped_lock lock(sync_); if (!handler->removing_) { - if (pending_events_.empty() && !active_handler_) { + if (pending_events_.empty()) { cond_.signal(lock); } - pending_events_.emplace_back(handler, evt, deletable); + pending_events_.emplace_back(handler, evt); return; } } - if (deletable) { - delete evt; - } + delete evt; } void event_loop::remove_handler(event_handler* handler) @@ -78,10 +71,10 @@ pending_events_.erase( std::remove_if(pending_events_.begin(), pending_events_.end(), [&](Events::value_type const& v) { - if (std::get<0>(v) == handler && std::get<2>(v)) { - delete std::get<1>(v); + if (v.first == handler) { + delete v.second; } - return std::get<0>(v) == handler; + return v.first == handler; } ), pending_events_.end() @@ -107,24 +100,19 @@ l.lock(); } } - else { - resend_ = false; - } } } -void event_loop::filter_events(std::function<bool(event_handler*& h, event_base& ev)> const& filter) +void event_loop::filter_events(std::function<bool(Events::value_type &)> const& filter) { scoped_lock l(sync_); pending_events_.erase( std::remove_if(pending_events_.begin(), pending_events_.end(), [&](Events::value_type & v) { - auto *& h = std::get<0>(v); - bool const remove = filter(h, *std::get<1>(v)); - event_assert(h); - if (remove && std::get<2>(v)) { - delete std::get<1>(v); + bool const remove = filter(v); + if (remove) { + delete v.second; } return remove; } @@ -195,7 +183,7 @@ return id; } -timer_id event_loop::setup_timer(scoped_lock &l, timer_data &d, event_handler* handler, monotonic_clock const& deadline, duration const& interval) +timer_id event_loop::setup_timer(scoped_lock &lock, timer_data &d, event_handler* handler, monotonic_clock const& deadline, duration const& interval) { if (handler->removing_) { return 0; @@ -209,7 +197,7 @@ if (!deadline_ || d.deadline_ < deadline_) { // Our new time is the next timer to trigger deadline_ = d.deadline_; - timer_cond_.signal(l); + cond_.signal(lock); } return d.id_; @@ -225,35 +213,16 @@ ev = pending_events_.front(); pending_events_.pop_front(); - event_assert(std::get<0>(ev)); - event_assert(std::get<1>(ev)); - event_assert(!std::get<0>(ev)->removing_); + event_assert(ev.first); + event_assert(ev.second); + event_assert(!ev.first->removing_); - active_handler_ = std::get<0>(ev); + active_handler_ = ev.first; l.unlock(); - - event_assert(!resend_); - - (*std::get<0>(ev))(*std::get<1>(ev)); - if (resend_) { - resend_ = false; - l.lock(); - if (!std::get<0>(ev)->removing_) { - pending_events_.emplace_back(ev); - } - else { // Unlikely, but possible to get into this branch branch - if (std::get<2>(ev)) { - delete std::get<1>(ev); - } - } - } - else { - if (std::get<2>(ev)) { - delete std::get<1>(ev); - } - l.lock(); - } + (*ev.first)(*ev.second); + delete ev.second; + l.lock(); active_handler_ = nullptr; @@ -286,7 +255,7 @@ scoped_lock l(sync_); while (!quit_) { - if (do_timers_ && process_timers(l, now)) { + if (process_timers(l, now)) { continue; } if (process_event(l)) { @@ -294,30 +263,11 @@ } // Nothing to do, now we wait - cond_.wait(l); - } -} - -void event_loop::timer_entry() -{ - monotonic_clock now; - - scoped_lock l(sync_); - while (!quit_) { - if (deadline_ && !do_timers_) { - now = fz::monotonic_clock::now(); - if (deadline_ <= now) { - do_timers_ = true; - if (pending_events_.empty() && !active_handler_) { - cond_.signal(l); - } - } - else { - timer_cond_.wait(l, deadline_ - now); - } + if (deadline_) { + cond_.wait(l, deadline_ - now); } else { - timer_cond_.wait(l); + cond_.wait(l); } } } @@ -325,7 +275,6 @@ bool event_loop::process_timers(scoped_lock & l, monotonic_clock & now) { if (!deadline_) { - do_timers_ = false; // There's no deadline return false; } @@ -333,8 +282,6 @@ now = monotonic_clock::now(); if (now < deadline_) { // Deadline has not yet expired - do_timers_ = false; - timer_cond_.signal(l); return false; } @@ -372,7 +319,7 @@ timers_.pop_back(); } else { - it->deadline_ = std::max(now, it->deadline_ + it->interval_); + it->deadline_ = now + it->interval_; if (!deadline_ || it->deadline_ < deadline_) { deadline_ = it->deadline_; } @@ -392,11 +339,6 @@ return true; } - if (deadline_) { - do_timers_ = false; - timer_cond_.signal(l); - } - return false; } @@ -406,20 +348,15 @@ scoped_lock l(sync_); quit_ = true; cond_.signal(l); - timer_cond_.signal(l); } if (join) { thread_.reset(); task_.reset(); - timer_thread_.reset(); - timer_task_.reset(); scoped_lock lock(sync_); for (auto & v : pending_events_) { - if (std::get<2>(v)) { - delete std::get<1>(v); - } + delete v.second; } pending_events_.clear(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/hostname_lookup.cpp new/libfilezilla-0.42.2/lib/hostname_lookup.cpp --- old/libfilezilla-0.43.0/lib/hostname_lookup.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/hostname_lookup.cpp 2021-07-02 11:04:19.000000000 +0200 @@ -150,14 +150,17 @@ namespace { void filter_hostname_events(fz::hostname_lookup* lookup, fz::event_handler* handler) { - auto filter = [&](event_base const& ev) -> bool { - if (ev.derived_type() != hostname_lookup_event::type()) { + auto filter = [&](event_loop::Events::value_type const& ev) -> bool { + if (ev.first != handler) { return false; } - return std::get<0>(static_cast<hostname_lookup_event const&>(ev).v_) == lookup; + else if (ev.second->derived_type() != hostname_lookup_event::type()) { + return false; + } + return std::get<0>(static_cast<hostname_lookup_event const&>(*ev.second).v_) == lookup; }; - handler->filter_events(filter); + handler->event_loop_.filter_events(filter); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/libfilezilla/event.hpp new/libfilezilla-0.42.2/lib/libfilezilla/event.hpp --- old/libfilezilla-0.43.0/lib/libfilezilla/event.hpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/libfilezilla/event.hpp 2022-07-08 15:18:44.000000000 +0200 @@ -74,7 +74,7 @@ template<typename First_Value, typename...Remaining_Values> explicit simple_event(First_Value&& value, Remaining_Values&& ...values) - : v_(std::forward<First_Value>(value), std::forward<Remaining_Values>(values)...) + : v_(std::forward<First_Value>(value), std::forward<Remaining_Values>(values)...) { } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/libfilezilla/event_handler.hpp new/libfilezilla-0.42.2/lib/libfilezilla/event_handler.hpp --- old/libfilezilla-0.43.0/lib/libfilezilla/event_handler.hpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/libfilezilla/event_handler.hpp 2022-07-08 15:18:44.000000000 +0200 @@ -86,19 +86,12 @@ */ template<typename T, typename... Args> void send_event(Args&&... args) { - event_loop_.send_event(this, new T(std::forward<Args>(args)...), true); + event_loop_.send_event(this, new T(std::forward<Args>(args)...)); } template<typename T> void send_event(T* evt) { - event_loop_.send_event(this, evt, true); - } - - - /// Be careful with lifetime. - template<typename T> - void send_persistent_event(T* evt) { - event_loop_.send_event(this, evt, false); + event_loop_.send_event(this, evt); } /** \brief Adds a timer, returns the timer id. @@ -162,19 +155,6 @@ */ timer_id stop_add_timer(timer_id id, duration const& interval, bool one_shot); - void filter_events(std::function<bool(event_base& ev)> const& filter) { - event_loop_.filter_events([&](event_handler*& h, event_base& ev) { - if (h != this) { - return false; - } - return filter(ev); - }); - } - - void resend_current_event() { - event_loop_.resend_current_event(); - } - event_loop & event_loop_; private: friend class event_loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/libfilezilla/event_loop.hpp new/libfilezilla-0.42.2/lib/libfilezilla/event_loop.hpp --- old/libfilezilla-0.43.0/lib/libfilezilla/event_loop.hpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/libfilezilla/event_loop.hpp 2022-07-08 15:18:44.000000000 +0200 @@ -33,6 +33,8 @@ class FZ_PUBLIC_SYMBOL event_loop final { public: + typedef std::deque<std::pair<event_handler*, event_base*>> Events; + /// Spawns a thread and starts the loop event_loop(); @@ -62,7 +64,7 @@ * * Filtering events is a blocking operation and temporarily pauses the loop. */ - void filter_events(std::function<bool (event_handler*&, event_base&)> const& filter); + void filter_events(std::function<bool (Events::value_type&)> const& filter); /** \brief Stops the loop * @@ -76,11 +78,6 @@ void run(); bool running() const; - - void resend_current_event() { - resend_ = true; - } - private: friend class event_handler; @@ -90,7 +87,7 @@ void FZ_PRIVATE_SYMBOL stop_timer(timer_id id); timer_id FZ_PRIVATE_SYMBOL stop_add_timer(timer_id id, event_handler* handler, monotonic_clock const& deadline, duration const& interval); - void send_event(event_handler* handler, event_base* evt, bool deletable); + void send_event(event_handler* handler, event_base* evt); // Process the next (if any) event. Returns true if an event has been processed bool FZ_PRIVATE_SYMBOL process_event(scoped_lock & l); @@ -99,7 +96,6 @@ bool FZ_PRIVATE_SYMBOL process_timers(scoped_lock & l, monotonic_clock& now); void FZ_PRIVATE_SYMBOL entry(); - void FZ_PRIVATE_SYMBOL timer_entry(); struct FZ_PRIVATE_SYMBOL timer_data final { @@ -113,16 +109,12 @@ typedef std::vector<timer_data> Timers; - typedef std::deque<std::tuple<event_handler*, event_base*, bool>> Events; Events pending_events_; Timers timers_; mutable mutex sync_; condition cond_; - condition timer_cond_; - bool do_timers_{}; - event_handler * active_handler_{}; monotonic_clock deadline_; @@ -134,12 +126,8 @@ std::unique_ptr<thread> thread_; std::unique_ptr<async_task> task_; - std::unique_ptr<thread> timer_thread_; - std::unique_ptr<async_task> timer_task_; - bool quit_{}; bool threadless_{}; - bool resend_{}; }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/libfilezilla/string.hpp new/libfilezilla-0.42.2/lib/libfilezilla/string.hpp --- old/libfilezilla-0.43.0/lib/libfilezilla/string.hpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/libfilezilla/string.hpp 2023-04-12 14:41:33.000000000 +0200 @@ -266,10 +266,10 @@ /// Returns the function argument of the type matching the template argument. \sa fzS template<typename Char> -constexpr Char const* choose_string(char const* c, wchar_t const* w); +Char const* choose_string(char const* c, wchar_t const* w); -template<> constexpr inline char const* choose_string(char const* c, wchar_t const*) { return c; } -template<> constexpr inline wchar_t const* choose_string(char const*, wchar_t const* w) { return w; } +template<> inline char const* choose_string(char const* c, wchar_t const*) { return c; } +template<> inline wchar_t const* choose_string(char const*, wchar_t const* w) { return w; } #if !defined(fzS) || defined(DOXYGEN) /** \brief Macro to get const pointer to a string of the corresponding type diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/libfilezilla/time.hpp new/libfilezilla-0.42.2/lib/libfilezilla/time.hpp --- old/libfilezilla-0.43.0/lib/libfilezilla/time.hpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/libfilezilla/time.hpp 2022-09-13 11:39:49.000000000 +0200 @@ -429,7 +429,7 @@ public: /// Gets the current point in time time static monotonic_clock now() { - return monotonic_clock(std::chrono::time_point_cast<std::chrono::milliseconds>(clock_type::now())); + return monotonic_clock(clock_type::now()); } explicit operator bool() const { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/libfilezilla/tls_layer.hpp new/libfilezilla-0.42.2/lib/libfilezilla/tls_layer.hpp --- old/libfilezilla-0.43.0/lib/libfilezilla/tls_layer.hpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/libfilezilla/tls_layer.hpp 2022-02-03 10:53:39.000000000 +0100 @@ -162,14 +162,6 @@ /// Returns the version of the loaded GnuTLS library, may be different than the version used at compile-time. static std::string get_gnutls_version(); - /// Type of certificate to create. - enum class cert_type { - any, /// Except ca. Includes, but is not limited to, client and server. - client, - server, - ca - }; - /** \brief Creates a new private key and a self-signed certificate. * * The distinguished name must be a RFC4514-compliant string. @@ -178,20 +170,8 @@ * * The output pair is in PEM, first element is the key and the second the certificate. */ - static std::pair<std::string, std::string> generate_selfsigned_certificate(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, cert_type type = cert_type::any, bool ecsda = true); - - /// Creates CA certificate. - static std::pair<std::string, std::string> generate_ca_certificate(native_string const& password, std::string const& distinguished_name, duration const& lifetime = {}, bool ecdsa = true); - - /// Creates a CSR - static std::pair<std::string, std::string> generate_csr(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, bool csr_as_pem = true, cert_type type = cert_type::any); - - /** - * /brief Creates a certificate from a CSR. - * - * If DN and hostnames are not given, the DN/hostnames from the CSR are taken. - */ - static std::string generate_cert_from_csr(std::pair<std::string, std::string> const& issuer, native_string const& password, std::string const& csr, std::string const& distinguished_name = {}, std::vector<std::string> const& hostnames = {}, duration const& lifetime = {}, cert_type type = cert_type::any); + static std::pair<std::string, std::string> generate_selfsigned_certificate(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames); + static std::pair<std::string, std::string> generate_csr(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, bool csr_as_pem = true); /** \brief Negotiate application protocol * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/mutex.cpp new/libfilezilla-0.42.2/lib/mutex.cpp --- old/libfilezilla-0.43.0/lib/mutex.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/mutex.cpp 2022-02-03 10:53:39.000000000 +0100 @@ -333,7 +333,7 @@ bool const success = SleepConditionVariableCS(&cond_, l.m_, static_cast<DWORD>(ms)) != 0; debug_post_wait(l.m_); #else - + int res; timespec ts; #if HAVE_CLOCK_GETTIME && HAVE_DECL_PTHREAD_CONDATTR_SETCLOCK clock_gettime(CLOCK_MONOTONIC, &ts); @@ -346,12 +346,11 @@ ts.tv_sec += timeout.get_milliseconds() / 1000; ts.tv_nsec += (timeout.get_milliseconds() % 1000) * 1000 * 1000; - if (ts.tv_nsec >= 1000000000ll) { + if (ts.tv_nsec > 1000000000ll) { ++ts.tv_sec; ts.tv_nsec -= 1000000000ll; } - int res; do { debug_prepare_wait(l.m_); res = pthread_cond_timedwait(&cond_, l.m_, &ts); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/process.cpp new/libfilezilla-0.42.2/lib/process.cpp --- old/libfilezilla-0.43.0/lib/process.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/process.cpp 2023-04-12 14:41:33.000000000 +0200 @@ -371,14 +371,17 @@ return; } - auto process_event_filter = [&](event_base const& ev) -> bool { - if (ev.derived_type() == process_event::type()) { - return std::get<0>(static_cast<process_event const&>(ev).v_) == &process_; + auto process_event_filter = [&](event_loop::Events::value_type const& ev) -> bool { + if (ev.first != handler_) { + return false; + } + else if (ev.second->derived_type() == process_event::type()) { + return std::get<0>(static_cast<process_event const&>(*ev.second).v_) == &process_; } return false; }; - handler_->filter_events(process_event_filter); + handler_->event_loop_.filter_events(process_event_filter); } template<typename Out, typename In> @@ -892,14 +895,17 @@ return; } - auto process_event_filter = [&](event_base const& ev) -> bool { - if (ev.derived_type() == process_event::type()) { - return std::get<0>(static_cast<process_event const&>(ev).v_) == &process_; + auto process_event_filter = [&](event_loop::Events::value_type const& ev) -> bool { + if (ev.first != handler_) { + return false; + } + else if (ev.second->derived_type() == process_event::type()) { + return std::get<0>(static_cast<process_event const&>(*ev.second).v_) == &process_; } return false; }; - handler_->filter_events(process_event_filter); + handler_->event_loop_.filter_events(process_event_filter); } bool do_waitpid(bool wait = false) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/socket.cpp new/libfilezilla-0.42.2/lib/socket.cpp --- old/libfilezilla-0.43.0/lib/socket.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/socket.cpp 2023-04-12 14:41:33.000000000 +0200 @@ -96,17 +96,20 @@ return; } - auto socket_event_filter = [&](event_base const& ev) -> bool { - if (ev.derived_type() == socket_event::type()) { - return std::get<0>(static_cast<socket_event const&>(ev).v_) == source; + auto socket_event_filter = [&](event_loop::Events::value_type const& ev) -> bool { + if (ev.first != handler) { + return false; } - else if (ev.derived_type() == hostaddress_event::type()) { - return std::get<0>(static_cast<hostaddress_event const&>(ev).v_) == source; + else if (ev.second->derived_type() == socket_event::type()) { + return std::get<0>(static_cast<socket_event const&>(*ev.second).v_) == source; + } + else if (ev.second->derived_type() == hostaddress_event::type()) { + return std::get<0>(static_cast<hostaddress_event const&>(*ev.second).v_) == source; } return false; }; - handler->filter_events(socket_event_filter); + handler->event_loop_.filter_events(socket_event_filter); } socket_event_flag change_socket_event_handler(event_handler * old_handler, event_handler * new_handler, socket_event_source const* const source, socket_event_flag remove) @@ -127,10 +130,10 @@ #endif socket_event_flag ret = socket_event_flag{}; - auto socket_event_filter = [&](event_handler*& h, event_base const& ev) -> bool { - if (h == old_handler) { - if (ev.derived_type() == socket_event::type()) { - auto & sev = static_cast<socket_event const&>(ev); + auto socket_event_filter = [&](event_loop::Events::value_type & ev) -> bool { + if (ev.first == old_handler) { + if (ev.second->derived_type() == socket_event::type()) { + auto & sev = static_cast<socket_event const&>(*ev.second); if (std::get<0>(sev.v_) == source) { auto const flag = std::get<1>(sev.v_); #if DEBUG_SOCKETEVENTS @@ -141,12 +144,12 @@ return true; } ret |= flag; - h = new_handler; + ev.first = new_handler; } } - else if (ev.derived_type() == hostaddress_event::type()) { - if (std::get<0>(static_cast<hostaddress_event const&>(ev).v_) == source) { - h = new_handler; + else if (ev.second->derived_type() == hostaddress_event::type()) { + if (std::get<0>(static_cast<hostaddress_event const&>(*ev.second).v_) == source) { + ev.first = new_handler; } } } @@ -166,9 +169,9 @@ bool ret = false; - auto socket_event_filter = [&](event_base const& ev) -> bool { - if (ev.derived_type() == socket_event::type()) { - auto const& socket_ev = static_cast<socket_event const&>(ev).v_; + auto socket_event_filter = [&](event_loop::Events::value_type const& ev) -> bool { + if (ev.first == handler && ev.second->derived_type() == socket_event::type()) { + auto const& socket_ev = static_cast<socket_event const&>(*ev.second).v_; if (std::get<0>(socket_ev) == source && std::get<1>(socket_ev) & event) { ret = true; } @@ -176,7 +179,7 @@ return false; }; - handler->filter_events(socket_event_filter); + handler->event_loop_.filter_events(socket_event_filter); return ret; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/tls_layer.cpp new/libfilezilla-0.42.2/lib/tls_layer.cpp --- old/libfilezilla-0.43.0/lib/tls_layer.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/tls_layer.cpp 2022-02-03 10:53:39.000000000 +0100 @@ -126,24 +126,14 @@ return impl_->connect(host, port, family); } -std::pair<std::string, std::string> tls_layer::generate_selfsigned_certificate(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, cert_type type, bool ecdsa) +std::pair<std::string, std::string> tls_layer::generate_selfsigned_certificate(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames) { - return tls_layer_impl::generate_selfsigned_certificate(password, distinguished_name, hostnames, duration(), type, ecdsa); + return tls_layer_impl::generate_selfsigned_certificate(password, distinguished_name, hostnames); } -std::pair<std::string, std::string> tls_layer::generate_ca_certificate(native_string const& password, std::string const& distinguished_name, duration const& lifetime, bool ecdsa) +std::pair<std::string, std::string> tls_layer::generate_csr(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, bool csr_as_pem) { - return tls_layer_impl::generate_selfsigned_certificate(password, distinguished_name, {}, lifetime, cert_type::ca, ecdsa); -} - -std::pair<std::string, std::string> tls_layer::generate_csr(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, bool csr_as_pem, cert_type type) -{ - return tls_layer_impl::generate_csr(password, distinguished_name, hostnames, csr_as_pem, type); -} - -std::string tls_layer::generate_cert_from_csr(std::pair<std::string, std::string> const& issuer, native_string const& password, std::string const& csr, std::string const& distinguished_name, std::vector<std::string> const& hostnames, duration const& lifetime, cert_type type) -{ - return tls_layer_impl::generate_cert_from_csr(issuer, password, csr, distinguished_name, hostnames, lifetime, type); + return tls_layer_impl::generate_csr(password, distinguished_name, hostnames, csr_as_pem); } int tls_layer::shutdown_read() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/tls_layer_impl.cpp new/libfilezilla-0.42.2/lib/tls_layer_impl.cpp --- old/libfilezilla-0.43.0/lib/tls_layer_impl.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/tls_layer_impl.cpp 2022-12-12 15:29:22.000000000 +0100 @@ -56,14 +56,17 @@ return; } - auto event_filter = [&](event_base const& ev) -> bool { - if (ev.derived_type() == certificate_verification_event::type()) { - return std::get<0>(static_cast<certificate_verification_event const&>(ev).v_) == source; + auto event_filter = [&](event_loop::Events::value_type const& ev) -> bool { + if (ev.first != handler) { + return false; + } + else if (ev.second->derived_type() == certificate_verification_event::type()) { + return std::get<0>(static_cast<certificate_verification_event const&>(*ev.second).v_) == source; } return false; }; - handler->filter_events(event_filter); + handler->event_loop_.filter_events(event_filter); } extern "C" ssize_t c_push_function(gnutls_transport_ptr_t ptr, const void* data, size_t len) @@ -2224,438 +2227,244 @@ return ret; } -namespace { -bool get_purposes(gnutls_x509_crt_t & crt, std::set<std::string> & purposes) +std::pair<std::string, std::string> tls_layer_impl::generate_selfsigned_certificate(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames) { - for (unsigned int i = 0; ; ++i) { - char buf[512]; - size_t s = 512; - unsigned int critical{}; - int res = gnutls_x509_crt_get_key_purpose_oid(crt, i, &buf, &s, &critical); - if (res) { - return res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - } - if (!purposes.emplace(buf).second) { - return false; - } + std::pair<std::string, std::string> ret; + + gnutls_x509_privkey_t priv; + int res = gnutls_x509_privkey_init(&priv); + if (res) { + return ret; } - return false; -} + auto fmt = GNUTLS_PK_ECDSA; + unsigned int bits = gnutls_sec_param_to_pk_bits(fmt, GNUTLS_SEC_PARAM_HIGH); + if (fmt == GNUTLS_PK_RSA && bits < 2048) { + bits = 2048; + } -bool get_purposes(gnutls_x509_crq_t & crq, std::set<std::string> & purposes) -{ - for (unsigned int i = 0; ; ++i) { - char buf[512]; - size_t s = 512; - unsigned int critical{}; - int res = gnutls_x509_crq_get_key_purpose_oid(crq, i, &buf, &s, &critical); - if (res) { - return res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - } - if (!purposes.emplace(buf).second) { - return false; - } + res = gnutls_x509_privkey_generate(priv, fmt, bits, 0); + if (res) { + gnutls_x509_privkey_deinit(priv); + return ret; } - return false; -} + datum_holder kh; -bool verify_purposes(std::set<std::string> & purposes, tls_layer::cert_type t) -{ - for (auto const& p : purposes) { - if (p == GNUTLS_KP_TLS_WWW_CLIENT) { - if (t != tls_layer::cert_type::any && t != tls_layer::cert_type::client) { - return {}; - } - } - else if (p == GNUTLS_KP_TLS_WWW_SERVER) { - if (t != tls_layer::cert_type::any && t != tls_layer::cert_type::server) { - return {}; - } - } - else { - return {}; - } + if (password.empty()) { + res = gnutls_x509_privkey_export2(priv, GNUTLS_X509_FMT_PEM, &kh); + } + else { + res = gnutls_x509_privkey_export2_pkcs8(priv, GNUTLS_X509_FMT_PEM, to_utf8(password).c_str(), 0, &kh); + } + if (res) { + gnutls_x509_privkey_deinit(priv); + return ret; } - return true; -} + gnutls_x509_crt_t crt; + res = gnutls_x509_crt_init(&crt); + if (res) { + gnutls_x509_privkey_deinit(priv); + return ret; + } -bool set_cert_params(gnutls_x509_crt_t & crt, tls_layer::cert_type t, std::string const& distinguished_name, std::vector<std::string> const& hostnames, duration lifetime) -{ - int res = gnutls_x509_crt_set_serial(crt, random_bytes(20).data(), 20); + res = gnutls_x509_crt_set_version(crt, 3); if (res) { - return {}; + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; + } + + res = gnutls_x509_crt_set_key(crt, priv); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; + } + + char const* out{}; + res = gnutls_x509_crt_set_dn(crt, distinguished_name.c_str(), &out); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; } - if (!distinguished_name.empty()) { - char const* out{}; - int res = gnutls_x509_crt_set_dn(crt, distinguished_name.c_str(), &out); + for (auto const& hostname : hostnames) { + res = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, hostname.c_str(), hostname.size(), GNUTLS_FSAN_APPEND); if (res) { - return {}; + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; } } - if (!hostnames.empty()) { - for (size_t i = 0; i < hostnames.size(); ++i) { - res = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, hostnames[i].c_str(), hostnames[i].size(), i ? GNUTLS_FSAN_APPEND : GNUTLS_FSAN_SET); - if (res) { - return {}; - } - } + res = gnutls_x509_crt_set_serial(crt, random_bytes(20).data(), 20); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; } auto const now = datetime::now(); - if (lifetime <= duration()) { - lifetime = duration::from_days(366); - } - res = gnutls_x509_crt_set_activation_time(crt, (now - duration::from_minutes(5)).get_time_t()); if (res) { - return {}; + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; } - res = gnutls_x509_crt_set_expiration_time(crt, (now + lifetime).get_time_t()); + res = gnutls_x509_crt_set_expiration_time(crt, (now + duration::from_days(366)).get_time_t()); if (res) { - return {}; - } - - int usage{}; - if (t == tls_layer::cert_type::ca) { - usage = GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN; - } - else { - usage = GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT; + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; } - res = gnutls_x509_crt_set_key_usage(crt, usage); + res = gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT); if (res) { - return {}; + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; } - - res = gnutls_x509_crt_set_basic_constraints(crt, (t == tls_layer::cert_type::ca) ? 1 : 0, -1); + res = gnutls_x509_crt_set_basic_constraints(crt, 0, -1); if (res) { - return {}; - } - - std::set<std::string> purposes; - if (!get_purposes(crt, purposes)) { - return {}; - } - if (!verify_purposes(purposes, t)) { - return false; - } - if (t == tls_layer::cert_type::client || t == tls_layer::cert_type::server) { - auto p = (t == tls_layer::cert_type::server) ? GNUTLS_KP_TLS_WWW_SERVER : GNUTLS_KP_TLS_WWW_CLIENT; - if (purposes.find(p) == purposes.end()) { - res = gnutls_x509_crt_set_key_purpose_oid(crt, p, 1); - if (res) { - return {}; - } - } + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; } - return true; -} -} -std::pair<std::string, std::string> tls_layer_impl::generate_selfsigned_certificate(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, duration const& lifetime, tls_layer::cert_type type, bool ecdsa) -{ - gnutls_x509_privkey_t priv; - int res = gnutls_x509_privkey_init(&priv); + res = gnutls_x509_crt_sign2(crt, crt, priv, GNUTLS_DIG_SHA256, 0); if (res) { - return {}; + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crt_deinit(crt); + return ret; } - gnutls_x509_crt_t crt; - res = gnutls_x509_crt_init(&crt); + datum_holder ch; + res = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &ch); if (res) { gnutls_x509_privkey_deinit(priv); - return {}; + gnutls_x509_crt_deinit(crt); + return ret; } - auto ret = [&]() -> std::pair<std::string, std::string> { - - auto fmt = ecdsa ? GNUTLS_PK_ECDSA : GNUTLS_PK_RSA; - unsigned int bits = gnutls_sec_param_to_pk_bits(fmt, GNUTLS_SEC_PARAM_HIGH); - if (fmt == GNUTLS_PK_RSA) { - unsigned int const min_rsa_bits = type == tls_layer::cert_type::ca ? 4096 : 2048; - if (bits < min_rsa_bits) { - bits = min_rsa_bits; - } - } - - res = gnutls_x509_privkey_generate(priv, fmt, bits, 0); - if (res) { - return {}; - } - - datum_holder kh; - - if (password.empty()) { - res = gnutls_x509_privkey_export2(priv, GNUTLS_X509_FMT_PEM, &kh); - } - else { - res = gnutls_x509_privkey_export2_pkcs8(priv, GNUTLS_X509_FMT_PEM, to_utf8(password).c_str(), 0, &kh); - } - if (res) { - return {}; - } - - res = gnutls_x509_crt_set_version(crt, 3); - if (res) { - return {}; - } - - res = gnutls_x509_crt_set_key(crt, priv); - if (res) { - return {}; - } - - if (!set_cert_params(crt, type, distinguished_name, hostnames, lifetime)) { - return {}; - } - - res = gnutls_x509_crt_sign2(crt, crt, priv, GNUTLS_DIG_SHA256, 0); - if (res) { - return {}; - } - - datum_holder ch; - res = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &ch); - if (res) { - return {}; - } - - return {kh.to_string(), ch.to_string()}; - }(); - gnutls_x509_privkey_deinit(priv); gnutls_x509_crt_deinit(crt); + ret.first = kh.to_string(); + ret.second = ch.to_string(); return ret; } -std::string tls_layer_impl::generate_cert_from_csr(std::pair<std::string, std::string> const& issuer, native_string const& password, std::string const& csr, std::string const& distinguished_name, std::vector<std::string> const& hostnames, duration const& lifetime, tls_layer::tls_layer::cert_type type) +std::pair<std::string, std::string> tls_layer_impl::generate_csr(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, bool csr_as_pem) { + std::pair<std::string, std::string> ret; + gnutls_x509_privkey_t priv; int res = gnutls_x509_privkey_init(&priv); if (res) { - return {}; + return ret; } - gnutls_x509_crt_t icrt; - if (gnutls_x509_crt_init(&icrt)) { - gnutls_x509_privkey_deinit(priv); - return {}; + + auto fmt = GNUTLS_PK_ECDSA; + unsigned int bits = gnutls_sec_param_to_pk_bits(fmt, GNUTLS_SEC_PARAM_HIGH); + if (fmt == GNUTLS_PK_RSA && bits < 2048) { + bits = 2048; } - gnutls_x509_crq_t crq; - if (gnutls_x509_crq_init(&crq) != 0) { - gnutls_x509_crt_deinit(icrt); + + res = gnutls_x509_privkey_generate(priv, fmt, bits, 0); + if (res) { gnutls_x509_privkey_deinit(priv); - return {}; + return ret; } - gnutls_x509_crt_t crt; - if (gnutls_x509_crt_init(&crt) != 0) { - gnutls_x509_crq_deinit(crq); - gnutls_x509_crt_deinit(icrt); - gnutls_x509_privkey_deinit(priv); - return {}; - } - - std::string cert = [&]() -> std::string { - - gnutls_datum_t kd; - kd.data = const_cast<unsigned char*>(reinterpret_cast<unsigned char const*>(issuer.first.data())); - kd.size = issuer.first.size(); - if (gnutls_x509_privkey_import2(priv, &kd, GNUTLS_X509_FMT_PEM, to_utf8(password).c_str(), 0) != 0) { - return {}; - } - - gnutls_datum_t icrtd; - icrtd.data = const_cast<unsigned char*>(reinterpret_cast<unsigned char const*>(issuer.second.data())); - icrtd.size = issuer.second.size(); - res = gnutls_x509_crt_import(icrt, &icrtd, GNUTLS_X509_FMT_PEM); - if (res) { - return {}; - } - - gnutls_datum_t csrd; - csrd.data = const_cast<unsigned char*>(reinterpret_cast<unsigned char const*>(csr.data())); - csrd.size = csr.size(); - res = gnutls_x509_crq_import(crq, &csrd, GNUTLS_X509_FMT_PEM); - if (res) { - return {}; - } - - res = gnutls_x509_crq_verify(crq, 0); - if (res) { - return {}; - } - - // Verify key purpose oids - std::set<std::string> purposes; - if (!get_purposes(crq, purposes)) { - return {}; - } - if (!verify_purposes(purposes, type)) { - return {}; - } - - // Verify key usage - unsigned int usage{}; - unsigned int critical{}; - if ((res = gnutls_x509_crq_get_key_usage(crq, &usage, &critical)) && res != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - return {}; - } - - if (type == tls_layer::cert_type::ca) { - if (usage & ~(GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN)) { - return {}; - } - } - else { - if (usage & ~(GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT)) { - return {}; - } - } - - res = gnutls_x509_crt_set_version(crt, 3); - if (res) { - return {}; - } - - res = gnutls_x509_crt_set_crq(crt, crq); - if (res) { - return {}; - } - - res = gnutls_x509_crt_set_crq_extensions(crt, crq); - if (res) { - return {}; - } - - if (!set_cert_params(crt, type, distinguished_name, hostnames, lifetime)) { - return {}; - } - - res = gnutls_x509_crt_sign(crt, icrt, priv); - if (res) { - return {}; - } - - datum_holder ch; - res = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &ch); - if (res) { - return {}; - } - return ch.to_string(); - }(); + datum_holder kh; - gnutls_x509_crt_deinit(crt); - gnutls_x509_crq_deinit(crq); - gnutls_x509_crt_deinit(icrt); - gnutls_x509_privkey_deinit(priv); - - return cert; -} - -std::pair<std::string, std::string> tls_layer_impl::generate_csr(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, bool csr_as_pem, tls_layer::cert_type type) -{ - gnutls_x509_privkey_t priv; - int res = gnutls_x509_privkey_init(&priv); + if (password.empty()) { + res = gnutls_x509_privkey_export2(priv, GNUTLS_X509_FMT_PEM, &kh); + } + else { + res = gnutls_x509_privkey_export2_pkcs8(priv, GNUTLS_X509_FMT_PEM, to_utf8(password).c_str(), 0, &kh); + } if (res) { - return {}; + gnutls_x509_privkey_deinit(priv); + return ret; } + gnutls_x509_crq_t crq; res = gnutls_x509_crq_init(&crq); if (res) { gnutls_x509_privkey_deinit(priv); - return {}; + return ret; } - auto ret = [&]() -> std::pair<std::string, std::string> { - - auto fmt = GNUTLS_PK_ECDSA; - unsigned int bits = gnutls_sec_param_to_pk_bits(fmt, GNUTLS_SEC_PARAM_HIGH); - if (fmt == GNUTLS_PK_RSA && bits < 2048) { - bits = 2048; - } - - res = gnutls_x509_privkey_generate(priv, fmt, bits, 0); - if (res) { - return {}; - } - - datum_holder kh; - - if (password.empty()) { - res = gnutls_x509_privkey_export2(priv, GNUTLS_X509_FMT_PEM, &kh); - } - else { - res = gnutls_x509_privkey_export2_pkcs8(priv, GNUTLS_X509_FMT_PEM, to_utf8(password).c_str(), 0, &kh); - } - if (res) { - return {}; - } - - res = gnutls_x509_crq_set_version(crq, 3); - if (res) { - return {}; - } - - res = gnutls_x509_crq_set_key(crq, priv); - if (res) { - return {}; - } + res = gnutls_x509_crq_set_version(crq, 3); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + return ret; + } - char const* out{}; - res = gnutls_x509_crq_set_dn(crq, distinguished_name.c_str(), &out); - if (res) { - return {}; - } + res = gnutls_x509_crq_set_key(crq, priv); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + return ret; + } - for (auto const& hostname : hostnames) { - res = gnutls_x509_crq_set_subject_alt_name(crq, GNUTLS_SAN_DNSNAME, hostname.c_str(), hostname.size(), GNUTLS_FSAN_APPEND); - if (res) { - return {}; - } - } + char const* out{}; + res = gnutls_x509_crq_set_dn(crq, distinguished_name.c_str(), &out); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + return ret; + } - res = gnutls_x509_crq_set_key_usage(crq, (type == tls_layer::cert_type::ca) ? (GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN) : (GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT)); + for (auto const& hostname : hostnames) { + res = gnutls_x509_crq_set_subject_alt_name(crq, GNUTLS_SAN_DNSNAME, hostname.c_str(), hostname.size(), GNUTLS_FSAN_APPEND); if (res) { - return {}; - } - - if (type == tls_layer::cert_type::client || type == tls_layer::cert_type::server) { - res = gnutls_x509_crq_set_key_purpose_oid(crq, (type == tls_layer::cert_type::server) ? GNUTLS_KP_TLS_WWW_SERVER : GNUTLS_KP_TLS_WWW_CLIENT, 1); - if (res) { - return {}; - } + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + return ret; } + } - res = gnutls_x509_crq_set_basic_constraints(crq, 0, -1); - if (res) { - return {}; - } + res = gnutls_x509_crq_set_key_usage(crq, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + return ret; + } - res = gnutls_x509_crq_sign2(crq, priv, GNUTLS_DIG_SHA256, 0); - if (res) { - return {}; - } + res = gnutls_x509_crq_set_basic_constraints(crq, 0, -1); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + return ret; + } - datum_holder ch; - res = gnutls_x509_crq_export2(crq, csr_as_pem ? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER, &ch); - if (res) { - return {}; - } + res = gnutls_x509_crq_sign2(crq, priv, GNUTLS_DIG_SHA256, 0); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + return ret; + } - return {kh.to_string(), ch.to_string()}; - }(); + datum_holder ch; + res = gnutls_x509_crq_export2(crq, csr_as_pem ? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER, &ch); + if (res) { + gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + return ret; + } - gnutls_x509_crq_deinit(crq); gnutls_x509_privkey_deinit(priv); + gnutls_x509_crq_deinit(crq); + ret.first = kh.to_string(); + ret.second = ch.to_string(); return ret; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/lib/tls_layer_impl.hpp new/libfilezilla-0.42.2/lib/tls_layer_impl.hpp --- old/libfilezilla-0.43.0/lib/tls_layer_impl.hpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/lib/tls_layer_impl.hpp 2022-12-12 15:29:22.000000000 +0100 @@ -84,10 +84,8 @@ ssize_t push_function(void const* data, size_t len); ssize_t pull_function(void* data, size_t len); - static std::pair<std::string, std::string> generate_selfsigned_certificate(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, duration const& lifetime, tls_layer::cert_type type, bool ecdsa); - static std::pair<std::string, std::string> generate_csr(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, bool csr_as_pem, tls_layer::cert_type type); - - static std::string generate_cert_from_csr(std::pair<std::string, std::string> const& issuer, native_string const& password, std::string const& csr, std::string const& distinguished_name, std::vector<std::string> const& hostnames, duration const& lifetime, tls_layer::cert_type type); + static std::pair<std::string, std::string> generate_selfsigned_certificate(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames); + static std::pair<std::string, std::string> generate_csr(native_string const& password, std::string const& distinguished_name, std::vector<std::string> const& hostnames, bool csr_as_pem); int shutdown_read(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libfilezilla-0.43.0/tests/eventloop.cpp new/libfilezilla-0.42.2/tests/eventloop.cpp --- old/libfilezilla-0.43.0/tests/eventloop.cpp 2023-05-26 09:44:37.000000000 +0200 +++ new/libfilezilla-0.42.2/tests/eventloop.cpp 2021-07-02 11:04:19.000000000 +0200 @@ -125,15 +125,15 @@ CPPUNIT_ASSERT(cond2_.wait(l, fz::duration::from_seconds(1))); } - auto f = [&](fz::event_handler *&, fz::event_base& ev) -> bool { - if (ev.derived_type() == T1::type()) { + auto f = [&](fz::event_loop::Events::value_type& ev) -> bool { + if (ev.second->derived_type() == T1::type()) { ++c_; return true; } - if (ev.derived_type() == T2::type()) { + if (ev.second->derived_type() == T2::type()) { ++d_; - std::get<0>(static_cast<T2&>(ev).v_) += 4; + std::get<0>(static_cast<T2&>(*ev.second).v_) += 4; } return false;