| 2113 | } |
| 2114 | |
| 2115 | int Server::ResetCertificates(const std::vector<CertInfo>& certs) { |
| 2116 | if (!_options.has_ssl_options()) { |
| 2117 | LOG(ERROR) << "ServerOptions.ssl_options is not configured yet"; |
| 2118 | return -1; |
| 2119 | } |
| 2120 | |
| 2121 | SSLContextMap tmp_map; |
| 2122 | if (tmp_map.init(certs.size() + 1) != 0) { |
| 2123 | LOG(ERROR) << "Fail to init tmp_map"; |
| 2124 | return -1; |
| 2125 | } |
| 2126 | |
| 2127 | // Add default certificate into tmp_map first since it can't be reloaded |
| 2128 | std::string default_cert_key = |
| 2129 | _options.ssl_options().default_cert.certificate |
| 2130 | + _options.ssl_options().default_cert.private_key; |
| 2131 | tmp_map[default_cert_key] = _ssl_ctx_map[default_cert_key]; |
| 2132 | |
| 2133 | for (size_t i = 0; i < certs.size(); ++i) { |
| 2134 | std::string cert_key(certs[i].certificate); |
| 2135 | cert_key.append(certs[i].private_key); |
| 2136 | if (tmp_map.seek(cert_key) != NULL) { |
| 2137 | LOG(WARNING) << certs[i] << " already exists"; |
| 2138 | return 0; |
| 2139 | } |
| 2140 | |
| 2141 | SSLContext ssl_ctx; |
| 2142 | ssl_ctx.filters = certs[i].sni_filters; |
| 2143 | ssl_ctx.ctx = std::make_shared<SocketSSLContext>(); |
| 2144 | ssl_ctx.ctx->raw_ctx = CreateServerSSLContext( |
| 2145 | certs[i].certificate, certs[i].private_key, |
| 2146 | _options.ssl_options(), &_raw_alpns, &ssl_ctx.filters); |
| 2147 | if (ssl_ctx.ctx->raw_ctx == NULL) { |
| 2148 | return -1; |
| 2149 | } |
| 2150 | |
| 2151 | #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME |
| 2152 | SSL_CTX_set_tlsext_servername_callback(ssl_ctx.ctx->raw_ctx, SSLSwitchCTXByHostname); |
| 2153 | SSL_CTX_set_tlsext_servername_arg(ssl_ctx.ctx->raw_ctx, this); |
| 2154 | #endif |
| 2155 | tmp_map[cert_key] = ssl_ctx; |
| 2156 | } |
| 2157 | |
| 2158 | if (!_reload_cert_maps.Modify(ResetCertMappings, tmp_map)) { |
| 2159 | return -1; |
| 2160 | } |
| 2161 | |
| 2162 | _ssl_ctx_map.swap(tmp_map); |
| 2163 | return 0; |
| 2164 | } |
| 2165 | |
| 2166 | bool Server::ResetCertMappings(CertMaps& bg, const SSLContextMap& ctx_map) { |
| 2167 | bg.cert_map.clear(); |