conf_lib.c 9.4 KB
Newer Older
1
/*
M
Matt Caswell 已提交
2
 * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9
 */

10
#include "e_os.h"
11
#include <stdio.h>
R
Rich Salz 已提交
12
#include <string.h>
R
Rich Salz 已提交
13
#include "internal/conf.h"
14
#include "crypto/ctype.h"
15 16 17 18 19 20
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <openssl/conf_api.h>
#include <openssl/lhash.h>

21
static CONF_METHOD *default_CONF_method = NULL;
22

D
 
Dr. Stephen Henson 已提交
23 24
/* Init a 'CONF' structure from an old LHASH */

B
Ben Laurie 已提交
25
void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
26 27 28
{
    if (default_CONF_method == NULL)
        default_CONF_method = NCONF_default();
D
 
Dr. Stephen Henson 已提交
29

30 31 32
    default_CONF_method->init(conf);
    conf->data = hash;
}
D
 
Dr. Stephen Henson 已提交
33

34 35 36 37
/*
 * The following section contains the "CONF classic" functions, rewritten in
 * terms of the new CONF interface.
 */
38 39

int CONF_set_default_method(CONF_METHOD *meth)
40 41 42 43
{
    default_CONF_method = meth;
    return 1;
}
44

B
Ben Laurie 已提交
45
LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
46 47 48 49
                                long *eline)
{
    LHASH_OF(CONF_VALUE) *ltmp;
    BIO *in = NULL;
50

51
#ifdef OPENSSL_SYS_VMS
52
    in = BIO_new_file(file, "r");
53
#else
54
    in = BIO_new_file(file, "rb");
55
#endif
56 57 58 59
    if (in == NULL) {
        CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB);
        return NULL;
    }
60

61 62
    ltmp = CONF_load_bio(conf, in, eline);
    BIO_free(in);
63

64 65
    return ltmp;
}
66

R
Rich Salz 已提交
67
#ifndef OPENSSL_NO_STDIO
B
Ben Laurie 已提交
68
LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
69 70 71 72
                                   long *eline)
{
    BIO *btmp;
    LHASH_OF(CONF_VALUE) *ltmp;
73
    if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
74 75 76 77 78 79 80
        CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB);
        return NULL;
    }
    ltmp = CONF_load_bio(conf, btmp, eline);
    BIO_free(btmp);
    return ltmp;
}
81 82
#endif

B
Ben Laurie 已提交
83
LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
84 85 86 87
                                    long *eline)
{
    CONF ctmp;
    int ret;
88

89
    CONF_set_nconf(&ctmp, conf);
90

91 92 93 94 95
    ret = NCONF_load_bio(&ctmp, bp, eline);
    if (ret)
        return ctmp.data;
    return NULL;
}
96

B
Ben Laurie 已提交
97
STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
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
                                       const char *section)
{
    if (conf == NULL) {
        return NULL;
    } else {
        CONF ctmp;
        CONF_set_nconf(&ctmp, conf);
        return NCONF_get_section(&ctmp, section);
    }
}

char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
                      const char *name)
{
    if (conf == NULL) {
        return NCONF_get_string(NULL, group, name);
    } else {
        CONF ctmp;
        CONF_set_nconf(&ctmp, conf);
        return NCONF_get_string(&ctmp, group, name);
    }
}

long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
                     const char *name)
{
    int status;
    long result = 0;

P
Pauli 已提交
127
    ERR_set_mark();
128 129 130 131 132 133 134
    if (conf == NULL) {
        status = NCONF_get_number_e(NULL, group, name, &result);
    } else {
        CONF ctmp;
        CONF_set_nconf(&ctmp, conf);
        status = NCONF_get_number_e(&ctmp, group, name, &result);
    }
P
Pauli 已提交
135 136
    ERR_pop_to_mark();
    return status == 0 ? 0L : result;
137
}
138

B
Ben Laurie 已提交
139
void CONF_free(LHASH_OF(CONF_VALUE) *conf)
140 141 142 143 144
{
    CONF ctmp;
    CONF_set_nconf(&ctmp, conf);
    NCONF_free_data(&ctmp);
}
145

R
Rich Salz 已提交
146
#ifndef OPENSSL_NO_STDIO
B
Ben Laurie 已提交
147
int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
148 149 150 151
{
    BIO *btmp;
    int ret;

152
    if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) {
153 154 155 156 157 158 159
        CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB);
        return 0;
    }
    ret = CONF_dump_bio(conf, btmp);
    BIO_free(btmp);
    return ret;
}
160 161
#endif

B
Ben Laurie 已提交
162
int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
163 164 165 166 167 168 169 170 171 172 173 174 175
{
    CONF ctmp;
    CONF_set_nconf(&ctmp, conf);
    return NCONF_dump_bio(&ctmp, out);
}

/*
 * The following section contains the "New CONF" functions.  They are
 * completely centralised around a new CONF structure that may contain
 * basically anything, but at least a method pointer and a table of data.
 * These functions are also written in terms of the bridge functions used by
 * the "CONF classic" functions, for consistency.
 */
176 177

