/* Parse mcast and ttl options */ int config_param_shcupd_mcastif (char *str, char **iface, char **ttl) { char buf[150]; char *sp; if (strlen(str) >= sizeof buf) { config_error_set("Invalid option for IFACE[,TTL]"); return 0; } sp = strchr(str, ','); if (!sp) { if (!strcmp(str, "*")) *iface = NULL; else *iface = str; *ttl = NULL; return 1; } else if (!strncmp(str, "*", sp - str)) { *iface = NULL; } else { *sp = 0; *iface = str; } *ttl = sp + 1; return 1; }
stud_config * config_new (void) { stud_config *r = NULL; r = malloc(sizeof(stud_config)); if (r == NULL) { config_error_set("Unable to allocate memory for configuration structure: %s", strerror(errno)); return NULL; } // set default values r->ETYPE = ENC_TLS; r->PMODE = SSL_SERVER; r->WRITE_IP_OCTET = 0; r->WRITE_PROXY_LINE = 0; r->PROXY_PROXY_LINE = 0; r->CHROOT = NULL; r->UID = 0; r->GID = 0; r->FRONT_IP = NULL; r->FRONT_PORT = strdup("8443"); r->BACK_IP = strdup("127.0.0.1"); r->BACK_PORT = strdup("8000"); #ifdef _SC_NPROCESSORS_ONLN r->NCORES = sysconf(_SC_NPROCESSORS_ONLN); #endif r->CERT_FILES = NULL; r->CIPHER_SUITE = NULL; r->NAMED_CURVE = NULL; r->ENGINE = NULL; r->BACKLOG = 100; #ifdef USE_SHARED_CACHE r->SHARED_CACHE = 0; r->SHCUPD_IP = NULL; r->SHCUPD_PORT = NULL; for (int i = 0 ; i < MAX_SHCUPD_PEERS; i++) memset(&r->SHCUPD_PEERS[i], 0, sizeof(shcupd_peer_opt)); r->SHCUPD_MCASTIF = NULL; r->SHCUPD_MCASTTTL = NULL; #endif r->QUIET = 0; r->SYSLOG = 0; r->SYSLOG_FACILITY = LOG_DAEMON; r->TCP_KEEPALIVE_TIME = 3600; r->DAEMONIZE = 0; r->PREFER_SERVER_CIPHERS = 0; config_param_val_pid_file(NULL, r->PID_FILE); return r; }
int config_param_val_intl_pos (char *str, long int *dst) { long int num = 0; if (str != NULL) num = atol(str); if (num < 1) { config_error_set("Not a positive number."); return 0; } *dst = num; return 1; }
void config_param_validate (char *k, char *v, stud_config *cfg, char *file, int line) { int r = 1; struct stat st; if (strcmp(k, "tls") == 0) { cfg->ETYPE = ENC_TLS; } else if (strcmp(k, "ssl") == 0) { cfg->ETYPE = ENC_SSL; } else if (strcmp(k, CFG_CIPHERS) == 0) { if (v != NULL && strlen(v) > 0) { config_assign_str(&cfg->CIPHER_SUITE, v); } } else if (strcmp(k, CFG_SSL_ENGINE) == 0) { if (v != NULL && strlen(v) > 0) { config_assign_str(&cfg->ENGINE, v); } } else if (strcmp(k, CFG_PREFER_SERVER_CIPHERS) == 0) { r = config_param_val_bool(v, &cfg->PREFER_SERVER_CIPHERS); } else if (strcmp(k, CFG_FRONTEND) == 0) { r = config_param_host_port_wildcard(v, &cfg->FRONT_IP, &cfg->FRONT_PORT, 1); } else if (strcmp(k, CFG_BACKEND) == 0) { r = config_param_host_port(v, &cfg->BACK_IP, &cfg->BACK_PORT); } else if (strcmp(k, CFG_WORKERS) == 0) { r = config_param_val_intl_pos(v, &cfg->NCORES); } else if (strcmp(k, CFG_BACKLOG) == 0) { r = config_param_val_int(v, &cfg->BACKLOG); if (r && cfg->BACKLOG < -1) cfg->BACKLOG = -1; } else if (strcmp(k, CFG_KEEPALIVE) == 0) { r = config_param_val_int_pos(v, &cfg->TCP_KEEPALIVE_TIME); } #ifdef USE_SHARED_CACHE else if (strcmp(k, CFG_SHARED_CACHE) == 0) { r = config_param_val_int(v, &cfg->SHARED_CACHE); } else if (strcmp(k, CFG_SHARED_CACHE_LISTEN) == 0) { if (v != NULL && strlen(v) > 0) r = config_param_host_port_wildcard(v, &cfg->SHCUPD_IP, &cfg->SHCUPD_PORT, 1); } else if (strcmp(k, CFG_SHARED_CACHE_PEER) == 0) { r = config_param_shcupd_peer(v, cfg); } else if (strcmp(k, CFG_SHARED_CACHE_MCASTIF) == 0) { r = config_param_shcupd_mcastif(v, &cfg->SHCUPD_MCASTIF, &cfg->SHCUPD_MCASTTTL); } #endif else if (strcmp(k, CFG_CHROOT) == 0) { if (v != NULL && strlen(v) > 0) { // check directory if (stat(v, &st) != 0) { config_error_set("Unable to stat directory '%s': %s'.", v, strerror(errno)); r = 0; } else { if (! S_ISDIR(st.st_mode)) { config_error_set("Bad chroot directory '%s': Not a directory.", v, strerror(errno)); r = 0; } else { config_assign_str(&cfg->CHROOT, v); } } } } else if (strcmp(k, CFG_USER) == 0) { if (v != NULL && strlen(v) > 0) { struct passwd *passwd; passwd = getpwnam(v); if (!passwd) { config_error_set("Invalid user '%s'.", v); r = 0; } else { cfg->UID = passwd->pw_uid; cfg->GID = passwd->pw_gid; } } } else if (strcmp(k, CFG_GROUP) == 0) { if (v != NULL && strlen(v) > 0) { struct group *grp; grp = getgrnam(v); if (!grp) { config_error_set("Invalid group '%s'.", v); r = 0; } else { cfg->GID = grp->gr_gid; } } } else if (strcmp(k, CFG_QUIET) == 0) { r = config_param_val_bool(v, &cfg->QUIET); } else if (strcmp(k, CFG_SYSLOG) == 0) { r = config_param_val_bool(v, &cfg->SYSLOG); } else if (strcmp(k, CFG_SYSLOG_FACILITY) == 0) { r = 1; if (!strcmp(v, "auth") || !strcmp(v, "authpriv")) cfg->SYSLOG_FACILITY = LOG_AUTHPRIV; else if (!strcmp(v, "cron")) cfg->SYSLOG_FACILITY = LOG_CRON; else if (!strcmp(v, "daemon")) cfg->SYSLOG_FACILITY = LOG_DAEMON; else if (!strcmp(v, "ftp")) cfg->SYSLOG_FACILITY = LOG_FTP; else if (!strcmp(v, "local0")) cfg->SYSLOG_FACILITY = LOG_LOCAL0; else if (!strcmp(v, "local1")) cfg->SYSLOG_FACILITY = LOG_LOCAL1; else if (!strcmp(v, "local2")) cfg->SYSLOG_FACILITY = LOG_LOCAL2; else if (!strcmp(v, "local3")) cfg->SYSLOG_FACILITY = LOG_LOCAL3; else if (!strcmp(v, "local4")) cfg->SYSLOG_FACILITY = LOG_LOCAL4; else if (!strcmp(v, "local5")) cfg->SYSLOG_FACILITY = LOG_LOCAL5; else if (!strcmp(v, "local6")) cfg->SYSLOG_FACILITY = LOG_LOCAL6; else if (!strcmp(v, "local7")) cfg->SYSLOG_FACILITY = LOG_LOCAL7; else if (!strcmp(v, "lpr")) cfg->SYSLOG_FACILITY = LOG_LPR; else if (!strcmp(v, "mail")) cfg->SYSLOG_FACILITY = LOG_MAIL; else if (!strcmp(v, "news")) cfg->SYSLOG_FACILITY = LOG_NEWS; else if (!strcmp(v, "user")) cfg->SYSLOG_FACILITY = LOG_USER; else if (!strcmp(v, "uucp")) cfg->SYSLOG_FACILITY = LOG_UUCP; else { config_error_set("Invalid facility '%s'.", v); r = 0; } } else if (strcmp(k, CFG_DAEMON) == 0) { r = config_param_val_bool(v, &cfg->DAEMONIZE); } else if (strcmp(k, CFG_WRITE_IP) == 0) { r = config_param_val_bool(v, &cfg->WRITE_IP_OCTET); } else if (strcmp(k, CFG_WRITE_PROXY) == 0) { r = config_param_val_bool(v, &cfg->WRITE_PROXY_LINE); } else if (strcmp(k, CFG_PROXY_PROXY) == 0) { r = config_param_val_bool(v, &cfg->PROXY_PROXY_LINE); } else if (strcmp(k, CFG_PEM_FILE) == 0) { printf( "strcmp %s\n", k ); if (v != NULL && strlen(v) > 0) { if (stat(v, &st) != 0) { config_error_set("Unable to stat x509 certificate PEM file '%s': ", v, strerror(errno)); r = 0; } else if (! S_ISREG(st.st_mode)) { config_error_set("Invalid x509 certificate PEM file '%s': Not a file.", v); r = 0; } else { struct cert_files *cert = calloc(1, sizeof(*cert)); config_assign_str(&cert->CERT_FILE, v); cert->NEXT = cfg->CERT_FILES; cfg->CERT_FILES = cert; } } } else { fprintf( stderr, "Ignoring unknown configuration key '%s' in configuration file '%s', line %d\n", k, file, line ); } if (! r) { if (file != NULL) config_die("Error in configuration file '%s', line %d: %s\n", file, line, config_error_get()); else config_die("Invalid parameter '%s': %s", k, config_error_get()); } }
int config_param_shcupd_peer (char *str, stud_config *cfg) { if (cfg == NULL) { config_error_set("Configuration pointer is NULL."); return 0; } // parse result int r = 1; // find place for new peer int offset = 0; int i = 0; for (i = 0; i < MAX_SHCUPD_PEERS; i++) { if (cfg->SHCUPD_PEERS[i].ip == NULL && cfg->SHCUPD_PEERS[i].port == NULL) { offset = i; break; } } if (i >= MAX_SHCUPD_PEERS) { config_error_set( "Reached maximum number of shared cache update peers (%d).", MAX_SHCUPD_PEERS ); return 0; } // create place for new peer char *addr = malloc(ADDR_LEN); if (addr == NULL) { config_error_set( "Unable to allocate memory for new shared cache update peer address: %s", strerror(errno) ); r = 0; goto outta_parse_peer; } memset(addr, '\0', ADDR_LEN); char *port = malloc(PORT_LEN); if (port == NULL) { config_error_set( "Unable to allocate memory for new shared cache update peer port: %s", strerror(errno) ); r = 0; goto outta_parse_peer; } memset(port, '\0', PORT_LEN); // try to parse address if (! config_param_host_port(str, &addr, &port)) { r = 0; goto outta_parse_peer; } outta_parse_peer: if (! r) { if (addr != NULL) free(addr); if (port != NULL) free(port); } else { cfg->SHCUPD_PEERS[offset].ip = addr; cfg->SHCUPD_PEERS[offset].port = port; } return r; }
int config_param_host_port_wildcard (char *str, char **addr, char **port, int wildcard_okay) { int len = (str != NULL) ? strlen(str) : 0; if (str == NULL || ! len) { config_error_set("Invalid/unset host/port string."); return 0; } // address/port buffers char port_buf[PORT_LEN]; char addr_buf[ADDR_LEN]; memset(port_buf, '\0', sizeof(port_buf)); memset(addr_buf, '\0', sizeof(addr_buf)); // NEW FORMAT: [address]:port if (*str == '[') { char *ptr = str + 1; char *x = strrchr(ptr, ']'); if (x == NULL) { config_error_set("Invalid address '%s'.", str); return 0; } // address memcpy(addr_buf, ptr, (x - ptr)); // port x += 2; memcpy(port_buf, x, sizeof(port_buf) - 1); } // OLD FORMAT: address,port else { char *x = strrchr(str, ','); if (x == NULL) { config_error_set("Invalid address string '%s'", str); return 0; } // addr int addr_len = x - str; memcpy(addr_buf, str, addr_len); // port memcpy(port_buf, (++x), sizeof(port_buf)); } // printf("PARSED ADDR '%s', PORT '%s'\n", addr_buf, port_buf); // check port int p = atoi(port_buf); if (p < 1 || p > 65536) { config_error_set("Invalid port number '%s'", port_buf); return 0; } // write if (strcmp(addr_buf, "*") == 0) { if (wildcard_okay) free(*addr); else { config_error_set("Invalid address: wildcards are not allowed."); return 0; } } else { //if (*addr != NULL) free(*addr); *addr = strdup(addr_buf); } // if (**port != NULL) free(*port); *port = strdup(port_buf); // printf("ADDR FINAL: '%s', '%s'\n", *addr, *port); return 1; }