Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
Index: Makefile
===================================================================
--- Makefile	(nonexistent)
+++ Makefile	(revision 5)
@@ -0,0 +1,56 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/l/botan
+
+versions    = 2.19.3
+pkgname     = Botan
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+patches     = $(CURDIR)/patches/Botan-2.19.3-boost-bind.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======\n" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-2.19.3-boost-bind-patch ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli/tls_http_server.cpp
===================================================================
--- create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli/tls_http_server.cpp	(nonexistent)
+++ create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli/tls_http_server.cpp	(revision 5)
@@ -0,0 +1,579 @@
+/*
+* (C) 2014,2015,2017,2019 Jack Lloyd
+* (C) 2016 Matthias Gierlings
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "cli.h"
+
+#if defined(BOTAN_HAS_TLS) && defined(BOTAN_HAS_BOOST_ASIO) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <string>
+#include <vector>
+#include <thread>
+#include <atomic>
+
+#define _GLIBCXX_HAVE_GTHR_DEFAULT
+#include <boost/asio.hpp>
+#include <boost/bind/bind.hpp>
+#include <botan/internal/os_utils.h>
+
+#include <botan/tls_server.h>
+#include <botan/tls_messages.h>
+#include <botan/x509cert.h>
+#include <botan/pkcs8.h>
+#include <botan/version.h>
+#include <botan/hex.h>
+#include <botan/rng.h>
+
+#if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER)
+   #include <botan/tls_session_manager_sqlite.h>
+#endif
+
+#include "tls_helpers.h"
+
+#if BOOST_VERSION >= 107000
+#define GET_IO_SERVICE(s) (static_cast<boost::asio::io_context&>((s).get_executor().context()))
+#else
+#define GET_IO_SERVICE(s) ((s).get_io_service())
+#endif
+
+namespace Botan_CLI {
+
+namespace {
+
+using boost::asio::ip::tcp;
+
+inline void log_exception(const char* where, const std::exception& e)
+   {
+   std::cout << where << ' ' << e.what() << std::endl;
+   }
+
+class ServerStatus
+   {
+   public:
+      ServerStatus(size_t max_clients) : m_max_clients(max_clients), m_clients_serviced(0) {}
+
+      bool should_exit() const
+         {
+         if(m_max_clients == 0)
+            return false;
+
+         return clients_serviced() >= m_max_clients;
+         }
+
+      void client_serviced() { m_clients_serviced++; }
+
+      size_t clients_serviced() const { return m_clients_serviced.load(); }
+   private:
+      size_t m_max_clients;
+      std::atomic<size_t> m_clients_serviced;
+   };
+
+/*
+* This is an incomplete and highly buggy HTTP request parser. It is just
+* barely sufficient to handle a GET request sent by a browser.
+*/
+class HTTP_Parser final
+   {
+   public:
+      class Request
+         {
+         public:
+            const std::string& verb() const { return m_verb; }
+            const std::string& location() const { return m_location; }
+            const std::map<std::string, std::string>& headers() const { return m_headers; }
+
+            Request(const std::string& verb,
+                    const std::string& location,
+                    const std::map<std::string, std::string>& headers) :
+               m_verb(verb),
+               m_location(location),
+               m_headers(headers)
+               {}
+
+         private:
+            std::string m_verb;
+            std::string m_location;
+            std::map<std::string, std::string> m_headers;
+         };
+
+      class Callbacks
+         {
+         public:
+            virtual void handle_http_request(const Request& request) = 0;
+            virtual ~Callbacks() = default;
+         };
+
+      HTTP_Parser(Callbacks& cb) : m_cb(cb) {}
+
+      void consume_input(const uint8_t buf[], size_t buf_len)
+         {
+         m_req_buf.append(reinterpret_cast<const char*>(buf), buf_len);
+
+         std::istringstream strm(m_req_buf);
+
+         std::string http_version;
+         std::string verb;
+         std::string location;
+         std::map<std::string, std::string> headers;
+
+         strm >> verb >> location >> http_version;
+
+         if(verb.empty() || location.empty())
+            return;
+
+         while(true)
+            {
+            std::string header_line;
+            std::getline(strm, header_line);
+
+            if(header_line == "\r")
+               {
+               continue;
+               }
+
+            auto delim = header_line.find(": ");
+            if(delim == std::string::npos)
+               {
+               break;
+               }
+
+            const std::string hdr_name = header_line.substr(0, delim);
+            const std::string hdr_val = header_line.substr(delim + 2, std::string::npos);
+
+            headers[hdr_name] = hdr_val;
+
+            if(headers.size() > 1024)
+               throw Botan::Invalid_Argument("Too many HTTP headers sent in request");
+            }
+
+         if(verb != "" && location != "")
+            {
+            Request req(verb, location, headers);
+            m_cb.handle_http_request(req);
+            m_req_buf.clear();
+            }
+         else
+            printf("ignoring\n");
+         }
+   private:
+      Callbacks& m_cb;
+      std::string m_req_buf;
+   };
+
+static const size_t READBUF_SIZE = 4096;
+
+class TLS_Asio_HTTP_Session final : public std::enable_shared_from_this<TLS_Asio_HTTP_Session>,
+                                    public Botan::TLS::Callbacks,
+                                    public HTTP_Parser::Callbacks
+   {
+   public:
+      typedef std::shared_ptr<TLS_Asio_HTTP_Session> pointer;
+
+      static pointer create(
+         boost::asio::io_service& io,
+         Botan::TLS::Session_Manager& session_manager,
+         Botan::Credentials_Manager& credentials,
+         Botan::TLS::Policy& policy)
+         {
+         return pointer(new TLS_Asio_HTTP_Session(io, session_manager, credentials, policy));
+         }
+
+      tcp::socket& client_socket()
+         {
+         return m_client_socket;
+         }
+
+      void start()
+         {
+         m_c2s.resize(READBUF_SIZE);
+         client_read(boost::system::error_code(), 0); // start read loop
+         }
+
+      void stop()
+         {
+         m_tls.close();
+         }
+
+   private:
+      TLS_Asio_HTTP_Session(boost::asio::io_service& io,
+                            Botan::TLS::Session_Manager& session_manager,
+                            Botan::Credentials_Manager& credentials,
+                            Botan::TLS::Policy& policy)
+         : m_strand(io)
+         , m_client_socket(io)
+         , m_rng(cli_make_rng())
+         , m_tls(*this, session_manager, credentials, policy, *m_rng) {}
+
+      void client_read(const boost::system::error_code& error,
+                       size_t bytes_transferred)
+         {
+         if(error)
+            {
+            return stop();
+            }
+
+         try
+            {
+            m_tls.received_data(&m_c2s[0], bytes_transferred);
+            }
+         catch(Botan::Exception& e)
+            {
+            log_exception("TLS connection failed", e);
+            return stop();
+            }
+
+         m_client_socket.async_read_some(
+            boost::asio::buffer(&m_c2s[0], m_c2s.size()),
+            m_strand.wrap(
+               boost::bind(
+                  &TLS_Asio_HTTP_Session::client_read, shared_from_this(),
+                  boost::asio::placeholders::error,
+                  boost::asio::placeholders::bytes_transferred)));
+         }
+
+      void handle_client_write_completion(const boost::system::error_code& error)
+         {
+         if(error)
+            {
+            return stop();
+            }
+
+         m_s2c.clear();
+
+         if(m_s2c_pending.empty() && m_tls.is_closed())
+            {
+            m_client_socket.close();
+            }
+         tls_emit_data(nullptr, 0); // initiate another write if needed
+         }
+
+      std::string tls_server_choose_app_protocol(const std::vector<std::string>& /*client_protos*/) override
+         {
+         return "http/1.1";
+         }
+
+      void tls_record_received(uint64_t /*rec_no*/, const uint8_t buf[], size_t buf_len) override
+         {
+         if(!m_http_parser)
+            m_http_parser.reset(new HTTP_Parser(*this));
+
+         m_http_parser->consume_input(buf, buf_len);
+         }
+
+      std::string summarize_request(const HTTP_Parser::Request& request)
+         {
+         std::ostringstream strm;
+
+         strm << "Client " << client_socket().remote_endpoint().address().to_string()
+              << " requested " << request.verb() << " " << request.location() << "\n";
+
+         if(request.headers().empty() == false)
+            {
+            strm << "Client HTTP headers:\n";
+            for(auto kv : request.headers())
+               strm << " " << kv.first << ": " << kv.second << "\n";
+            }
+
+         return strm.str();
+         }
+
+      void handle_http_request(const HTTP_Parser::Request& request) override
+         {
+         std::ostringstream response;
+         if(request.verb() == "GET")
+            {
+            if(request.location() == "/" || request.location() == "/status")
+               {
+               const std::string http_summary = summarize_request(request);
+
+               const std::string report = m_session_summary + m_chello_summary + http_summary;
+
+               response << "HTTP/1.0 200 OK\r\n";
+               response << "Server: " << Botan::version_string() << "\r\n";
+               response << "Content-Type: text/plain\r\n";
+               response << "Content-Length: " << report.size() << "\r\n";
+               response << "\r\n";
+
+               response << report;
+               }
+            else
+               {
+               response << "HTTP/1.0 404 Not Found\r\n\r\n";
+               }
+            }
+         else
+            {
+            response << "HTTP/1.0 405 Method Not Allowed\r\n\r\n";
+            }
+
+         const std::string response_str = response.str();
+         m_tls.send(response_str);
+         m_tls.close();
+         }
+
+      void tls_emit_data(const uint8_t buf[], size_t buf_len) override
+         {
+         if(buf_len > 0)
+            {
+            m_s2c_pending.insert(m_s2c_pending.end(), buf, buf + buf_len);
+            }
+
+         // no write now active and we still have output pending
+         if(m_s2c.empty() && !m_s2c_pending.empty())
+            {
+            std::swap(m_s2c_pending, m_s2c);
+
+            boost::asio::async_write(
+               m_client_socket,
+               boost::asio::buffer(&m_s2c[0], m_s2c.size()),
+               m_strand.wrap(
+                  boost::bind(
+                     &TLS_Asio_HTTP_Session::handle_client_write_completion,
+                     shared_from_this(),
+                     boost::asio::placeholders::error)));
+            }
+         }
+
+      bool tls_session_established(const Botan::TLS::Session& session) override
+         {
+         std::ostringstream strm;
+
+         strm << "TLS negotiation with " << Botan::version_string() << " test server\n\n";
+
+         strm << "Version: " << session.version().to_string() << "\n";
+         strm << "Ciphersuite: " << session.ciphersuite().to_string() << "\n";
+         if(session.session_id().empty() == false)
+            {
+            strm << "SessionID: " << Botan::hex_encode(session.session_id()) << "\n";
+            }
+         if(session.server_info().hostname() != "")
+            {
+            strm << "SNI: " << session.server_info().hostname() << "\n";
+            }
+
+         m_session_summary = strm.str();
+         return true;
+         }
+
+      void tls_inspect_handshake_msg(const Botan::TLS::Handshake_Message& message) override
+         {
+         if(message.type() == Botan::TLS::CLIENT_HELLO)
+            {
+            const Botan::TLS::Client_Hello& client_hello = dynamic_cast<const Botan::TLS::Client_Hello&>(message);
+
+            std::ostringstream strm;
+
+            strm << "Client random: " << Botan::hex_encode(client_hello.random()) << "\n";
+
+            strm << "Client offered following ciphersuites:\n";
+            for(uint16_t suite_id : client_hello.ciphersuites())
+               {
+               Botan::TLS::Ciphersuite ciphersuite = Botan::TLS::Ciphersuite::by_id(suite_id);
+
+               strm << " - 0x"
+                    << std::hex << std::setfill('0') << std::setw(4) << suite_id
+                    << std::dec << std::setfill(' ') << std::setw(0) << " ";
+
+               if(ciphersuite.valid())
+                  strm << ciphersuite.to_string() << "\n";
+               else if(suite_id == 0x00FF)
+                  strm << "Renegotiation SCSV\n";
+               else
+                  strm << "Unknown ciphersuite\n";
+               }
+
+            m_chello_summary = strm.str();
+            }
+
+         }
+
+      void tls_alert(Botan::TLS::Alert alert) override
+         {
+         if(alert.type() == Botan::TLS::Alert::CLOSE_NOTIFY)
+            {
+            m_tls.close();
+            return;
+            }
+         else
+            {
+            std::cout << "Alert " << alert.type_string() << std::endl;
+            }
+         }
+
+      boost::asio::io_service::strand m_strand;
+
+      tcp::socket m_client_socket;
+
+      std::unique_ptr<Botan::RandomNumberGenerator> m_rng;
+      Botan::TLS::Server m_tls;
+      std::string m_chello_summary;
+      std::string m_session_summary;
+      std::unique_ptr<HTTP_Parser> m_http_parser;
+
+      std::vector<uint8_t> m_c2s;
+      std::vector<uint8_t> m_s2c;
+      std::vector<uint8_t> m_s2c_pending;
+   };
+
+class TLS_Asio_HTTP_Server final
+   {
+   public:
+      typedef TLS_Asio_HTTP_Session session;
+
+      TLS_Asio_HTTP_Server(
+         boost::asio::io_service& io, unsigned short port,
+         Botan::Credentials_Manager& creds,
+         Botan::TLS::Policy& policy,
+         Botan::TLS::Session_Manager& session_mgr,
+         size_t max_clients)
+         : m_acceptor(io, tcp::endpoint(tcp::v4(), port))
+         , m_creds(creds)
+         , m_policy(policy)
+         , m_session_manager(session_mgr)
+         , m_status(max_clients)
+         {
+         session::pointer new_session = make_session();
+
+         m_acceptor.async_accept(
+            new_session->client_socket(),
+            boost::bind(
+               &TLS_Asio_HTTP_Server::handle_accept,
+               this,
+               new_session,
+               boost::asio::placeholders::error));
+         }
+
+   private:
+      session::pointer make_session()
+         {
+         return session::create(
+                   GET_IO_SERVICE(m_acceptor),
+                   m_session_manager,
+                   m_creds,
+                   m_policy);
+         }
+
+      void handle_accept(session::pointer new_session,
+                         const boost::system::error_code& error)
+         {
+         if(!error)
+            {
+            new_session->start();
+            new_session = make_session();
+
+            m_status.client_serviced();
+
+            if(m_status.should_exit() == false)
+               {
+               m_acceptor.async_accept(
+                  new_session->client_socket(),
+                  boost::bind(
+                     &TLS_Asio_HTTP_Server::handle_accept,
+                     this,
+                     new_session,
+                     boost::asio::placeholders::error));
+               }
+            }
+         }
+
+      tcp::acceptor m_acceptor;
+
+      Botan::Credentials_Manager& m_creds;
+      Botan::TLS::Policy& m_policy;
+      Botan::TLS::Session_Manager& m_session_manager;
+      ServerStatus m_status;
+   };
+
+}
+
+class TLS_HTTP_Server final : public Command
+   {
+   public:
+      TLS_HTTP_Server() : Command("tls_http_server server_cert server_key "
+                                  "--port=443 --policy=default --threads=0 --max-clients=0 "
+                                  "--session-db= --session-db-pass=") {}
+
+      std::string group() const override
+         {
+         return "tls";
+         }
+
+      std::string description() const override
+         {
+         return "Provides a simple HTTP server";
+         }
+
+      size_t thread_count() const
+         {
+         if(size_t t = get_arg_sz("threads"))
+            return t;
+         if(size_t t = Botan::OS::get_cpu_available())
+            return t;
+         return 2;
+         }
+
+      void go() override
+         {
+         const uint16_t listen_port = get_arg_u16("port");
+
+         const std::string server_crt = get_arg("server_cert");
+         const std::string server_key = get_arg("server_key");
+
+         const size_t num_threads = thread_count();
+         const size_t max_clients = get_arg_sz("max-clients");
+
+         Basic_Credentials_Manager creds(rng(), server_crt, server_key);
+
+         auto policy = load_tls_policy(get_arg("policy"));
+
+         std::unique_ptr<Botan::TLS::Session_Manager> session_mgr;
+
+         const std::string sessions_db = get_arg("session-db");
+
+         if(!sessions_db.empty())
+            {
+#if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER)
+            const std::string sessions_passphrase = get_passphrase_arg("Session DB passphrase", "session-db-pass");
+            session_mgr.reset(new Botan::TLS::Session_Manager_SQLite(sessions_passphrase, rng(), sessions_db));
+#else
+            throw CLI_Error_Unsupported("Sqlite3 support not available");
+#endif
+            }
+
+         if(!session_mgr)
+            {
+            session_mgr.reset(new Botan::TLS::Session_Manager_In_Memory(rng()));
+            }
+
+         boost::asio::io_service io;
+
+         TLS_Asio_HTTP_Server server(io, listen_port, creds, *policy, *session_mgr, max_clients);
+
+         std::vector<std::shared_ptr<std::thread>> threads;
+
+         // run forever... first thread is main calling io.run below
+         for(size_t i = 2; i <= num_threads; ++i)
+            {
+            threads.push_back(std::make_shared<std::thread>([&io]() { io.run(); }));
+            }
+
+         io.run();
+
+         for(size_t i = 0; i < threads.size(); ++i)
+            {
+            threads[i]->join();
+            }
+         }
+   };
+
+BOTAN_REGISTER_COMMAND("tls_http_server", TLS_HTTP_Server);
+
+}
+
+#endif
Index: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli/tls_proxy.cpp
===================================================================
--- create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli/tls_proxy.cpp	(nonexistent)
+++ create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli/tls_proxy.cpp	(revision 5)
@@ -0,0 +1,526 @@
+/*
+* TLS Server Proxy
+* (C) 2014,2015,2019 Jack Lloyd
+* (C) 2016 Matthias Gierlings
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "cli.h"
+
+#if defined(BOTAN_HAS_TLS) && defined(BOTAN_HAS_BOOST_ASIO) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <thread>
+#include <atomic>
+
+#define _GLIBCXX_HAVE_GTHR_DEFAULT
+#include <boost/asio.hpp>
+#include <boost/bind/bind.hpp>
+#include <botan/internal/os_utils.h>
+
+#include <botan/tls_server.h>
+#include <botan/x509cert.h>
+#include <botan/pkcs8.h>
+#include <botan/hex.h>
+#include <botan/rng.h>
+
+#if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER)
+   #include <botan/tls_session_manager_sqlite.h>
+#endif
+
+#include "tls_helpers.h"
+
+#if BOOST_VERSION >= 107000
+#define GET_IO_SERVICE(s) (static_cast<boost::asio::io_context&>((s).get_executor().context()))
+#else
+#define GET_IO_SERVICE(s) ((s).get_io_service())
+#endif
+
+namespace Botan_CLI {
+
+namespace {
+
+using boost::asio::ip::tcp;
+
+void log_exception(const char* where, const std::exception& e)
+   {
+   std::cout << where << ' ' << e.what() << std::endl;
+   }
+
+void log_error(const char* where, const boost::system::error_code& error)
+   {
+   std::cout << where << ' ' << error.message() << std::endl;
+   }
+
+void log_binary_message(const char* where, const uint8_t buf[], size_t buf_len)
+   {
+   BOTAN_UNUSED(where, buf, buf_len);
+   //std::cout << where << ' ' << Botan::hex_encode(buf, buf_len) << std::endl;
+   }
+
+void log_text_message(const char* where,  const uint8_t buf[], size_t buf_len)
+   {
+   BOTAN_UNUSED(where, buf, buf_len);
+   //const char* c = reinterpret_cast<const char*>(buf);
+   //std::cout << where << ' ' << std::string(c, c + buf_len)  << std::endl;
+   }
+
+class ServerStatus
+   {
+   public:
+      ServerStatus(size_t max_clients) : m_max_clients(max_clients), m_clients_serviced(0) {}
+
+      bool should_exit() const
+         {
+         if(m_max_clients == 0)
+            return false;
+
+         return clients_serviced() >= m_max_clients;
+         }
+
+      void client_serviced() { m_clients_serviced++; }
+
+      size_t clients_serviced() const { return m_clients_serviced.load(); }
+   private:
+      size_t m_max_clients;
+      std::atomic<size_t> m_clients_serviced;
+   };
+
+class tls_proxy_session final : public std::enable_shared_from_this<tls_proxy_session>,
+                                public Botan::TLS::Callbacks
+   {
+   public:
+      enum { readbuf_size = 17 * 1024 };
+
+      typedef std::shared_ptr<tls_proxy_session> pointer;
+
+      static pointer create(
+         boost::asio::io_service& io,
+         Botan::TLS::Session_Manager& session_manager,
+         Botan::Credentials_Manager& credentials,
+         Botan::TLS::Policy& policy,
+         tcp::resolver::iterator endpoints)
+         {
+         return pointer(
+                   new tls_proxy_session(
+                      io,
+                      session_manager,
+                      credentials,
+                      policy,
+                      endpoints)
+                );
+         }
+
+      tcp::socket& client_socket()
+         {
+         return m_client_socket;
+         }
+
+      void start()
+         {
+         m_c2p.resize(readbuf_size);
+         client_read(boost::system::error_code(), 0); // start read loop
+         }
+
+      void stop()
+         {
+         if(m_is_closed == false)
+            {
+            /*
+            Don't need to talk to the server anymore
+            Client socket is closed during write callback
+            */
+            m_server_socket.close();
+            m_tls.close();
+            m_is_closed = true;
+            }
+         }
+
+   private:
+      tls_proxy_session(
+         boost::asio::io_service& io,
+         Botan::TLS::Session_Manager& session_manager,
+         Botan::Credentials_Manager& credentials,
+         Botan::TLS::Policy& policy,
+         tcp::resolver::iterator endpoints)
+         : m_strand(io)
+         , m_server_endpoints(endpoints)
+         , m_client_socket(io)
+         , m_server_socket(io)
+         , m_rng(cli_make_rng())
+         , m_tls(*this,
+                 session_manager,
+                 credentials,
+                 policy,
+                 *m_rng) {}
+
+      void client_read(const boost::system::error_code& error,
+                       size_t bytes_transferred)
+         {
+         if(error)
+            {
+            log_error("Read failed", error);
+            stop();
+            return;
+            }
+
+         try
+            {
+            if(!m_tls.is_active())
+               {
+               log_binary_message("From client", &m_c2p[0], bytes_transferred);
+               }
+            m_tls.received_data(&m_c2p[0], bytes_transferred);
+            }
+         catch(Botan::Exception& e)
+            {
+            log_exception("TLS connection failed", e);
+            stop();
+            return;
+            }
+
+         m_client_socket.async_read_some(
+            boost::asio::buffer(&m_c2p[0], m_c2p.size()),
+            m_strand.wrap(
+               boost::bind(
+                  &tls_proxy_session::client_read, shared_from_this(),
+                  boost::asio::placeholders::error,
+                  boost::asio::placeholders::bytes_transferred)));
+         }
+
+      void handle_client_write_completion(const boost::system::error_code& error)
+         {
+         if(error)
+            {
+            log_error("Client write", error);
+            stop();
+            return;
+            }
+
+         m_p2c.clear();
+
+         if(m_p2c_pending.empty() && m_tls.is_closed())
+            {
+            m_client_socket.close();
+            }
+         tls_emit_data(nullptr, 0); // initiate another write if needed
+         }
+
+      void handle_server_write_completion(const boost::system::error_code& error)
+         {
+         if(error)
+            {
+            log_error("Server write", error);
+            stop();
+            return;
+            }
+
+         m_p2s.clear();
+         proxy_write_to_server(nullptr, 0); // initiate another write if needed
+         }
+
+      void tls_record_received(uint64_t /*rec_no*/, const uint8_t buf[], size_t buf_len) override
+         {
+         // Immediately bounce message to server
+         proxy_write_to_server(buf, buf_len);
+         }
+
+      void tls_emit_data(const uint8_t buf[], size_t buf_len) override
+         {
+         if(buf_len > 0)
+            {
+            m_p2c_pending.insert(m_p2c_pending.end(), buf, buf + buf_len);
+            }
+
+         // no write now active and we still have output pending
+         if(m_p2c.empty() && !m_p2c_pending.empty())
+            {
+            std::swap(m_p2c_pending, m_p2c);
+
+            log_binary_message("To Client", &m_p2c[0], m_p2c.size());
+
+            boost::asio::async_write(
+               m_client_socket,
+               boost::asio::buffer(&m_p2c[0], m_p2c.size()),
+               m_strand.wrap(
+                  boost::bind(
+                     &tls_proxy_session::handle_client_write_completion,
+                     shared_from_this(),
+                     boost::asio::placeholders::error)));
+            }
+         }
+
+      void proxy_write_to_server(const uint8_t buf[], size_t buf_len)
+         {
+         if(buf_len > 0)
+            {
+            m_p2s_pending.insert(m_p2s_pending.end(), buf, buf + buf_len);
+            }
+
+         // no write now active and we still have output pending
+         if(m_p2s.empty() && !m_p2s_pending.empty())
+            {
+            std::swap(m_p2s_pending, m_p2s);
+
+            log_text_message("To Server", &m_p2s[0], m_p2s.size());
+
+            boost::asio::async_write(
+               m_server_socket,
+               boost::asio::buffer(&m_p2s[0], m_p2s.size()),
+               m_strand.wrap(
+                  boost::bind(
+                     &tls_proxy_session::handle_server_write_completion,
+                     shared_from_this(),
+                     boost::asio::placeholders::error)));
+            }
+         }
+
+      void server_read(const boost::system::error_code& error,
+                       size_t bytes_transferred)
+         {
+         if(error)
+            {
+            log_error("Server read failed", error);
+            stop();
+            return;
+            }
+
+         try
+            {
+            if(bytes_transferred)
+               {
+               log_text_message("Server to client", &m_s2p[0], m_s2p.size());
+               log_binary_message("Server to client", &m_s2p[0], m_s2p.size());
+               m_tls.send(&m_s2p[0], bytes_transferred);
+               }
+            }
+         catch(Botan::Exception& e)
+            {
+            log_exception("TLS connection failed", e);
+            stop();
+            return;
+            }
+
+         m_s2p.resize(readbuf_size);
+
+         m_server_socket.async_read_some(
+            boost::asio::buffer(&m_s2p[0], m_s2p.size()),
+            m_strand.wrap(
+               boost::bind(&tls_proxy_session::server_read, shared_from_this(),
+                           boost::asio::placeholders::error,
+                           boost::asio::placeholders::bytes_transferred)));
+         }
+
+      bool tls_session_established(const Botan::TLS::Session& session) override
+         {
+         m_hostname = session.server_info().hostname();
+
+         auto onConnect = [this](boost::system::error_code ec, tcp::resolver::iterator /*endpoint*/)
+            {
+            if(ec)
+               {
+               log_error("Server connection", ec);
+               return;
+               }
+            server_read(boost::system::error_code(), 0); // start read loop
+            proxy_write_to_server(nullptr, 0);
+            };
+         async_connect(m_server_socket, m_server_endpoints, onConnect);
+         return true;
+         }
+
+      void tls_alert(Botan::TLS::Alert alert) override
+         {
+         if(alert.type() == Botan::TLS::Alert::CLOSE_NOTIFY)
+            {
+            m_tls.close();
+            return;
+            }
+         }
+
+      boost::asio::io_service::strand m_strand;
+
+      tcp::resolver::iterator m_server_endpoints;
+
+      tcp::socket m_client_socket;
+      tcp::socket m_server_socket;
+
+      std::unique_ptr<Botan::RandomNumberGenerator> m_rng;
+      Botan::TLS::Server m_tls;
+      std::string m_hostname;
+
+      std::vector<uint8_t> m_c2p;
+      std::vector<uint8_t> m_p2c;
+      std::vector<uint8_t> m_p2c_pending;
+
+      std::vector<uint8_t> m_s2p;
+      std::vector<uint8_t> m_p2s;
+      std::vector<uint8_t> m_p2s_pending;
+
+      bool m_is_closed = false;
+   };
+
+class tls_proxy_server final
+   {
+   public:
+      typedef tls_proxy_session session;
+
+      tls_proxy_server(
+         boost::asio::io_service& io, unsigned short port,
+         tcp::resolver::iterator endpoints,
+         Botan::Credentials_Manager& creds,
+         Botan::TLS::Policy& policy,
+         Botan::TLS::Session_Manager& session_mgr,
+         size_t max_clients)
+         : m_acceptor(io, tcp::endpoint(tcp::v4(), port))
+         , m_server_endpoints(endpoints)
+         , m_creds(creds)
+         , m_policy(policy)
+         , m_session_manager(session_mgr)
+         , m_status(max_clients)
+         {
+         session::pointer new_session = make_session();
+
+         m_acceptor.async_accept(
+            new_session->client_socket(),
+            boost::bind(
+               &tls_proxy_server::handle_accept,
+               this,
+               new_session,
+               boost::asio::placeholders::error));
+         }
+
+   private:
+      session::pointer make_session()
+         {
+         return session::create(
+                   GET_IO_SERVICE(m_acceptor),
+                   m_session_manager,
+                   m_creds,
+                   m_policy,
+                   m_server_endpoints);
+         }
+
+      void handle_accept(session::pointer new_session,
+                         const boost::system::error_code& error)
+         {
+         if(!error)
+            {
+            new_session->start();
+            new_session = make_session();
+
+            m_status.client_serviced();
+
+            if(m_status.should_exit() == false)
+               {
+               m_acceptor.async_accept(
+                  new_session->client_socket(),
+                  boost::bind(
+                     &tls_proxy_server::handle_accept,
+                     this,
+                     new_session,
+                     boost::asio::placeholders::error));
+               }
+            }
+         }
+
+      tcp::acceptor m_acceptor;
+      tcp::resolver::iterator m_server_endpoints;
+
+      Botan::Credentials_Manager& m_creds;
+      Botan::TLS::Policy& m_policy;
+      Botan::TLS::Session_Manager& m_session_manager;
+      ServerStatus m_status;
+   };
+
+}
+
+class TLS_Proxy final : public Command
+   {
+   public:
+      TLS_Proxy() : Command("tls_proxy listen_port target_host target_port server_cert server_key "
+                               "--policy=default --threads=0 --max-clients=0 --session-db= --session-db-pass=") {}
+
+      std::string group() const override
+         {
+         return "tls";
+         }
+
+      std::string description() const override
+         {
+         return "Proxies requests between a TLS client and a TLS server";
+         }
+
+      size_t thread_count() const
+         {
+         if(size_t t = get_arg_sz("threads"))
+            return t;
+         if(size_t t = Botan::OS::get_cpu_available())
+            return t;
+         return 2;
+         }
+
+      void go() override
+         {
+         const uint16_t listen_port = get_arg_u16("listen_port");
+         const std::string target = get_arg("target_host");
+         const std::string target_port = get_arg("target_port");
+
+         const std::string server_crt = get_arg("server_cert");
+         const std::string server_key = get_arg("server_key");
+
+         const size_t num_threads = thread_count();
+         const size_t max_clients = get_arg_sz("max-clients");
+
+         Basic_Credentials_Manager creds(rng(), server_crt, server_key);
+
+         auto policy = load_tls_policy(get_arg("policy"));
+
+         boost::asio::io_service io;
+
+         tcp::resolver resolver(io);
+         auto server_endpoint_iterator = resolver.resolve({ target, target_port });
+
+         std::unique_ptr<Botan::TLS::Session_Manager> session_mgr;
+
+#if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER)
+         const std::string sessions_passphrase = get_passphrase_arg("Session DB passphrase", "session-db-pass");
+         const std::string sessions_db = get_arg("session-db");
+
+         if(!sessions_db.empty())
+            {
+            session_mgr.reset(new Botan::TLS::Session_Manager_SQLite(sessions_passphrase, rng(), sessions_db));
+            }
+#endif
+         if(!session_mgr)
+            {
+            session_mgr.reset(new Botan::TLS::Session_Manager_In_Memory(rng()));
+            }
+
+         tls_proxy_server server(io, listen_port, server_endpoint_iterator, creds, *policy, *session_mgr, max_clients);
+
+         std::vector<std::shared_ptr<std::thread>> threads;
+
+         // run forever... first thread is main calling io.run below
+         for(size_t i = 2; i <= num_threads; ++i)
+            {
+            threads.push_back(std::make_shared<std::thread>([&io]() { io.run(); }));
+            }
+
+         io.run();
+
+         for(size_t i = 0; i < threads.size(); ++i)
+            {
+            threads[i]->join();
+            }
+         }
+   };
+
+BOTAN_REGISTER_COMMAND("tls_proxy", TLS_Proxy);
+
+}
+
+#endif
Index: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli
===================================================================
--- create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli	(nonexistent)
+++ create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli	(revision 5)