CONF *NCONF_new(CONF_METHOD *meth)
178 179
{
    CONF *ret;
180

181 182
    if (meth == NULL)
        meth = NCONF_default();
183

184 185 186
    ret = meth->create(meth);
    if (ret == NULL) {
        CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
187
        return NULL;
188
    }
189

190 191
    return ret;
}
192 193

void NCONF_free(CONF *conf)
194 195 196 197 198
{
    if (conf == NULL)
        return;
    conf->meth->destroy(conf);
}
199 200

void NCONF_free_data(CONF *conf)
201 202 203 204 205
{
    if (conf == NULL)
        return;
    conf->meth->destroy_data(conf);
}
206 207

int NCONF_load(CONF *conf, const char *file, long *eline)
208 209 210 211 212
{
    if (conf == NULL) {
        CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF);
        return 0;
    }
213

214 215
    return conf->meth->load(conf, file, eline);
}
216

R
Rich Salz 已提交
217
#ifndef OPENSSL_NO_STDIO
218 219 220 221
int NCONF_load_fp(CONF *conf, FILE *fp, long *eline)
{
    BIO *btmp;
    int ret;
222
    if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
223 224 225 226 227 228 229
        CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB);
        return 0;
    }
    ret = NCONF_load_bio(conf, btmp, eline);
    BIO_free(btmp);
    return ret;
}
230 231
#endif

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
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);
}

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);
}

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;
}

P
Pauli 已提交
278 279 280 281 282 283 284 285 286 287
static int default_is_number(const CONF *conf, char c)
{
    return ossl_isdigit(c);
}

static int default_to_int(const CONF *conf, char c)
{
    return (int)(c - '0');
}

288 289 290 291
int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
                       long *result)
{
    char *str;
P
Pauli 已提交
292 293 294
    long res;
    int (*is_number)(const CONF *, char) = &default_is_number;
    int (*to_int)(const CONF *, char) = &default_to_int;
295 296 297 298 299 300 301 302 303 304 305

    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;

P
Pauli 已提交
306 307 308 309 310 311 312 313 314 315 316 317
    if (conf != NULL) {
        if (conf->meth->is_number != NULL)
            is_number = conf->meth->is_number;
        if (conf->meth->to_int != NULL)
            to_int = conf->meth->to_int;
    }
    for (res = 0; is_number(conf, *str); str++) {
        const int d = to_int(conf, *str);

        if (res > (LONG_MAX - d) / 10L) {
            CONFerr(CONF_F_NCONF_GET_NUMBER_E, CONF_R_NUMBER_TOO_LARGE);
            return 0;
P
Pauli 已提交
318
        }
P
Pauli 已提交
319 320
        res = res * 10 + d;
    }
321

P
Pauli 已提交
322
    *result = res;
323 324
    return 1;
}
325

R
Rich Salz 已提交
326
#ifndef OPENSSL_NO_STDIO
327
int NCONF_dump_fp(const CONF *conf, FILE *out)
328 329 330
{
    BIO *btmp;
    int ret;
331
    if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) {
332 333 334 335 336 337 338
        CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB);
        return 0;
    }
    ret = NCONF_dump_bio(conf, btmp);
    BIO_free(btmp);
    return ret;
}
339 340
#endif

341
int NCONF_dump_bio(const CONF *conf, BIO *out)
342 343 344 345 346
{
    if (conf == NULL) {
        CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF);
        return 0;
    }
347

348 349
    return conf->meth->dump(conf, out);
}
R
Rich Salz 已提交
350 351 352 353 354 355 356 357 358

/*
 * These routines call the C malloc/free, to avoid intermixing with
 * OpenSSL function pointers before the library is initialized.
 */
OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void)
{
    OPENSSL_INIT_SETTINGS *ret = malloc(sizeof(*ret));

F
FdaSilvaYY 已提交
359 360 361 362
    if (ret == NULL)
        return NULL;

    memset(ret, 0, sizeof(*ret));
363 364
    ret->flags = DEFAULT_CONF_MFLAGS;

R
Rich Salz 已提交
365 366 367 368
    return ret;
}


369
#ifndef OPENSSL_NO_STDIO
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings,
                                     const char *filename)
{
    char *newfilename = NULL;

    if (filename != NULL) {
        newfilename = strdup(filename);
        if (newfilename == NULL)
            return 0;
    }

    free(settings->filename);
    settings->filename = newfilename;

    return 1;
}

void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings,
                                        unsigned long flags)
{
    settings->flags = flags;
}

393 394
int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings,
                                    const char *appname)
R
Rich Salz 已提交
395
{
396
    char *newappname = NULL;
397

398 399 400
    if (appname != NULL) {
        newappname = strdup(appname);
        if (newappname == NULL)
401 402 403
            return 0;
    }

404 405
    free(settings->appname);
    settings->appname = newappname;
406 407

    return 1;
R
Rich Salz 已提交
408
}
409
#endif
R
Rich Salz 已提交
410 411 412

void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings)
{
413
    free(settings->filename);
414
    free(settings->appname);
R
Rich Salz 已提交
415 416
    free(settings);
}