static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) { static const ssl_flag_tbl ssl_option_list[] = { SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET), SSL_FLAG_TBL_INV("EmptyFragments", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS), SSL_FLAG_TBL("Bugs", SSL_OP_ALL), SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION), SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE), SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE), SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), SSL_FLAG_TBL("UnsafeLegacyRenegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC), SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION), SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA) }; if (value == NULL) return -3; cctx->tbl = ssl_option_list; cctx->ntbl = OSSL_NELEM(ssl_option_list); return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); }
int ENGINE_set_default_string(ENGINE *e, const char *def_list) { unsigned int flags = 0; if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags)) { ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING, ENGINE_R_INVALID_STRING); ERR_add_error_data(2, "str=", def_list); return 0; } return ENGINE_set_default(e, flags); }
static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) { static const ssl_flag_tbl ssl_protocol_list[] = { SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK), SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2), SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3), SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1), SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1), SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2) }; cctx->tbl = ssl_protocol_list; cctx->ntbl = OSSL_NELEM(ssl_protocol_list); return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); }
static int cmd_VerifyMode(SSL_CONF_CTX *cctx, const char *value) { static const ssl_flag_tbl ssl_vfy_list[] = { SSL_FLAG_VFY_CLI("Peer", SSL_VERIFY_PEER), SSL_FLAG_VFY_SRV("Request", SSL_VERIFY_PEER), SSL_FLAG_VFY_SRV("Require", SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE) }; if (value == NULL) return -3; cctx->tbl = ssl_vfy_list; cctx->ntbl = OSSL_NELEM(ssl_vfy_list); return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); }
static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) { static const ssl_flag_tbl ssl_protocol_list[] = { SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK), SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3), SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1), SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1), SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2) }; if (!(cctx->flags & SSL_CONF_FLAG_FILE)) return -2; cctx->tbl = ssl_protocol_list; cctx->ntbl = sizeof(ssl_protocol_list)/sizeof(ssl_flag_tbl); return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); }
static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) { static const ssl_flag_tbl ssl_option_list[] = { SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET), SSL_FLAG_TBL_INV("EmptyFragments", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS), SSL_FLAG_TBL("Bugs", SSL_OP_ALL), SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION), SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE), SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE), SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), SSL_FLAG_TBL("UnsafeLegacyRenegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), }; if (!(cctx->flags & SSL_CONF_FLAG_FILE)) return -2; if (value == NULL) return -3; cctx->tbl = ssl_option_list; cctx->ntbl = sizeof(ssl_option_list)/sizeof(ssl_flag_tbl); return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); }
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) { ASN1_TYPE *atmp = NULL; CONF_VALUE vtmp; unsigned char *rdata; long rdlen; int no_unused = 1; if (!(atmp = ASN1_TYPE_new())) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); return NULL; } if (!str) str = ""; switch(utype) { case V_ASN1_NULL: if (str && *str) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); goto bad_form; } break; case V_ASN1_BOOLEAN: if (format != ASN1_GEN_FORMAT_ASCII) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); goto bad_form; } vtmp.name = NULL; vtmp.section = NULL; vtmp.value = (char *)str; if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); goto bad_str; } break; case V_ASN1_INTEGER: case V_ASN1_ENUMERATED: if (format != ASN1_GEN_FORMAT_ASCII) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); goto bad_form; } if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); goto bad_str; } break; case V_ASN1_OBJECT: if (format != ASN1_GEN_FORMAT_ASCII) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); goto bad_form; } if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); goto bad_str; } break; case V_ASN1_UTCTIME: case V_ASN1_GENERALIZEDTIME: if (format != ASN1_GEN_FORMAT_ASCII) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); goto bad_form; } if (!(atmp->value.asn1_string = ASN1_STRING_new())) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_str; } if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_str; } atmp->value.asn1_string->type = utype; if (!ASN1_TIME_check(atmp->value.asn1_string)) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); goto bad_str; } break; case V_ASN1_BMPSTRING: case V_ASN1_PRINTABLESTRING: case V_ASN1_IA5STRING: case V_ASN1_T61STRING: case V_ASN1_UTF8STRING: case V_ASN1_VISIBLESTRING: case V_ASN1_UNIVERSALSTRING: case V_ASN1_GENERALSTRING: if (format == ASN1_GEN_FORMAT_ASCII) format = MBSTRING_ASC; else if (format == ASN1_GEN_FORMAT_UTF8) format = MBSTRING_UTF8; else { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); goto bad_form; } if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, -1, format, ASN1_tag2bit(utype)) <= 0) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_str; } break; case V_ASN1_BIT_STRING: case V_ASN1_OCTET_STRING: if (!(atmp->value.asn1_string = ASN1_STRING_new())) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_form; } if (format == ASN1_GEN_FORMAT_HEX) { if (!(rdata = string_to_hex((char *)str, &rdlen))) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); goto bad_str; } atmp->value.asn1_string->data = rdata; atmp->value.asn1_string->length = rdlen; atmp->value.asn1_string->type = utype; } else if (format == ASN1_GEN_FORMAT_ASCII) ASN1_STRING_set(atmp->value.asn1_string, str, -1); else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING)) { if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string)) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); goto bad_str; } no_unused = 0; } else { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); goto bad_form; } if ((utype == V_ASN1_BIT_STRING) && no_unused) { atmp->value.asn1_string->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; } break; default: ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); goto bad_str; break; } atmp->type = utype; return atmp; bad_str: ERR_add_error_data(2, "string=", str); bad_form: ASN1_TYPE_free(atmp); return NULL; }
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) { ASN1_TYPE *ret; tag_exp_arg asn1_tags; tag_exp_type *etmp; int i, len; unsigned char *orig_der = NULL, *new_der = NULL; const unsigned char *cpy_start; unsigned char *p; const unsigned char *cp; int cpy_len; long hdr_len; int hdr_constructed = 0, hdr_tag, hdr_class; int r; asn1_tags.imp_tag = -1; asn1_tags.imp_class = -1; asn1_tags.format = ASN1_GEN_FORMAT_ASCII; asn1_tags.exp_count = 0; if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) return NULL; if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET)) { if (!cnf) { ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); return NULL; } ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf); } else ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); if (!ret) return NULL; /* If no tagging return base type */ if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) return ret; /* Generate the encoding */ cpy_len = i2d_ASN1_TYPE(ret, &orig_der); ASN1_TYPE_free(ret); ret = NULL; /* Set point to start copying for modified encoding */ cpy_start = orig_der; /* Do we need IMPLICIT tagging? */ if (asn1_tags.imp_tag != -1) { /* If IMPLICIT we will replace the underlying tag */ /* Skip existing tag+len */ r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len); if (r & 0x80) goto err; /* Update copy length */ cpy_len -= (int)(cpy_start - orig_der); /* For IMPLICIT tagging the length should match the * original length and constructed flag should be * consistent. */ if (r & 0x1) { /* Indefinite length constructed */ hdr_constructed = 2; hdr_len = 0; } else /* Just retain constructed flag */ hdr_constructed = r & V_ASN1_CONSTRUCTED; /* Work out new length with IMPLICIT tag: ignore constructed * because it will mess up if indefinite length */ len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); } else len = cpy_len; /* Work out length in any EXPLICIT, starting from end */ for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--) { /* Content length: number of content octets + any padding */ len += etmp->exp_pad; etmp->exp_len = len; /* Total object length: length including new header */ len = ASN1_object_size(0, len, etmp->exp_tag); } /* Allocate buffer for new encoding */ new_der = OPENSSL_malloc(len); /* Generate tagged encoding */ p = new_der; /* Output explicit tags first */ for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++) { ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, etmp->exp_tag, etmp->exp_class); if (etmp->exp_pad) *p++ = 0; } /* If IMPLICIT, output tag */ if (asn1_tags.imp_tag != -1) ASN1_put_object(&p, hdr_constructed, hdr_len, asn1_tags.imp_tag, asn1_tags.imp_class); /* Copy across original encoding */ memcpy(p, cpy_start, cpy_len); cp = new_der; /* Obtain new ASN1_TYPE structure */ ret = d2i_ASN1_TYPE(NULL, &cp, len); err: if (orig_der) OPENSSL_free(orig_der); if (new_der) OPENSSL_free(new_der); return ret; }
int ASN1_str2mask(const char *str, unsigned long *pmask) { *pmask = 0; return CONF_parse_list(str, '|', 1, mask_cb, pmask); }
static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) { int *new_list; switch (cmd) { #ifdef CIOCGSESSINFO case DEVCRYPTO_CMD_USE_SOFTDRIVERS: switch (i) { case DEVCRYPTO_REQUIRE_ACCELERATED: case DEVCRYPTO_USE_SOFTWARE: case DEVCRYPTO_REJECT_SOFTWARE: break; default: fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i); return 0; } if (use_softdrivers == i) return 1; use_softdrivers = i; #ifdef IMPLEMENT_DIGEST rebuild_known_digest_nids(e); #endif rebuild_known_cipher_nids(e); return 1; #endif /* CIOCGSESSINFO */ case DEVCRYPTO_CMD_CIPHERS: if (p == NULL) return 1; if (strcasecmp((const char *)p, "ALL") == 0) { devcrypto_select_all_ciphers(selected_ciphers); } else if (strcasecmp((const char*)p, "NONE") == 0) { memset(selected_ciphers, 0, sizeof(selected_ciphers)); } else { new_list=OPENSSL_zalloc(sizeof(selected_ciphers)); if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) { OPENSSL_free(new_list); return 0; } memcpy(selected_ciphers, new_list, sizeof(selected_ciphers)); OPENSSL_free(new_list); } rebuild_known_cipher_nids(e); return 1; #ifdef IMPLEMENT_DIGEST case DEVCRYPTO_CMD_DIGESTS: if (p == NULL) return 1; if (strcasecmp((const char *)p, "ALL") == 0) { devcrypto_select_all_digests(selected_digests); } else if (strcasecmp((const char*)p, "NONE") == 0) { memset(selected_digests, 0, sizeof(selected_digests)); } else { new_list=OPENSSL_zalloc(sizeof(selected_digests)); if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) { OPENSSL_free(new_list); return 0; } memcpy(selected_digests, new_list, sizeof(selected_digests)); OPENSSL_free(new_list); } rebuild_known_digest_nids(e); return 1; #endif /* IMPLEMENT_DIGEST */ case DEVCRYPTO_CMD_DUMP_INFO: dump_cipher_info(); #ifdef IMPLEMENT_DIGEST dump_digest_info(); #endif return 1; default: break; } return 0; }
/* launch a service */ pid_t launch_svc(CONF *conf, const char *name) { int fds[2], i; pid_t pid; char *cmd, *args, *argv[32] = {0}, **ap, *dir; char *groups; long uid, gid; if (nsvcs) warnx("Launching service %d: %s", nsvcs, name); else warnx("Launching %s", name); if (!(cmd = NCONF_get_string(conf, name, "cmd"))) errx(1, "`cmd' missing in [%s]", name); if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) err(1, "socketpair"); switch ((pid = fork())) { case -1: /* error */ err(1, "fork"); case 0: /* child */ close(fds[0]); break; default: /* parent */ warnx("%s: pid %d", name, pid); close(fds[1]); svcfds[nsvcs] = fds[0]; ++nsvcs; return pid; } /* child */ argv[0] = cmd; /* argv[1] is used by svc to receive data from zookd */ asprintf(&argv[1], "%d", fds[1]); /* split extra arguments */ if ((args = NCONF_get_string(conf, name, "args"))) { for (ap = &argv[2]; (*ap = strsep(&args, " \t")) != NULL; ) if (**ap != '\0') if (++ap >= &argv[31]) break; } if (NCONF_get_number_e(conf, name, "uid", &uid)) { /* change real, effective, and saved uid to uid */ warnx("setuid %ld", uid); } if (NCONF_get_number_e(conf, name, "gid", &gid)) { /* change real, effective, and saved gid to gid */ warnx("setgid %ld", gid); } if ((groups = NCONF_get_string(conf, name, "extra_gids"))) { ngids = 0; CONF_parse_list(groups, ',', 1, &group_parse_cb, NULL); /* set the grouplist to gids */ for (i = 0; i < ngids; i++) warnx("extra gid %d", gids[i]); } if ((dir = NCONF_get_string(conf, name, "dir"))) { /* chroot into dir */ } signal(SIGCHLD, SIG_DFL); signal(SIGPIPE, SIG_DFL); execv(argv[0], argv); err(1, "execv %s %s", argv[0], argv[1]); }
int main(int argc, char **argv) { char *filename = ZOOK_CONF; CONF *conf; long eline = 0; char *portstr, *svcs; int sockfd; pid_t disppid; int i, status; /* read configuration http://linux.die.net/man/5/config http://www.openssl.org/docs/apps/config.html */ if (argc > 1) filename = argv[1]; conf = NCONF_new(NULL); if (!NCONF_load(conf, filename, &eline)) { if (eline) errx(1, "Failed parsing %s:%ld", filename, eline); else errx(1, "Failed opening %s", filename); } /* http server port, default 80 */ if (!(portstr = NCONF_get_string(conf, "zook", "port"))) portstr = "80"; sockfd = start_server(portstr); warnx("Listening on port %s", portstr); signal(SIGCHLD, SIG_IGN); signal(SIGPIPE, SIG_IGN); /* launch the dispatch daemon */ disppid = launch_svc(conf, "zookd"); /* launch http services */ if ((svcs = NCONF_get_string(conf, "zook", "http_svcs"))) CONF_parse_list(svcs, ',', 1, &service_parse_cb, conf); /* send the server socket to zookd */ if (sendfd(svcfds[0], &nsvcs, sizeof(nsvcs), sockfd) < 0) err(1, "sendfd to zookd"); close(sockfd); /* send all svc sockets with their url patterns to http services */ for (i = 1; i < nsvcs; ++i) { char *url = NCONF_get_string(conf, svcnames[i], "url"); if (!url) url = ".*"; sendfd(svcfds[0], url, strlen(url) + 1, svcfds[i]); close(svcfds[i]); } close(svcfds[0]); /* launch non-http services */ if ((svcs = NCONF_get_string(conf, "zook", "extra_svcs"))) CONF_parse_list(svcs, ',', 1, &service_parse_cb, conf); NCONF_free(conf); /* wait for zookd */ waitpid(disppid, &status, 0); }