1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
| -- -- Licensed to the Apache Software Foundation (ASF) under one or more -- contributor license agreements. See the NOTICE file distributed with -- this work for additional information regarding copyright ownership. -- The ASF licenses this file to You under the Apache License, Version 2.0 -- (the "License"); you may not use this file except in compliance with -- the License. You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. -- local get_request = require("resty.core.base").get_request local router_new = require("apisix.utils.router").new local core = require("apisix.core") local apisix_ssl = require("apisix.ssl") local ngx_ssl = require("ngx.ssl") local config_util = require("apisix.core.config_util") local ipairs = ipairs local type = type local error = error local str_find = core.string.find local str_gsub = string.gsub local ssl_certificates local radixtree_router local radixtree_router_ver
local _M = { version = 0.1, server_name = ngx_ssl.server_name, }
local function create_router(ssl_items) --changed local ssl_items = ssl_items or {}
local route_items = core.table.new(#ssl_items, 0) local idx = 0
for _, ssl in config_util.iterate_values(ssl_items) do if ssl.value ~= nil and (ssl.value.status == nil or ssl.value.status == 1) then -- compatible with old version local labels_port = tostring(ssl.value.port) idx = idx + 1 route_items[idx] = { paths = labels_port, handler = function (api_ctx) if not api_ctx then return end api_ctx.matched_ssl = ssl end } end end
core.log.info("route items: ", core.json.delay_encode(route_items, true)) -- for testing if #route_items > 1 then core.log.info("we have more than 1 ssl certs now") end local router, err = router_new(route_items) if not router then return nil, err end
return router end
local function set_pem_ssl_key(port, cert, pkey) --changed local r = get_request() if r == nil then return false, "no request found" end
local parsed_cert, err = apisix_ssl.fetch_cert(port, cert) if not parsed_cert then return false, "failed to parse PEM cert: " .. err end
local ok, err = ngx_ssl.set_cert(parsed_cert) if not ok then return false, "failed to set PEM cert: " .. err end
local parsed_pkey, err = apisix_ssl.fetch_pkey(port, pkey) if not parsed_cert then return false, "failed to parse PEM priv key: " .. err end
ok, err = ngx_ssl.set_priv_key(parsed_pkey) if not ok then return false, "failed to set PEM priv key: " .. err end
return true end
function _M.match_and_set(api_ctx) local err if not radixtree_router or radixtree_router_ver ~= ssl_certificates.conf_version then radixtree_router, err = create_router(ssl_certificates.values) if not radixtree_router then return false, "failed to create radixtree router: " .. err end radixtree_router_ver = ssl_certificates.conf_version end
local port = tostring(ngx_ssl.server_port()) --changed local ok = radixtree_router:dispatch(port, nil, api_ctx)
if not ok then core.log.error("failed to find any SSL certificate by Port: ", port) --changed return false end
local matched_ssl = api_ctx.matched_ssl core.log.info("debug - matched: ", core.json.delay_encode(matched_ssl, true))
ngx_ssl.clear_certs()
ok, err = set_pem_ssl_key(port, matched_ssl.value.cert, matched_ssl.value.key) --changed if not ok then return false, err end
-- multiple certificates support. if matched_ssl.value.certs then for i = 1, #matched_ssl.value.certs do local cert = matched_ssl.value.certs[i] local key = matched_ssl.value.keys[i]
ok, err = set_pem_ssl_key(port, cert, key) --changed if not ok then return false, err end end end
if matched_ssl.value.client then local ca_cert = matched_ssl.value.client.ca local depth = matched_ssl.value.client.depth if apisix_ssl.support_client_verification() then local parsed_cert, err = apisix_ssl.fetch_cert(port, ca_cert) --changed if not parsed_cert then return false, "failed to parse client cert: " .. err end
local ok, err = ngx_ssl.verify_client(parsed_cert, depth) if not ok then return false, err end
api_ctx.ssl_client_verified = true end end
return true end
function _M.ssls() if not ssl_certificates then return nil, nil end
return ssl_certificates.values, ssl_certificates.conf_version end
function _M.init_worker() local err ssl_certificates, err = core.config.new("/ssl", { automatic = true, item_schema = core.schema.ssl, checker = function (item, schema_type) return apisix_ssl.check_ssl_conf(true, item) end, }) if not ssl_certificates then error("failed to create etcd instance for fetching ssl certificates: " .. err) end end
return _M
|