Property changes on: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/cli
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/tests/unit_asio_stream.cpp
===================================================================
--- create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/tests/unit_asio_stream.cpp	(nonexistent)
+++ create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/tests/unit_asio_stream.cpp	(revision 5)
@@ -0,0 +1,817 @@
+/*
+* TLS ASIO Stream Unit Tests
+* (C) 2018-2020 Jack Lloyd
+*     2018-2020 Hannes Rantzsch, Tim Oesterreich, Rene Meusel
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+
+#if defined(BOTAN_HAS_TLS) && defined(BOTAN_HAS_TLS_ASIO_STREAM)
+
+#include <botan/asio_stream.h>
+#include <botan/tls_callbacks.h>
+
+// The boost::beast::test::stream we use is available starting from boost
+// version 1.68, so we cannot run these tests with a smaller version.
+#include <boost/version.hpp>
+#if BOOST_VERSION >= 106800
+
+// boost::beast::test::stream's include path has been changed in boost version
+// 1.70.
+#if BOOST_VERSION < 107000
+#include <boost/beast/experimental/test/stream.hpp>
+#else
+#include <boost/beast/_experimental/test/stream.hpp>
+#endif
+
+#include <boost/bind/bind.hpp>
+
+namespace Botan_Tests {
+
+namespace net    = boost::asio;
+using error_code = boost::system::error_code;
+
+constexpr uint8_t     TEST_DATA[] = "The story so far: In the beginning the Universe was created. "
+                                    "This has made a lot of people very angry and been widely regarded as a bad move.";
+constexpr std::size_t TEST_DATA_SIZE = 142;
+static_assert(sizeof(TEST_DATA) == TEST_DATA_SIZE, "size of TEST_DATA must match TEST_DATA_SIZE");
+
+/**
+ * Mocked Botan::TLS::Channel. Pretends to perform TLS operations and triggers appropriate callbacks in StreamCore.
+ */
+class MockChannel
+   {
+   public:
+      MockChannel(Botan::TLS::Callbacks& core)
+         : m_callbacks(core)
+         , m_bytes_till_complete_record(TEST_DATA_SIZE)
+         , m_active(false) {}
+
+   public:
+      std::size_t received_data(const uint8_t[], std::size_t buf_size)
+         {
+         if(m_bytes_till_complete_record <= buf_size)
+            {
+            m_callbacks.tls_record_received(0, TEST_DATA, TEST_DATA_SIZE);
+            m_active = true;  // claim to be active once a full record has been received (for handshake test)
+            return 0;
+            }
+         m_bytes_till_complete_record -= buf_size;
+         return m_bytes_till_complete_record;
+         }
+
+      void send(const uint8_t buf[], std::size_t buf_size) { m_callbacks.tls_emit_data(buf, buf_size); }
+
+      bool is_active() { return m_active; }
+
+   protected:
+      Botan::TLS::Callbacks& m_callbacks;
+      std::size_t m_bytes_till_complete_record;  // number of bytes still to read before tls record is completed
+      bool        m_active;
+   };
+
+class ThrowingMockChannel : public MockChannel
+   {
+   public:
+      static boost::system::error_code expected_ec()
+         {
+         return Botan::TLS::Alert::UNEXPECTED_MESSAGE;
+         }
+
+      ThrowingMockChannel(Botan::TLS::Callbacks& core) : MockChannel(core)
+         {
+         }
+
+      std::size_t received_data(const uint8_t[], std::size_t)
+         {
+         throw Botan::TLS::Unexpected_Message("test_error");
+         }
+
+      void send(const uint8_t[], std::size_t)
+         {
+         throw Botan::TLS::Unexpected_Message("test_error");
+         }
+   };
+
+// Unfortunately, boost::beast::test::stream keeps lowest_layer_type private and
+// only friends boost::asio::ssl::stream. We need to make our own.
+class TestStream : public boost::beast::test::stream
+   {
+   public:
+      using boost::beast::test::stream::stream;
+      using lowest_layer_type = boost::beast::test::stream;
+   };
+
+using FailCount = boost::beast::test::fail_count;
+
+class AsioStream : public Botan::TLS::Stream<TestStream, MockChannel>
+   {
+   public:
+      template <typename... Args>
+      AsioStream(Botan::TLS::Context& context, Args&& ... args)
+         : Stream(context, args...)
+         {
+         m_native_handle = std::unique_ptr<MockChannel>(new MockChannel(m_core));
+         }
+
+      virtual ~AsioStream() = default;
+   };
+
+class ThrowingAsioStream : public Botan::TLS::Stream<TestStream, ThrowingMockChannel>
+   {
+   public:
+      template <typename... Args>
+      ThrowingAsioStream(Botan::TLS::Context& context, Args&& ... args)
+         : Stream(context, args...)
+         {
+         m_native_handle = std::unique_ptr<ThrowingMockChannel>(new ThrowingMockChannel(m_core));
+         }
+
+      virtual ~ThrowingAsioStream() = default;
+   };
+
+/**
+ * Synchronous tests for Botan::Stream.
+ *
+ * This test validates the asynchronous behavior Botan::Stream, including its utility classes StreamCore and Async_*_Op.
+ * The stream's channel, i.e. TLS_Client or TLS_Server, is mocked and pretends to perform TLS operations (noop) and
+ * provides the test data to the stream.
+ * The underlying network socket, claiming it read / wrote a number of bytes.
+ */
+class Asio_Stream_Tests final : public Test
+   {
+      Botan::Credentials_Manager m_credentials_manager;
+      Botan::Null_RNG m_rng;
+      Botan::TLS::Session_Manager_Noop m_session_manager;
+      Botan::TLS::Default_Policy m_policy;
+
+      Botan::TLS::Context get_context()
+         {
+         return Botan::TLS::Context(m_credentials_manager, m_rng, m_session_manager, m_policy);
+         }
+
+      // use memcmp to check if the data in a is a prefix of the data in b
+      bool contains(const void* a, const void* b, const std::size_t size) { return memcmp(a, b, size) == 0; }
+
+      boost::string_view test_data() const
+         {
+         return boost::string_view(reinterpret_cast<const char*>(TEST_DATA), TEST_DATA_SIZE);
+         }
+
+      void test_sync_handshake(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, test_data());
+
+         ssl.handshake(Botan::TLS::CLIENT);
+
+         Test::Result result("sync TLS handshake");
+         result.test_eq("feeds data into channel until active", ssl.native_handle()->is_active(), true);
+         results.push_back(result);
+         }
+
+      void test_sync_handshake_error(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         // fail right away
+         FailCount  fc{0, net::error::no_recovery};
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, fc);
+         ssl.next_layer().connect(remote);
+
+         // mimic handshake initialization
+         ssl.native_handle()->send(TEST_DATA, TEST_DATA_SIZE);
+
+         error_code ec;
+         ssl.handshake(Botan::TLS::CLIENT, ec);
+
+         Test::Result result("sync TLS handshake error");
+         result.test_eq("does not activate channel", ssl.native_handle()->is_active(), false);
+         result.confirm("propagates error code", ec == net::error::no_recovery);
+         results.push_back(result);
+         }
+
+      void test_sync_handshake_throw(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         ThrowingAsioStream ssl(ctx, ioc, test_data());
+         ssl.next_layer().connect(remote);
+
+         error_code ec;
+         ssl.handshake(Botan::TLS::CLIENT, ec);
+
+         Test::Result result("sync TLS handshake error");
+         result.test_eq("does not activate channel", ssl.native_handle()->is_active(), false);
+         result.confirm("propagates error code", ec == ThrowingMockChannel::expected_ec());
+         results.push_back(result);
+         }
+
+      void test_async_handshake(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, test_data());
+         ssl.next_layer().connect(remote);
+
+         // mimic handshake initialization
+         ssl.native_handle()->send(TEST_DATA, TEST_DATA_SIZE);
+
+         Test::Result result("async TLS handshake");
+
+         auto handler = [&](const error_code&)
+            {
+            result.confirm("reads from socket", ssl.next_layer().nread() > 0);
+            result.confirm("writes from socket", ssl.next_layer().nwrite() > 0);
+            result.test_eq("feeds data into channel until active", ssl.native_handle()->is_active(), true);
+            };
+
+         ssl.async_handshake(Botan::TLS::CLIENT, handler);
+
+         ssl.next_layer().close_remote();
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_handshake_error(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         // fail right away
+         FailCount  fc{0, net::error::no_recovery};
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, fc);
+         ssl.next_layer().connect(remote);
+
+         // mimic handshake initialization
+         ssl.native_handle()->send(TEST_DATA, TEST_DATA_SIZE);
+
+         Test::Result result("async TLS handshake error");
+
+         auto handler = [&](const error_code &ec)
+            {
+            result.test_eq("does not activate channel", ssl.native_handle()->is_active(), false);
+            result.confirm("propagates error code", ec == net::error::no_recovery);
+            };
+
+         ssl.async_handshake(Botan::TLS::CLIENT, handler);
+
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_handshake_throw(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         ThrowingAsioStream ssl(ctx, ioc, test_data());
+         ssl.next_layer().connect(remote);
+
+         Test::Result result("async TLS handshake throw");
+
+         auto handler = [&](const error_code &ec)
+            {
+            result.test_eq("does not activate channel", ssl.native_handle()->is_active(), false);
+            result.confirm("propagates error code", ec == ThrowingMockChannel::expected_ec());
+            };
+
+         ssl.async_handshake(Botan::TLS::CLIENT, handler);
+
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_sync_read_some_success(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, test_data());
+
+         const std::size_t buf_size = 128;
+         uint8_t           buf[buf_size];
+         error_code        ec;
+
+         auto bytes_transferred = net::read(ssl, net::mutable_buffer(buf, sizeof(buf)), ec);
+
+         Test::Result result("sync read_some success");
+         result.confirm("reads the correct data", contains(buf, TEST_DATA, buf_size));
+         result.test_eq("reads the correct amount of data", bytes_transferred, buf_size);
+         result.confirm("does not report an error", !ec);
+
+         results.push_back(result);
+         }
+
+      void test_sync_read_some_buffer_sequence(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, test_data());
+         error_code ec;
+
+         std::vector<net::mutable_buffer> data;
+         uint8_t buf1[TEST_DATA_SIZE/2];
+         uint8_t buf2[TEST_DATA_SIZE/2];
+         data.emplace_back(net::mutable_buffer(buf1, TEST_DATA_SIZE/2));
+         data.emplace_back(net::mutable_buffer(buf2, TEST_DATA_SIZE/2));
+
+         auto bytes_transferred = net::read(ssl, data, ec);
+
+         Test::Result result("sync read_some buffer sequence");
+
+         result.confirm("reads the correct data",
+                        contains(buf1, TEST_DATA, TEST_DATA_SIZE/2) &&
+                        contains(buf2, TEST_DATA+TEST_DATA_SIZE/2, TEST_DATA_SIZE/2));
+         result.test_eq("reads the correct amount of data", bytes_transferred, TEST_DATA_SIZE);
+         result.confirm("does not report an error", !ec);
+
+         results.push_back(result);
+         }
+
+      void test_sync_read_some_error(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         // fail right away
+         FailCount  fc{0, net::error::no_recovery};
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, fc);
+         ssl.next_layer().connect(remote);
+
+         uint8_t    buf[128];
+         error_code ec;
+
+         auto bytes_transferred = net::read(ssl, net::mutable_buffer(buf, sizeof(buf)), ec);
+
+         Test::Result result("sync read_some error");
+         result.test_eq("didn't transfer anything", bytes_transferred, 0);
+         result.confirm("propagates error code", ec == net::error::no_recovery);
+
+         results.push_back(result);
+         }
+
+      void test_sync_read_some_throw(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         ThrowingAsioStream ssl(ctx, ioc, test_data());
+         ssl.next_layer().connect(remote);
+
+         uint8_t    buf[128];
+         error_code ec;
+
+         auto bytes_transferred = net::read(ssl, net::mutable_buffer(buf, sizeof(buf)), ec);
+
+         Test::Result result("sync read_some throw");
+         result.test_eq("didn't transfer anything", bytes_transferred, 0);
+         result.confirm("propagates error code", ec == ThrowingMockChannel::expected_ec());
+
+         results.push_back(result);
+         }
+
+      void test_sync_read_zero_buffer(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc);
+
+         const std::size_t buf_size = 128;
+         uint8_t           buf[buf_size];
+         error_code        ec;
+
+         auto bytes_transferred = net::read(ssl, net::mutable_buffer(buf, std::size_t(0)), ec);
+
+         Test::Result result("sync read_some into zero-size buffer");
+         result.test_eq("reads the correct amount of data", bytes_transferred, 0);
+         // This relies on an implementation detail of TestStream: A "real" asio::tcp::stream
+         // would block here. TestStream sets error_code::eof.
+         result.confirm("does not report an error", !ec);
+
+         results.push_back(result);
+         }
+
+      void test_async_read_some_success(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, test_data());
+         uint8_t    data[TEST_DATA_SIZE];
+
+         Test::Result result("async read_some success");
+
+         auto read_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.confirm("reads the correct data", contains(data, TEST_DATA, TEST_DATA_SIZE));
+            result.test_eq("reads the correct amount of data", bytes_transferred, TEST_DATA_SIZE);
+            result.confirm("does not report an error", !ec);
+            };
+
+         net::mutable_buffer buf {data, TEST_DATA_SIZE};
+         net::async_read(ssl, buf, read_handler);
+
+         ssl.next_layer().close_remote();
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_read_some_buffer_sequence(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, test_data());
+
+         std::vector<net::mutable_buffer> data;
+         uint8_t buf1[TEST_DATA_SIZE/2];
+         uint8_t buf2[TEST_DATA_SIZE/2];
+         data.emplace_back(net::mutable_buffer(buf1, TEST_DATA_SIZE/2));
+         data.emplace_back(net::mutable_buffer(buf2, TEST_DATA_SIZE/2));
+
+         Test::Result result("async read_some buffer sequence");
+
+         auto read_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.confirm("reads the correct data",
+                           contains(buf1, TEST_DATA, TEST_DATA_SIZE/2) &&
+                           contains(buf2, TEST_DATA+TEST_DATA_SIZE/2, TEST_DATA_SIZE/2));
+            result.test_eq("reads the correct amount of data", bytes_transferred, TEST_DATA_SIZE);
+            result.confirm("does not report an error", !ec);
+            };
+
+         net::async_read(ssl, data, read_handler);
+
+         ssl.next_layer().close_remote();
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_read_some_error(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         // fail right away
+         FailCount  fc{0, net::error::no_recovery};
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, fc);
+         uint8_t    data[TEST_DATA_SIZE];
+
+         Test::Result result("async read_some error");
+
+         auto read_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.test_eq("didn't transfer anything", bytes_transferred, 0);
+            result.confirm("propagates error code", ec == net::error::no_recovery);
+            };
+
+         net::mutable_buffer buf {data, TEST_DATA_SIZE};
+         net::async_read(ssl, buf, read_handler);
+
+         ssl.next_layer().close_remote();
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_read_some_throw(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         auto ctx = get_context();
+         ThrowingAsioStream ssl(ctx, ioc, test_data());
+         uint8_t    data[TEST_DATA_SIZE];
+
+         Test::Result result("async read_some throw");
+
+         auto read_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.test_eq("didn't transfer anything", bytes_transferred, 0);
+            result.confirm("propagates error code", ec == ThrowingMockChannel::expected_ec());
+            };
+
+         net::mutable_buffer buf {data, TEST_DATA_SIZE};
+         net::async_read(ssl, buf, read_handler);
+
+         ssl.next_layer().close_remote();
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_read_zero_buffer(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc);
+         uint8_t    data[TEST_DATA_SIZE];
+
+         Test::Result result("async read_some into zero-size buffer");
+
+         auto read_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.test_eq("reads the correct amount of data", bytes_transferred, 0);
+            // This relies on an implementation detail of TestStream: A "real" asio::tcp::stream
+            // would block here. TestStream sets error_code::eof.
+            result.confirm("does not report an error", !ec);
+            };
+
+         net::mutable_buffer buf {data, std::size_t(0)};
+         net::async_read(ssl, buf, read_handler);
+
+         ssl.next_layer().close_remote();
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_sync_write_some_success(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc);
+         ssl.next_layer().connect(remote);
+         error_code ec;
+
+         auto bytes_transferred = net::write(ssl, net::const_buffer(TEST_DATA, TEST_DATA_SIZE), ec);
+
+         Test::Result result("sync write_some success");
+         result.confirm("writes the correct data", remote.str() == test_data());
+         result.test_eq("writes the correct amount of data", bytes_transferred, TEST_DATA_SIZE);
+         result.confirm("does not report an error", !ec);
+
+         results.push_back(result);
+         }
+
+      void test_sync_no_handshake(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         Botan::TLS::Stream<TestStream> ssl(ctx, ioc);  // Note that we're not using MockChannel here
+         ssl.next_layer().connect(remote);
+         error_code ec;
+
+         net::write(ssl, net::const_buffer(TEST_DATA, TEST_DATA_SIZE), ec);
+
+         Test::Result result("sync write_some without handshake fails gracefully");
+         result.confirm("reports an error", ec.failed());
+
+         results.push_back(result);
+         }
+
+      void test_sync_write_some_buffer_sequence(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc);
+         ssl.next_layer().connect(remote);
+         error_code ec;
+
+         // this should be Botan::TLS::MAX_PLAINTEXT_SIZE + 1024 + 1
+         std::array<uint8_t, 17 * 1024 + 1> random_data;
+         random_data.fill('4');  // chosen by fair dice roll
+         random_data.back() = '5';
+
+         std::vector<net::const_buffer> data;
+         data.emplace_back(net::const_buffer(random_data.data(), 1));
+         for(std::size_t i = 1; i < random_data.size(); i += 1024)
+            {
+            data.emplace_back(net::const_buffer(random_data.data() + i, 1024));
+            }
+
+         auto bytes_transferred = net::write(ssl, data, ec);
+
+         Test::Result result("sync write_some buffer sequence");
+
+         result.confirm("[precondition] MAX_PLAINTEXT_SIZE is still smaller than random_data.size()",
+                        Botan::TLS::MAX_PLAINTEXT_SIZE < random_data.size());
+
+         result.confirm("writes the correct data",
+                        contains(remote.buffer().data().data(), random_data.data(), random_data.size()));
+         result.test_eq("writes the correct amount of data", bytes_transferred, random_data.size());
+         result.test_eq("correct number of writes", ssl.next_layer().nwrite(), 2);
+         result.confirm("does not report an error", !ec);
+
+         results.push_back(result);
+         }
+
+      void test_sync_write_some_error(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         // fail right away
+         FailCount  fc{0, net::error::no_recovery};
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, fc);
+         ssl.next_layer().connect(remote);
+
+         error_code ec;
+
+         auto bytes_transferred = net::write(ssl, net::const_buffer(TEST_DATA, TEST_DATA_SIZE), ec);
+
+         Test::Result result("sync write_some error");
+         result.test_eq("didn't transfer anything", bytes_transferred, 0);
+         result.confirm("propagates error code", ec == net::error::no_recovery);
+
+         results.push_back(result);
+         }
+
+      void test_sync_write_some_throw(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         ThrowingAsioStream ssl(ctx, ioc);
+         ssl.next_layer().connect(remote);
+         error_code ec;
+
+         auto bytes_transferred = net::write(ssl, net::const_buffer(TEST_DATA, TEST_DATA_SIZE), ec);
+
+         Test::Result result("sync write_some throw");
+         result.test_eq("didn't transfer anything", bytes_transferred, 0);
+         result.confirm("propagates error code", ec == ThrowingMockChannel::expected_ec());
+
+         results.push_back(result);
+         }
+
+      void test_async_write_some_success(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc);
+         ssl.next_layer().connect(remote);
+
+         Test::Result result("async write_some success");
+
+         auto write_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.confirm("writes the correct data", remote.str() == test_data());
+            result.test_eq("writes the correct amount of data", bytes_transferred, TEST_DATA_SIZE);
+            result.confirm("does not report an error", !ec);
+            };
+
+         net::async_write(ssl, net::const_buffer(TEST_DATA, TEST_DATA_SIZE), write_handler);
+
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_write_some_buffer_sequence(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream      remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc);
+         ssl.next_layer().connect(remote);
+
+         // this should be Botan::TLS::MAX_PLAINTEXT_SIZE + 1024 + 1
+         std::array<uint8_t, 17 * 1024 + 1> random_data;
+         random_data.fill('4');  // chosen by fair dice roll
+         random_data.back() = '5';
+
+         std::vector<net::const_buffer> src;
+         src.emplace_back(net::const_buffer(random_data.data(), 1));
+         for(std::size_t i = 1; i < random_data.size(); i += 1024)
+            {
+            src.emplace_back(net::const_buffer(random_data.data() + i, 1024));
+            }
+
+         Test::Result result("async write_some buffer sequence");
+
+         result.confirm("[precondition] MAX_PLAINTEXT_SIZE is still smaller than random_data.size()",
+                        Botan::TLS::MAX_PLAINTEXT_SIZE < random_data.size());
+
+         auto write_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.confirm("writes the correct data",
+                           contains(remote.buffer().data().data(), random_data.data(), random_data.size()));
+            result.test_eq("writes the correct amount of data", bytes_transferred, random_data.size());
+            result.test_eq("correct number of writes", ssl.next_layer().nwrite(), 2);
+            result.confirm("does not report an error", !ec);
+            };
+
+         net::async_write(ssl, src, write_handler);
+
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_write_some_error(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         // fail right away
+         FailCount  fc{0, net::error::no_recovery};
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         AsioStream ssl(ctx, ioc, fc);
+         ssl.next_layer().connect(remote);
+
+         Test::Result result("async write_some error");
+
+         auto write_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.test_eq("committed some bytes to the core", bytes_transferred, TEST_DATA_SIZE);
+            result.confirm("propagates error code", ec == net::error::no_recovery);
+            };
+
+         net::async_write(ssl, net::const_buffer(TEST_DATA, TEST_DATA_SIZE), write_handler);
+
+         ioc.run();
+         results.push_back(result);
+         }
+
+      void test_async_write_throw(std::vector<Test::Result>& results)
+         {
+         net::io_context ioc;
+         TestStream remote{ioc};
+
+         auto ctx = get_context();
+         ThrowingAsioStream ssl(ctx, ioc);
+         ssl.next_layer().connect(remote);
+
+         Test::Result result("async write_some throw");
+
+         auto write_handler = [&](const error_code &ec, std::size_t bytes_transferred)
+            {
+            result.test_eq("didn't transfer anything", bytes_transferred, 0);
+            result.confirm("propagates error code", ec == ThrowingMockChannel::expected_ec());
+            };
+
+         net::async_write(ssl, net::const_buffer(TEST_DATA, TEST_DATA_SIZE), write_handler);
+
+         ioc.run();
+         results.push_back(result);
+         }
+
+   public:
+      std::vector<Test::Result> run() override
+         {
+         std::vector<Test::Result> results;
+
+         test_sync_no_handshake(results);
+
+         test_sync_handshake(results);
+         test_sync_handshake_error(results);
+         test_sync_handshake_throw(results);
+
+         test_async_handshake(results);
+         test_async_handshake_error(results);
+         test_async_handshake_throw(results);
+
+         test_sync_read_some_success(results);
+         test_sync_read_some_buffer_sequence(results);
+         test_sync_read_some_error(results);
+         test_sync_read_some_throw(results);
+         test_sync_read_zero_buffer(results);
+
+         test_async_read_some_success(results);
+         test_async_read_some_buffer_sequence(results);
+         test_async_read_some_error(results);
+         test_async_read_some_throw(results);
+         test_async_read_zero_buffer(results);
+
+         test_sync_write_some_success(results);
+         test_sync_write_some_buffer_sequence(results);
+         test_sync_write_some_error(results);
+         test_sync_write_some_throw(results);
+
+         test_async_write_some_success(results);
+         test_async_write_some_buffer_sequence(results);
+         test_async_write_some_error(results);
+         test_async_write_throw(results);
+
+         return results;
+         }
+   };
+
+BOTAN_REGISTER_TEST("tls", "tls_asio_stream", Asio_Stream_Tests);
+
+}  // namespace Botan_Tests
+
+#endif // BOOST_VERSION
+#endif // BOTAN_HAS_TLS && BOTAN_HAS_BOOST_ASIO
Index: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/tests
===================================================================
--- create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/tests	(nonexistent)
+++ create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/tests	(revision 5)

