M server/base_server/caudium.pike => server/base_server/caudium.pike +6 -5
@@ 3493,22 3493,23 @@ int main(int argc, array(string) argv)
return -1;
}
+// TODO make this timeout
mapping sni_configs=([]);
object get_configuration_for_sni(string sni) {
object conf;
conf = sni_configs[sni];
+
if(conf == -1) return 0;
else if(conf) return conf;
-werror("checking configurations\n");
+
foreach(configurations;; conf) {
- object x = conf->get_sni_configuration();
- if(!x) continue;
- werror("find %O: %O\n", sni, x->find_cert_domain(sni));
- if(x->find_cert_domain(sni)) {
+ if(conf->is_sni_match(sni)) {
+ object x = conf->get_sni_configuration();
sni_configs[sni] = conf;
return conf;
}
}
+
sni_configs[sni] = -1;
return 0;
}
M server/base_server/config/low_describers.pike => server/base_server/config/low_describers.pike +27 -7
@@ 76,12 76,12 @@ string describe_type(int type, mixed flag)
case TYPE_STRING_LIST:
if(!flag)
- return "(Commaseparated list of strings)";
+ return "(Comma separated list of strings)";
break;
case TYPE_DIR_LIST:
if(!flag)
- return "(Commaseparated list of directories)";
+ return "(Comma separated list of directories)";
break;
case TYPE_PASSWORD:
@@ 89,12 89,12 @@ string describe_type(int type, mixed flag)
case TYPE_INT_LIST:
if(!flag)
- return "(Commaseparated list of integers)";
+ return "(Comma separated list of integers)";
break;
case TYPE_SSL_CONFIG:
if(!flag)
- return "This is an SSL configuration.";
+ return "(SSL configuration)";
break;
case TYPE_PORTS:
@@ 454,12 454,14 @@ string encode_ssl_field(mixed id, string field) {
string encode_ssl_config(string from, mixed id)
{
string res = "";
- string cf, kf, cc, cca, cci;
+ string cf, kf, cc, cca, cci, min_ver, max_ver;
sscanf(from, "%*scert-file %s\n", cf);
sscanf(from, "%*skey-file %s\n", kf);
sscanf(from, "%*sclient-cert-request %s\n", cc);
sscanf(from, "%*sclient-cert-authorities %s\n", cca);
- sscanf(from, "%*sclient-cert-issuers %s\n", cci);
+ sscanf(from, "%*sclient-cert-issuers %s\n", cci);
+ sscanf(from, "%*smin-protocol-version %s\n", min_ver);
+ sscanf(from, "%*smax-protocol-version %s\n", max_ver);
res += ("<tr><td colspan=3>"
"<table width=100% cellspacing=0 border=0 bgcolor=#f0f0ff>\n"
@@ 470,6 472,24 @@ string encode_ssl_config(string from, mixed id)
"<tr><td>Key file: (OPTIONAL)<br>(A comma-separated list of files)</td><td><input size=30,1 "
"name=\"" + encode_ssl_field(id, "key") +"\" value="+Caudium.html_encode_tag_value(kf||"")+
"></td></tr>\n");
+
+ string minv = "";
+ array versions = ({"default"}) + sort(map(glob("PROTOCOL_*", indices(SSL.Constants)), lambda(mixed a){return a[sizeof("PROTOCOL_")..];}));
+ foreach(versions;; string ver) {
+ minv +=("<option value=\"" + ver + "\" " + ((min_ver == ver)?"SELECTED=\"1\"":"") + ">" + ver + "</option>");
+ }
+
+ res += ("<tr><td>Minimum Supported Version: (OPTIONAL)</td><td><select "
+ "name=\"" + encode_ssl_field(id, "min") + "\">" + minv + "</select></td></tr>\n");
+
+ string maxv = "";
+ foreach(versions;; string ver) {
+ maxv +=("<option value=\"" + ver + "\" " + ((max_ver == ver)?"SELECTED=\"1\"":"") + ">" + ver + "</option>");
+ }
+
+ res += ("<tr><td>Maximum Supported Version: (OPTIONAL)</td><td><select "
+ "name=\"" + encode_ssl_field(id, "max") + "\">" + maxv + "</select></td></tr>\n");
+
string ccrw = "";
foreach(({"no", "request", "require"});; string opt)
ccrw +=("<option value=\"" + opt + "\" " + ((cc == opt)?"SELECTED=\"1\"":"") + ">" + opt + "</option>");
@@ 623,7 643,7 @@ string describe_variable_low(array var, mixed path, int really_short,
tmp="<select name="+path+"> ";
misc=var[VAR_MISC];
-
+ if(functionp(misc)) misc = misc();
for(i=0; i<sizeof(misc); i++)
{
if(misc[i]==var[VAR_VALUE])
M server/base_server/configuration.pike => server/base_server/configuration.pike +36 -4
@@ 2487,6 2487,19 @@ object get_sni_configuration() {
return ctx;
}
+array(string) get_sni_selection_hosts() {
+ object c = get_sni_configuration();
+ if(!c) return ({});
+ else return ({"All", "None"}) + c->get_certificates()[0]->globs;
+}
+
+int(0..1) is_sni_match(string sni) {
+ object c = get_sni_configuration();
+ if(!c) return 0;
+ string m = QUERY(sni_host_match);
+ if(!m || (m == "None") || (m != "All" && m != sni)) return 0;
+ return (c->find_cert_domain(sni)?1:0);
+}
mapping parse_ssl_args(string options)
{
#ifdef SSL3_DEBUG
@@ 2642,13 2655,30 @@ void load_ssl_configuration(mapping options, mixed ctx,
ctx->auth_level = SSL.Constants.AUTHLEVEL_require;
}
-werror("additional hostnames: %O\n", additional_hostnames);
-if(stringp(additional_hostnames)){
- if(!sizeof(additional_hostnames)) additional_hostnames = 0;
-}
+ if(stringp(additional_hostnames)){
+ if(!sizeof(additional_hostnames)) additional_hostnames = 0;
+ }
// we need the certificates to be in the opposite order (my cert first) for ssl to work.
ctx->add_cert(rsa, reverse(certificates), additional_hostnames||({}));
+ if(options["min-protocol-version"])
+ {
+ if(options["min-protocol-version"] != "default") {
+ if(!SSL.Constants["PROTOCOL_" + options["min-protocol-version"]]) {
+ ({ report_error, throw }) ("ssl3: min protocol " + options["min-protocol-version"] + " is not valid\n");
+ }
+ ctx->min_version = SSL.Constants["PROTOCOL_" + options["min-protocol-version"]];
+ }
+ }
+ if(options["max-protocol-version"])
+ {
+ if(options["max-protocol-version"] != "default") {
+ if(!SSL.Constants["PROTOCOL_" + options["max-protocol-version"]]) {
+ ({ report_error, throw }) ("ssl3: max protocol " + options["max-protocol-version"] + " is not valid\n");
+ }
+ ctx->max_version = SSL.Constants["PROTOCOL_" + options["max-protocol-version"]];
+ }
+ }
}
//!
string MKPORTKEY(array(string) p)
@@ 4069,6 4099,8 @@ void create(string config)
TYPE_STRING_LIST,
"Additional host names to accept. Can be used to specify "
"host names when a wildcard certificate is employed.");
+ defvar("sni_host_match", "All", "SNI: Hostnames to handle",
+ TYPE_MULTIPLE_STRING, "Select the hostnames which will be handled by this virtual server.", get_sni_selection_hosts);
defvar("name", "", "Virtual server name",
TYPE_STRING|VAR_MORE,
"This is the name that will be used in the configuration "
M server/base_server/mainconfig.pike => server/base_server/mainconfig.pike +6 -1
@@ 496,7 496,12 @@ string parse_ssl_config(mixed path, mapping allvars) {
k = encode_ssl_field(path, "cci");
if(allvars[k] && strlen(allvars[k]))
args += "client-cert-issuers "+allvars[k]+"\n";
-
+ k = encode_ssl_field(path, "min");
+ if(allvars[k] && strlen(allvars[k]))
+ args += "min-protocol-version "+allvars[k]+"\n";
+ k = encode_ssl_field(path, "max");
+ if(allvars[k] && strlen(allvars[k]))
+ args += "max-protocol-version "+allvars[k]+"\n";
return args;
}
M server/protocols/ssl3.pike => server/protocols/ssl3.pike +5 -3
@@ 137,7 137,7 @@ array|void real_port(array port, object cfg)
#ifdef SSL3_DEBUG
werror(sprintf("options = %O\n", options));
#endif
- cfg->load_ssl_configuration(options, ctx);
+ cfg->load_ssl_configuration(options, ctx, ({"*"}));
}
@@ 367,7 367,10 @@ protected int parse_got()
string server_name = my_fd->get_server_name();
if(server_name) {
object c = caudium->get_configuration_for_sni(server_name);
- if(c) { werror("got sni config: %O\n", c);
+ if(c) {
+#ifdef SSL3_DEBUG
+ roxen_perror(sprintf("got sni config %O for server name %O\n", c, server_name));
+#endif /*SSL3_DEBUG*/
conf = c;
}
}
@@ 385,7 388,6 @@ protected int parse_got()
Standards.PKCS.Certificate.get_certificate_subject(der)));
}
}
-
// let's slide our client certificate info in...
// if()
// {