static int def_load(CONF *conf, const char *name, long *line) { int ret; BIO *in=NULL; #ifndef OPENSSL_NO_FP_API #ifdef OPENSSL_SYS_VMS in=BIO_new_file(name, "r"); #else in=BIO_new_file(name, "rb"); #endif #endif if (in == NULL) { if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) CONFerr(CONF_F_DEF_LOAD,CONF_R_NO_SUCH_FILE); else CONFerr(CONF_F_DEF_LOAD,ERR_R_SYS_LIB); return 0; } ret = def_load_bio(conf, in, line); BIO_free(in); return ret; }
STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,const char *section) { if (conf == NULL) { CONFerr(CONF_F_NCONF_GET_SECTION,CONF_R_NO_CONF); return NULL; } if (section == NULL) { CONFerr(CONF_F_NCONF_GET_SECTION,CONF_R_NO_SECTION); return NULL; } return _CONF_get_section_values(conf, section); }
/* * Check whether included path is a directory. * Returns next BIO to process and in case of a directory * also an opened directory context and the include path. */ static BIO *process_include(char *include, OPENSSL_DIR_CTX **dirctx, char **dirpath) { struct stat st = { 0 }; BIO *next; if (stat(include, &st) < 0) { SYSerr(SYS_F_STAT, errno); ERR_add_error_data(1, include); /* missing include file is not fatal error */ return NULL; } if (S_ISDIR(st.st_mode)) { if (*dirctx != NULL) { CONFerr(CONF_F_PROCESS_INCLUDE, CONF_R_RECURSIVE_DIRECTORY_INCLUDE); ERR_add_error_data(1, include); return NULL; } /* a directory, load its contents */ if ((next = get_next_file(include, dirctx)) != NULL) *dirpath = include; return next; } next = BIO_new_file(include, "r"); return next; }
char *NCONF_get_string(const CONF *conf,const char *group,const char *name) { char *s = _CONF_get_string(conf, group, name); /* Since we may get a value from an environment variable even if conf is NULL, let's check the value first */ if (s) return s; if (conf == NULL) { CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); return NULL; } CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); ERR_add_error_data(4,"group=",group," name=",name); return NULL; }
int NCONF_load_bio(CONF *conf, BIO *bp,long *eline) { if (conf == NULL) { CONFerr(CONF_F_NCONF_LOAD_BIO,CONF_R_NO_CONF); return 0; } return conf->meth->load_bio(conf, bp, eline); }
int NCONF_load(CONF *conf, const char *file, long *eline) { if (conf == NULL) { CONFerr(CONF_F_NCONF_LOAD,CONF_R_NO_CONF); return 0; } return conf->meth->load(conf, file, eline); }
int NCONF_dump_bio(const CONF *conf, BIO *out) { if (conf == NULL) { CONFerr(CONF_F_NCONF_DUMP_BIO,CONF_R_NO_CONF); return 0; } return conf->meth->dump(conf, out); }
/* * Get next file from the directory path. * Returns BIO of the next file to read and updates dirctx. */ static BIO *get_next_file(const char *path, OPENSSL_DIR_CTX **dirctx) { const char *filename; while ((filename = OPENSSL_DIR_read(dirctx, path)) != NULL) { size_t namelen; namelen = strlen(filename); if ((namelen > 5 && strcasecmp(filename + namelen - 5, ".conf") == 0) || (namelen > 4 && strcasecmp(filename + namelen - 4, ".cnf") == 0)) { size_t newlen; char *newpath; BIO *bio; newlen = strlen(path) + namelen + 2; newpath = OPENSSL_zalloc(newlen); if (newpath == NULL) { CONFerr(CONF_F_GET_NEXT_FILE, ERR_R_MALLOC_FAILURE); break; } #ifdef OPENSSL_SYS_VMS /* * If the given path isn't clear VMS syntax, * we treat it as on Unix. */ { size_t pathlen = strlen(path); if (path[pathlen - 1] == ']' || path[pathlen - 1] == '>' || path[pathlen - 1] == ':') { /* Clear VMS directory syntax, just copy as is */ OPENSSL_strlcpy(newpath, path, newlen); } } #endif if (newpath[0] == '\0') { OPENSSL_strlcpy(newpath, path, newlen); OPENSSL_strlcat(newpath, "/", newlen); } OPENSSL_strlcat(newpath, filename, newlen); bio = BIO_new_file(newpath, "r"); OPENSSL_free(newpath); /* Errors when opening files are non-fatal. */ if (bio != NULL) return bio; } } OPENSSL_DIR_end(dirctx); *dirctx = NULL; return NULL; }
int NCONF_dump_fp(const CONF *conf, FILE *out) { BIO *btmp; int ret; if(!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { CONFerr(CONF_F_NCONF_DUMP_FP,ERR_R_BUF_LIB); return 0; } ret = NCONF_dump_bio(conf, btmp); BIO_free(btmp); return ret; }
LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline) { BIO *btmp; LHASH *ltmp; if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB); return NULL; } ltmp = CONF_load_bio(conf, btmp, eline); BIO_free(btmp); return ltmp; }
int NCONF_load_fp(CONF *conf, FILE *fp,long *eline) { BIO *btmp; int ret; if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { CONFerr(CONF_F_NCONF_LOAD_FP,ERR_R_BUF_LIB); return 0; } ret = NCONF_load_bio(conf, btmp, eline); BIO_free(btmp); return ret; }
CONF *NCONF_new(CONF_METHOD *meth) { CONF *ret; if (meth == NULL) meth = NCONF_default(); ret = meth->create(meth); if (ret == NULL) { CONFerr(CONF_F_NCONF_NEW,ERR_R_MALLOC_FAILURE); return(NULL); } return ret; }
LHASH *CONF_load(LHASH *conf, const char *file, long *eline) { LHASH *ltmp; BIO *in=NULL; #ifdef OPENSSL_SYS_VMS in=BIO_new_file(file, "r"); #else in=BIO_new_file(file, "rb"); #endif if (in == NULL) { CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB); return NULL; } ltmp = CONF_load_bio(conf, in, eline); BIO_free(in); return ltmp; }
int NCONF_get_number_e(const CONF *conf,const char *group,const char *name, long *result) { char *str; if (result == NULL) { CONFerr(CONF_F_NCONF_GET_NUMBER_E,ERR_R_PASSED_NULL_PARAMETER); return 0; } str = NCONF_get_string(conf,group,name); if (str == NULL) return 0; for (*result = 0;conf->meth->is_number(conf, *str);) { *result = (*result)*10 + conf->meth->to_int(conf, *str); str++; } return 1; }
static int str_copy(CONF *conf, char *section, char **pto, char *from) { int q, r, rr = 0, to = 0, len = 0; char *s, *e, *rp, *p, *rrp, *np, *cp, v; BUF_MEM *buf; if ((buf = BUF_MEM_new()) == NULL) return 0; len = strlen(from) + 1; if (!BUF_MEM_grow(buf, len)) goto err; for (;;) { if (IS_QUOTE(conf, *from)) { q = *from; from++; while (!IS_EOF(conf, *from) && (*from != q)) { if (IS_ESC(conf, *from)) { from++; if (IS_EOF(conf, *from)) break; } buf->data[to++] = *(from++); } if (*from == q) from++; } else if (IS_DQUOTE(conf, *from)) { q = *from; from++; while (!IS_EOF(conf, *from)) { if (*from == q) { if (*(from + 1) == q) { from++; } else { break; } } buf->data[to++] = *(from++); } if (*from == q) from++; } else if (IS_ESC(conf, *from)) { from++; v = *(from++); if (IS_EOF(conf, v)) break; else if (v == 'r') v = '\r'; else if (v == 'n') v = '\n'; else if (v == 'b') v = '\b'; else if (v == 't') v = '\t'; buf->data[to++] = v; } else if (IS_EOF(conf, *from)) break; else if (*from == '$') { size_t newsize; /* try to expand it */ rrp = NULL; s = &(from[1]); if (*s == '{') q = '}'; else if (*s == '(') q = ')'; else q = 0; if (q) s++; cp = section; e = np = s; while (IS_ALNUM(conf, *e)) e++; if ((e[0] == ':') && (e[1] == ':')) { cp = np; rrp = e; rr = *e; *rrp = '\0'; e += 2; np = e; while (IS_ALNUM(conf, *e)) e++; } r = *e; *e = '\0'; rp = e; if (q) { if (r != q) { CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE); goto err; } e++; } /*- * So at this point we have * np which is the start of the name string which is * '\0' terminated. * cp which is the start of the section string which is * '\0' terminated. * e is the 'next point after'. * r and rr are the chars replaced by the '\0' * rp and rrp is where 'r' and 'rr' came from. */ p = _CONF_get_string(conf, cp, np); if (rrp != NULL) *rrp = rr; *rp = r; if (p == NULL) { CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE); goto err; } newsize = strlen(p) + buf->length - (e - from); if (newsize > MAX_CONF_VALUE_LENGTH) { CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG); goto err; } if (!BUF_MEM_grow_clean(buf, newsize)) { CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE); goto err; } while (*p) buf->data[to++] = *(p++); /* * Since we change the pointer 'from', we also have to change the * perceived length of the string it points at. /RL */ len -= e - from; from = e; /* * In case there were no braces or parenthesis around the * variable reference, we have to put back the character that was * replaced with a '\0'. /RL */ *rp = r; } else buf->data[to++] = *(from++); } buf->data[to] = '\0'; OPENSSL_free(*pto); *pto = buf->data; OPENSSL_free(buf); return 1; err: BUF_MEM_free(buf); return 0; }
static int def_load_bio(CONF *conf, BIO *in, long *line) { /* The macro BUFSIZE conflicts with a system macro in VxWorks */ #define CONFBUFSIZE 512 int bufnum = 0, i, ii; BUF_MEM *buff = NULL; char *s, *p, *end; int again; long eline = 0; char btmp[DECIMAL_SIZE(eline) + 1]; CONF_VALUE *v = NULL, *tv; CONF_VALUE *sv = NULL; char *section = NULL, *buf; char *start, *psection, *pname; void *h = (void *)(conf->data); STACK_OF(BIO) *biosk = NULL; #ifndef OPENSSL_NO_POSIX_IO char *dirpath = NULL; OPENSSL_DIR_CTX *dirctx = NULL; #endif if ((buff = BUF_MEM_new()) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); goto err; } section = OPENSSL_strdup("default"); if (section == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (_CONF_new_data(conf) == 0) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } sv = _CONF_new_section(conf, section); if (sv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } bufnum = 0; again = 0; for (;;) { if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); goto err; } p = &(buff->data[bufnum]); *p = '\0'; read_retry: BIO_gets(in, p, CONFBUFSIZE - 1); p[CONFBUFSIZE - 1] = '\0'; ii = i = strlen(p); if (i == 0 && !again) { /* the currently processed BIO is at EOF */ BIO *parent; #ifndef OPENSSL_NO_POSIX_IO /* continue processing with the next file from directory */ if (dirctx != NULL) { BIO *next; if ((next = get_next_file(dirpath, &dirctx)) != NULL) { BIO_vfree(in); in = next; goto read_retry; } else { OPENSSL_free(dirpath); dirpath = NULL; } } #endif /* no more files in directory, continue with processing parent */ if ((parent = sk_BIO_pop(biosk)) == NULL) { /* everything processed get out of the loop */ break; } else { BIO_vfree(in); in = parent; goto read_retry; } } again = 0; while (i > 0) { if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) break; else i--; } /* * we removed some trailing stuff so there is a new line on the end. */ if (ii && i == ii) again = 1; /* long line */ else { p[i] = '\0'; eline++; /* another input line */ } /* we now have a line with trailing \r\n removed */ /* i is the number of bytes */ bufnum += i; v = NULL; /* check for line continuation */ if (bufnum >= 1) { /* * If we have bytes and the last char '\\' and second last char * is not '\\' */ p = &(buff->data[bufnum - 1]); if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { bufnum--; again = 1; } } if (again) continue; bufnum = 0; buf = buff->data; clear_comments(conf, buf); s = eat_ws(conf, buf); if (IS_EOF(conf, *s)) continue; /* blank line */ if (*s == '[') { char *ss; s++; start = eat_ws(conf, s); ss = start; again: end = eat_alpha_numeric(conf, ss); p = eat_ws(conf, end); if (*p != ']') { if (*p != '\0' && ss != p) { ss = p; goto again; } CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); goto err; } *end = '\0'; if (!str_copy(conf, NULL, §ion, start)) goto err; if ((sv = _CONF_get_section(conf, section)) == NULL) sv = _CONF_new_section(conf, section); if (sv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } continue; } else { pname = s; end = eat_alpha_numeric(conf, s); if ((end[0] == ':') && (end[1] == ':')) { *end = '\0'; end += 2; psection = pname; pname = end; end = eat_alpha_numeric(conf, end); } else { psection = section; } p = eat_ws(conf, end); if (strncmp(pname, ".include", 8) == 0 && (p != pname + 8 || *p == '=')) { char *include = NULL; BIO *next; if (*p == '=') { p++; p = eat_ws(conf, p); } trim_ws(conf, p); if (!str_copy(conf, psection, &include, p)) goto err; /* get the BIO of the included file */ #ifndef OPENSSL_NO_POSIX_IO next = process_include(include, &dirctx, &dirpath); if (include != dirpath) { /* dirpath will contain include in case of a directory */ OPENSSL_free(include); } #else next = BIO_new_file(include, "r"); OPENSSL_free(include); #endif if (next != NULL) { /* push the currently processing BIO onto stack */ if (biosk == NULL) { if ((biosk = sk_BIO_new_null()) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } } if (!sk_BIO_push(biosk, in)) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } /* continue with reading from the included BIO */ in = next; } continue; } else if (*p != '=') { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); goto err; } *end = '\0'; p++; start = eat_ws(conf, p); trim_ws(conf, start); if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } v->name = OPENSSL_strdup(pname); v->value = NULL; if (v->name == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (!str_copy(conf, psection, &(v->value), start)) goto err; if (strcmp(psection, section) != 0) { if ((tv = _CONF_get_section(conf, psection)) == NULL) tv = _CONF_new_section(conf, psection); if (tv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } } else tv = sv; if (_CONF_add_string(conf, tv, v) == 0) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } v = NULL; } } BUF_MEM_free(buff); OPENSSL_free(section); /* * No need to pop, since we only get here if the stack is empty. * If this causes a BIO leak, THE ISSUE IS SOMEWHERE ELSE! */ sk_BIO_free(biosk); return 1; err: BUF_MEM_free(buff); OPENSSL_free(section); /* * Since |in| is the first element of the stack and should NOT be freed * here, we cannot use sk_BIO_pop_free(). Instead, we pop and free one * BIO at a time, making sure that the last one popped isn't. */ while (sk_BIO_num(biosk) > 0) { BIO *popped = sk_BIO_pop(biosk); BIO_vfree(in); in = popped; } sk_BIO_free(biosk); #ifndef OPENSSL_NO_POSIX_IO OPENSSL_free(dirpath); if (dirctx != NULL) OPENSSL_DIR_end(&dirctx); #endif if (line != NULL) *line = eline; BIO_snprintf(btmp, sizeof(btmp), "%ld", eline); ERR_add_error_data(2, "line ", btmp); if (h != conf->data) { CONF_free(conf->data); conf->data = NULL; } if (v != NULL) { OPENSSL_free(v->name); OPENSSL_free(v->value); OPENSSL_free(v); } return 0; }
static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) { size_t i, j, cnt; int rv = 0; const char *ssl_conf_section; STACK_OF(CONF_VALUE) *cmd_lists; ssl_conf_section = CONF_imodule_get_value(md); cmd_lists = NCONF_get_section(cnf, ssl_conf_section); if (sk_CONF_VALUE_num(cmd_lists) <= 0) { if (cmd_lists == NULL) CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_SECTION_NOT_FOUND); else CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_SECTION_EMPTY); ERR_add_error_data(2, "section=", ssl_conf_section); goto err; } cnt = sk_CONF_VALUE_num(cmd_lists); ssl_module_free(md); ssl_names = OPENSSL_zalloc(sizeof(*ssl_names) * cnt); if (ssl_names == NULL) goto err; ssl_names_count = cnt; for (i = 0; i < ssl_names_count; i++) { struct ssl_conf_name_st *ssl_name = ssl_names + i; CONF_VALUE *sect = sk_CONF_VALUE_value(cmd_lists, (int)i); STACK_OF(CONF_VALUE) *cmds = NCONF_get_section(cnf, sect->value); if (sk_CONF_VALUE_num(cmds) <= 0) { if (cmds == NULL) CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_COMMAND_SECTION_NOT_FOUND); else CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_COMMAND_SECTION_EMPTY); ERR_add_error_data(4, "name=", sect->name, ", value=", sect->value); goto err; } ssl_name->name = OPENSSL_strdup(sect->name); if (ssl_name->name == NULL) goto err; cnt = sk_CONF_VALUE_num(cmds); ssl_name->cmds = OPENSSL_zalloc(cnt * sizeof(struct ssl_conf_cmd_st)); if (ssl_name->cmds == NULL) goto err; ssl_name->cmd_count = cnt; for (j = 0; j < cnt; j++) { const char *name; CONF_VALUE *cmd_conf = sk_CONF_VALUE_value(cmds, (int)j); struct ssl_conf_cmd_st *cmd = ssl_name->cmds + j; /* Skip any initial dot in name */ name = strchr(cmd_conf->name, '.'); if (name != NULL) name++; else name = cmd_conf->name; cmd->cmd = OPENSSL_strdup(name); cmd->arg = OPENSSL_strdup(cmd_conf->value); if (cmd->cmd == NULL || cmd->arg == NULL) goto err; } } rv = 1; err: if (rv == 0) ssl_module_free(md); return rv; }
static int def_load_bio(CONF *conf, BIO *in, long *line) { /* The macro BUFSIZE conflicts with a system macro in VxWorks */ #define CONFBUFSIZE 512 int bufnum=0,i,ii; BUF_MEM *buff=NULL; char *s,*p,*end; int again; long eline=0; char btmp[DECIMAL_SIZE(eline)+1]; CONF_VALUE *v=NULL,*tv; CONF_VALUE *sv=NULL; char *section=NULL,*buf; STACK_OF(CONF_VALUE) *section_sk=NULL,*ts __UNUSED; char *start,*psection,*pname; void *h = (void *)(conf->data); if ((buff=BUF_MEM_new()) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB); goto err; } section=(char *)OPENSSL_malloc(10); if (section == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE); goto err; } BUF_strlcpy(section,"default",10); if (_CONF_new_data(conf) == 0) { CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_MALLOC_FAILURE); goto err; } sv=_CONF_new_section(conf,section); if (sv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } section_sk=(STACK_OF(CONF_VALUE) *)sv->value; bufnum=0; again=0; for (;;) { if (!BUF_MEM_grow(buff,bufnum+CONFBUFSIZE)) { CONFerr(CONF_F_DEF_LOAD_BIO,ERR_R_BUF_LIB); goto err; } p= &(buff->data[bufnum]); *p='\0'; BIO_gets(in, p, CONFBUFSIZE-1); p[CONFBUFSIZE-1]='\0'; ii=i=strlen(p); if (i == 0 && !again) break; again=0; while (i > 0) { if ((p[i-1] != '\r') && (p[i-1] != '\n')) break; else i--; } /* we removed some trailing stuff so there is a new * line on the end. */ if (ii && i == ii) again=1; /* long line */ else { p[i]='\0'; eline++; /* another input line */ } /* we now have a line with trailing \r\n removed */ /* i is the number of bytes */ bufnum+=i; v=NULL; /* check for line continuation */ if (bufnum >= 1) { /* If we have bytes and the last char '\\' and * second last char is not '\\' */ p= &(buff->data[bufnum-1]); if (IS_ESC(conf,p[0]) && ((bufnum <= 1) || !IS_ESC(conf,p[-1]))) { bufnum--; again=1; } } if (again) continue; bufnum=0; buf=buff->data; clear_comments(conf, buf); s=eat_ws(conf, buf); if (IS_EOF(conf,*s)) continue; /* blank line */ if (*s == '[') { char *ss; s++; start=eat_ws(conf, s); ss=start; again: end=eat_alpha_numeric(conf, ss); p=eat_ws(conf, end); if (*p != ']') { if (*p != '\0') { ss=p; goto again; } CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); goto err; } *end='\0'; if (!str_copy(conf,NULL,§ion,start)) goto err; if ((sv=_CONF_get_section(conf,section)) == NULL) sv=_CONF_new_section(conf,section); if (sv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } section_sk=(STACK_OF(CONF_VALUE) *)sv->value; continue; } else {
static int def_load_bio(CONF *conf, BIO *in, long *line) { /* The macro BUFSIZE conflicts with a system macro in VxWorks */ #define CONFBUFSIZE 512 int bufnum = 0, i, ii; BUF_MEM *buff = NULL; char *s, *p, *end; int again; long eline = 0; char btmp[DECIMAL_SIZE(eline) + 1]; CONF_VALUE *v = NULL, *tv; CONF_VALUE *sv = NULL; char *section = NULL, *buf; char *start, *psection, *pname; void *h = (void *)(conf->data); if ((buff = BUF_MEM_new()) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); goto err; } section = (char *)OPENSSL_malloc(10); if (section == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } BUF_strlcpy(section, "default", 10); if (_CONF_new_data(conf) == 0) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } sv = _CONF_new_section(conf, section); if (sv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } bufnum = 0; again = 0; for (;;) { if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); goto err; } p = &(buff->data[bufnum]); *p = '\0'; BIO_gets(in, p, CONFBUFSIZE - 1); p[CONFBUFSIZE - 1] = '\0'; ii = i = sgx_strlen(p); if (i == 0 && !again) break; again = 0; while (i > 0) { if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) break; else i--; } /* * we removed some trailing stuff so there is a new line on the end. */ if (ii && i == ii) again = 1; /* long line */ else { p[i] = '\0'; eline++; /* another input line */ } /* we now have a line with trailing \r\n removed */ /* i is the number of bytes */ bufnum += i; v = NULL; /* check for line continuation */ if (bufnum >= 1) { /* * If we have bytes and the last char '\\' and second last char * is not '\\' */ p = &(buff->data[bufnum - 1]); if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { bufnum--; again = 1; } } if (again) continue; bufnum = 0; buf = buff->data; clear_comments(conf, buf); s = eat_ws(conf, buf); if (IS_EOF(conf, *s)) continue; /* blank line */ if (*s == '[') { char *ss; s++; start = eat_ws(conf, s); ss = start; again: end = eat_alpha_numeric(conf, ss); p = eat_ws(conf, end); if (*p != ']') { if (*p != '\0' && ss != p) { ss = p; goto again; } CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); goto err; } *end = '\0'; if (!str_copy(conf, NULL, §ion, start)) goto err; if ((sv = _CONF_get_section(conf, section)) == NULL) sv = _CONF_new_section(conf, section); if (sv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } continue; } else { pname = s; psection = NULL; end = eat_alpha_numeric(conf, s); if ((end[0] == ':') && (end[1] == ':')) { *end = '\0'; end += 2; psection = pname; pname = end; end = eat_alpha_numeric(conf, end); } p = eat_ws(conf, end); if (*p != '=') { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); goto err; } *end = '\0'; p++; start = eat_ws(conf, p); while (!IS_EOF(conf, *p)) p++; p--; while ((p != start) && (IS_WS(conf, *p))) p--; p++; *p = '\0'; if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (psection == NULL) psection = section; v->name = (char *)OPENSSL_malloc(strlen(pname) + 1); v->value = NULL; if (v->name == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } BUF_strlcpy(v->name, pname, sgx_strlen(pname) + 1); if (!str_copy(conf, psection, &(v->value), start)) goto err; if (sgx_strcmp(psection, section) != 0) { if ((tv = _CONF_get_section(conf, psection)) == NULL) tv = _CONF_new_section(conf, psection); if (tv == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); goto err; } } else tv = sv; #if 1 if (_CONF_add_string(conf, tv, v) == 0) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } #else v->section = tv->section; if (!sk_CONF_VALUE_push(ts, v)) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); goto err; } vv = (CONF_VALUE *)lh_insert(conf->data, v); if (vv != NULL) { sk_CONF_VALUE_delete_ptr(ts, vv); OPENSSL_free(vv->name); OPENSSL_free(vv->value); OPENSSL_free(vv); } #endif v = NULL; } } if (buff != NULL) BUF_MEM_free(buff); if (section != NULL) OPENSSL_free(section); return (1); err: if (buff != NULL) BUF_MEM_free(buff); if (section != NULL) OPENSSL_free(section); if (line != NULL) *line = eline; BIO_snprintf(btmp, sizeof btmp, "%ld", eline); ERR_add_error_data(2, "line ", btmp); if ((h != conf->data) && (conf->data != NULL)) { CONF_free(conf->data); conf->data = NULL; } if (v != NULL) { if (v->name != NULL) OPENSSL_free(v->name); if (v->value != NULL) OPENSSL_free(v->value); if (v != NULL) OPENSSL_free(v); } return (0); }