xref: /openbmc/bmcweb/src/webserver_main.cpp (revision 9b65f1fdcfcaaa22719a83be26dbcb5dbe855b0c)
1 #include "crow/ci_map.h"
2 #include "crow/http_parser_merged.h"
3 #include "crow/query_string.h"
4 #include "crow/app.h"
5 #include "crow/common.h"
6 #include "crow/dumb_timer_queue.h"
7 #include "crow/http_connection.h"
8 #include "crow/http_request.h"
9 #include "crow/http_response.h"
10 #include "crow/http_server.h"
11 #include "crow/json.h"
12 #include "crow/logging.h"
13 #include "crow/middleware.h"
14 #include "crow/middleware_context.h"
15 #include "crow/mustache.h"
16 #include "crow/parser.h"
17 #include "crow/routing.h"
18 #include "crow/settings.h"
19 #include "crow/socket_adaptors.h"
20 #include "crow/utility.h"
21 #include "crow/websocket.h"
22 
23 #include "color_cout_g3_sink.hpp"
24 #include "token_authorization_middleware.hpp"
25 #include "webassets.hpp"
26 
27 #include <iostream>
28 #include <string>
29 #include "ssl_key_handler.hpp"
30 
31 #include <webassets.hpp>
32 
33 crow::ssl_context_t get_ssl_context(std::string ssl_pem_file){
34   crow::ssl_context_t m_ssl_context{boost::asio::ssl::context::sslv23};
35   m_ssl_context.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3 |
36                             boost::asio::ssl::context::single_dh_use | boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1);
37 
38   // m_ssl_context.set_verify_mode(boost::asio::ssl::verify_peer);
39   m_ssl_context.use_certificate_file(ssl_pem_file, boost::asio::ssl::context::pem);
40   m_ssl_context.use_private_key_file(ssl_pem_file, boost::asio::ssl::context::pem);
41 
42   // Set up EC curves to auto (boost asio doesn't have a method for this)
43   // There is a pull request to add this.  Once this is included in an asio drop, use the right way
44   // http://stackoverflow.com/questions/18929049/boost-asio-with-ecdsa-certificate-issue
45   if (SSL_CTX_set_ecdh_auto(m_ssl_context.native_handle(), 1) != 1) {
46     CROW_LOG_ERROR << "Error setting tmp ecdh list\n";
47   }
48 
49   // From mozilla "compatibility"
50   std::string ciphers =
51       //"ECDHE-ECDSA-CHACHA20-POLY1305:"
52       //"ECDHE-RSA-CHACHA20-POLY1305:"
53       //"ECDHE-ECDSA-AES128-GCM-SHA256:"
54       //"ECDHE-RSA-AES128-GCM-SHA256:"
55       //"ECDHE-ECDSA-AES256-GCM-SHA384:"
56       //"ECDHE-RSA-AES256-GCM-SHA384:"
57       //"DHE-RSA-AES128-GCM-SHA256:"
58       //"DHE-RSA-AES256-GCM-SHA384:"
59       //"ECDHE-ECDSA-AES128-SHA256:"
60       //"ECDHE-RSA-AES128-SHA256:"
61       //"ECDHE-ECDSA-AES128-SHA:"
62       //"ECDHE-RSA-AES256-SHA384:"
63       //"ECDHE-RSA-AES128-SHA:"
64       //"ECDHE-ECDSA-AES256-SHA384:"
65       //"ECDHE-ECDSA-AES256-SHA:"
66       //"ECDHE-RSA-AES256-SHA:"
67       //"DHE-RSA-AES128-SHA256:"
68       //"DHE-RSA-AES128-SHA:"
69       //"DHE-RSA-AES256-SHA256:"
70       //"DHE-RSA-AES256-SHA:"
71       //"ECDHE-ECDSA-DES-CBC3-SHA:"
72       //"ECDHE-RSA-DES-CBC3-SHA:"
73       //"EDH-RSA-DES-CBC3-SHA:"
74       "AES128-GCM-SHA256:"
75       "AES256-GCM-SHA384:"
76       "AES128-SHA256:"
77       "AES256-SHA256:"
78       "AES128-SHA:"
79       "AES256-SHA:"
80       "DES-CBC3-SHA:"
81       "!DSS";
82 
83   // From mozilla "modern"
84   std::string modern_ciphers =
85       "ECDHE-ECDSA-AES256-GCM-SHA384:"
86       "ECDHE-RSA-AES256-GCM-SHA384:"
87       "ECDHE-ECDSA-CHACHA20-POLY1305:"
88       "ECDHE-RSA-CHACHA20-POLY1305:"
89       "ECDHE-ECDSA-AES128-GCM-SHA256:"
90       "ECDHE-RSA-AES128-GCM-SHA256:"
91       "ECDHE-ECDSA-AES256-SHA384:"
92       "ECDHE-RSA-AES256-SHA384:"
93       "ECDHE-ECDSA-AES128-SHA256:"
94       "ECDHE-RSA-AES128-SHA256";
95 
96   if (SSL_CTX_set_cipher_list(m_ssl_context.native_handle(), ciphers.c_str()) != 1) {
97     CROW_LOG_ERROR << "Error setting cipher list\n";
98   }
99   return m_ssl_context;
100 }
101 
102 
103 int main(int argc, char** argv) {
104   auto worker(g3::LogWorker::createLogWorker());
105 
106   //TODO rotating logger isn't working super well
107   //auto logger = worker->addSink(std::make_unique<LogRotate>("webserverlog", "/tmp/"),
108   //                              &LogRotate::save);
109 
110   auto handle = worker->addDefaultLogger(argv[0], "/tmp/");
111   g3::initializeLogging(worker.get());
112   auto sink_handle = worker->addSink(std::make_unique<crow::ColorCoutSink>(), &crow::ColorCoutSink::ReceiveLogMessage);
113 
114   std::string ssl_pem_file("server.pem");
115   ensuressl::ensure_openssl_key_present_and_valid(ssl_pem_file);
116 
117   //crow::App<crow::TokenAuthorizationMiddleware> app;
118   crow::App<crow::TokenAuthorizationMiddleware> app;
119   crow::webassets::request_routes(app);
120 
121   crow::logger::setLogLevel(crow::LogLevel::INFO);
122 
123   auto rules = app.get_rules();
124   for (auto& rule : rules) {
125     LOG(DEBUG) << "Static route: " << rule;
126   }
127 
128   CROW_ROUTE(app, "/routes")
129   ([&app]() {
130     crow::json::wvalue routes;
131 
132     routes["routes"] = app.get_rules();
133     return routes;
134   });
135 
136   app.port(18080).ssl(std::move(get_ssl_context(ssl_pem_file))).run();
137 }
138