Property changes on: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src/tests
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src
===================================================================
--- create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src	(nonexistent)
+++ create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src	(revision 5)

Property changes on: create-2.19.3-boost-bind-patch/Botan-2.19.3-new/src
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.19.3-boost-bind-patch/Botan-2.19.3-new
===================================================================
--- create-2.19.3-boost-bind-patch/Botan-2.19.3-new	(nonexistent)
+++ create-2.19.3-boost-bind-patch/Botan-2.19.3-new	(revision 5)

Property changes on: create-2.19.3-boost-bind-patch/Botan-2.19.3-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-2.19.3-boost-bind-patch/create.patch.sh
===================================================================
--- create-2.19.3-boost-bind-patch/create.patch.sh	(nonexistent)
+++ create-2.19.3-boost-bind-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=2.19.3
+
+tar --files-from=file.list -xJvf ../Botan-$VERSION.tar.xz
+mv Botan-$VERSION Botan-$VERSION-orig
+
+cp -rf ./Botan-$VERSION-new ./Botan-$VERSION
+
+diff --unified -Nr  Botan-$VERSION-orig  Botan-$VERSION > Botan-$VERSION-boost-bind.patch
+
+mv Botan-$VERSION-boost-bind.patch ../patches
+
+rm -rf ./Botan-$VERSION
+rm -rf ./Botan-$VERSION-orig

Property changes on: create-2.19.3-boost-bind-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: create-2.19.3-boost-bind-patch/file.list
===================================================================
--- create-2.19.3-boost-bind-patch/file.list	(nonexistent)
+++ create-2.19.3-boost-bind-patch/file.list	(revision 5)
@@ -0,0 +1,3 @@
+Botan-2.19.3/src/cli/tls_http_server.cpp
+Botan-2.19.3/src/cli/tls_proxy.cpp
+Botan-2.19.3/src/tests/unit_asio_stream.cpp
Index: create-2.19.3-boost-bind-patch
===================================================================
--- create-2.19.3-boost-bind-patch	(nonexistent)
+++ create-2.19.3-boost-bind-patch	(revision 5)

Property changes on: create-2.19.3-boost-bind-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: patches/README
===================================================================
--- patches/README	(nonexistent)
+++ patches/README	(revision 5)
@@ -0,0 +1,6 @@
+
+/* begin *
+
+   TODO: Leave some comment here.
+
+ * end */
Index: patches
===================================================================
--- patches	(nonexistent)
+++ patches	(revision 5)

Property changes on: patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: .
===================================================================
--- .	(nonexistent)
+++ .	(revision 5)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~