int sh_readconf_set_path (char * which, const char * what) { int len; SL_ENTER( _("sh_readconf_set_path")); if (which == NULL || what == NULL) { TPT((0, FIL__, __LINE__ , _("msg=<Input error>\n"))); SL_RETURN( -1, _("sh_readconf_set_path")); } if (0 == sl_strcmp(what, _("AUTO"))) { len = sl_strlen(which); if ( (len + sl_strlen(sh.host.name) + 2) > SH_PATHBUF) { TPT((0, FIL__, __LINE__ , _("msg=<Path too large: %s:%s>\n"), which, sh.host.name)); SL_RETURN( -1, _("sh_readconf_set_path")); } else { which[len] = ':'; which[len+1] = '\0'; sl_strlcat(which, sh.host.name, SH_PATHBUF); } } else /* not auto */ { if (sl_strlen(what) > (SH_PATHBUF-1)) { TPT((0, FIL__, __LINE__ , _("msg=<Path too large: %s>\n"), what)); SL_RETURN( -1, _("sh_readconf_set_path")); } else { sl_strlcpy(which, what, SH_PATHBUF); } } SL_RETURN( 0, _("sh_readconf_set_path")); }
int sh_prelink_set_hash (const char * str) { size_t len; SL_ENTER(_("sh_prelink_set_hash")); if (prelink_hash != NULL) SH_FREE(prelink_hash); len = sl_strlen (str); if (len != KEY_LEN) { prelink_hash = NULL; SL_RETURN((-1), _("sh_prelink_set_hash")); } prelink_hash = SH_ALLOC(len+1); (void) sl_strlcpy(prelink_hash, str, len+1); SL_RETURN(0, _("sh_prelink_set_hash")); }
/* --- Read the configuration file. --- */ int sh_readconf_read (void) { #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) /* This is for modules. */ int modnum; #endif int i; SL_TICKET fd = -1; #if defined(SH_STEALTH) && !defined(SH_STEALTH_MICRO) SL_TICKET fdTmp = -1; #endif #if defined(WITH_GPG) || defined(WITH_PGP) SL_TICKET fdGpg = -1; #endif char * tmp; #define SH_LINE_IN 16384 char * line_in; char * line; /* This is for nested conditionals. */ int cond_depth = 0; int cond_excl = 0; int local_file = 1; char local_flag = 'R'; #if defined(WITH_GPG) || defined(WITH_PGP) int signed_content = S_FALSE; int true_content = S_FALSE; #endif #if defined(SH_STEALTH) && !defined(SH_STEALTH_MICRO) int hidden_count = 0; #endif uid_t euid; char hashbuf[KEYBUF_SIZE]; SL_ENTER(_("sh_readconf_read")); /* --- Open config file, exit on failure. --- */ #if defined(SH_WITH_CLIENT) if (0 == sl_strcmp(file_path('C', 'R'), _("REQ_FROM_SERVER"))) { sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_D_START); fd = sh_forward_req_file(_("CONF")); if (!SL_ISERROR(fd)) { local_file = 0; } else if (sh.flag.checkSum != SH_CHECK_INIT) { aud_exit (FIL__, __LINE__, EXIT_FAILURE); } else { sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_D_FAIL); local_file = 1; local_flag = 'I'; } } #endif /* Use a local configuration file. */ if (local_file == 1) { if (0 != tf_trust_check (file_path('C', local_flag), SL_YESPRIV)) { sl_get_euid(&euid); dlog(1, FIL__, __LINE__, _("The configuration file: %s is untrusted, i.e. an\nuntrusted user owns or can write to some directory in the path.\n"), ( (NULL == file_path('C', local_flag)) ? _("(null)") : file_path('C', local_flag) )); sh_error_handle ((-1), FIL__, __LINE__, EACCES, MSG_TRUST, (long) euid, ( (NULL == file_path('C', local_flag)) ? _("(null)") : file_path('C', local_flag) ) ); aud_exit (FIL__, __LINE__, EXIT_FAILURE); } if (SL_ISERROR(fd = sl_open_read(FIL__, __LINE__, file_path('C',local_flag),SL_YESPRIV))) { sl_get_euid(&euid); dlog(1, FIL__, __LINE__, _("Could not open the local configuration file for reading because\nof the following error: %s (errnum = %ld)\nIf this is a permission problem, you need to change file permissions\nto make the file readable for the effective UID: %d\n"), sl_get_errmsg(), fd, (int) euid); sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_NOACCESS, (long) euid, ( (NULL == file_path('C', local_flag)) ? _("(null)") : file_path('C', local_flag) ) ); aud_exit (FIL__, __LINE__, EXIT_FAILURE); } } /* Compute the checksum of the open file. */ sl_strlcpy(sh.conf.hash, sh_tiger_hash(file_path('C',local_flag), fd, TIGER_NOLIM, hashbuf, sizeof(hashbuf)), KEY_LEN+1); sl_rewind (fd); line_in = SH_ALLOC(SH_LINE_IN); #if defined(SH_STEALTH) && !defined(SH_STEALTH_MICRO) /* extract the data and copy to temporary file */ fdTmp = open_tmp(); sh_unix_getline_stealth (0, NULL, 0); /* initialize */ while ( sh_unix_getline_stealth (fd, line_in, SH_LINE_IN-2) > 0) { hidden_count++; if (line_in[0] == '\n') { sl_write(fdTmp, line_in, 1); } else { sl_write_line(fdTmp, line_in, sl_strlen(line_in)); } #if defined(WITH_GPG) || defined(WITH_PGP) if (0 == sl_strncmp(line_in, _("-----END PGP SIGNATURE-----"), 25)) break; #else if (0 == sl_strncmp(line_in, _("[EOF]"), 5)) break; #endif if (hidden_count > 1048576) /* arbitrary safeguard, 1024*1024 */ break; } sl_close(fd); fd = fdTmp; sl_rewind (fd); #endif #if defined(WITH_GPG) || defined(WITH_PGP) /* extract the data and copy to temporary file */ fdGpg = sh_gpg_extract_signed(fd); sl_close(fd); fd = fdGpg; /* Validate signature of open file. */ if (0 != sh_gpg_check_sign (fd, 0, 1)) { SH_FREE(line_in); aud_exit (FIL__, __LINE__, EXIT_FAILURE); } sl_rewind (fd); #endif /* --- Start reading lines. --- */ conf_line = 0; while ( sh_unix_getline (fd, line_in, SH_LINE_IN-2) > 0) { ++conf_line; line = &(line_in[0]); /* fprintf(stderr, "<%s>\n", line); */ /* Sun May 27 18:40:05 CEST 2001 */ #if defined(WITH_GPG) || defined(WITH_PGP) if (signed_content == S_FALSE) { if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNED MESSAGE-----"))) signed_content = S_TRUE; else continue; } else if (true_content == S_FALSE) { if (line[0] == '\n') true_content = S_TRUE; else continue; } else if (signed_content == S_TRUE) { if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNATURE-----"))) break; else if (0 == sl_strcmp(line, _("-----BEGIN PGP SIGNED MESSAGE-----"))) { sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, _("second signed message in file"), _("sh_readconf_read")); dlog(1, FIL__, __LINE__, _("There seems to be more than one signed message in the configuration\nfile. Please make sure there is only one signed message.\n")); sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EXIT_ABORT1, sh.prg_name); SH_FREE(line_in); aud_exit (FIL__, __LINE__,EXIT_FAILURE); } } #endif /* Skip leading white space. */ while (isspace((int)*line)) ++line; /* Skip header etc. */ if (line[0] == '#' || line[0] == '\0' || line[0] == ';' || (line[0] == '/' && line[1] == '/')) continue; /* Clip off trailing white space. */ tmp = line + sl_strlen( line ); --tmp; while( isspace((int) *tmp ) && tmp >= line ) *tmp-- = '\0'; /* --- an @host/@if/$system directive -------------- */ if (line[0] == '@' || (line[0] == '!' && line[1] == '@') || line[0] == '$' || (line[0] == '!' && line[1] == '$')) { if (sh_readconf_is_end(line)) { if (0 == cond_depth) { sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALD, _("config file"), (long) conf_line); } else { if (cond_excl == cond_depth) cond_excl = 0; --cond_depth; } } else if (sh_readconf_is_else(line)) { if (0 == cond_depth) { sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALD, _("config file"), (long) conf_line); } else if (cond_excl == cond_depth) { cond_excl = 0; } else if (cond_excl == 0) { cond_excl = cond_depth; } } else { if (sh_readconf_cond_match(line, conf_line)) { ++cond_depth; } else { ++cond_depth; if (cond_excl == 0) cond_excl = cond_depth; } } continue; } /**************************************************** * * Only carry on if this section is intended for us * ****************************************************/ if (cond_excl != 0) { continue; } /* ------- starts a section ------------ */ else if (line[0] == '[') { read_mode = SH_SECTION_NONE; if (0 == sl_strncasecmp (line, _("[EOF]"), 5)) { goto nopel; } i = 0; while (tab_ListSections[i].name != 0) { if (sl_strncasecmp (line, _(tab_ListSections[i].name), sl_strlen(tab_ListSections[i].name)) == 0) { read_mode = tab_ListSections[i].type; break; } ++i; } #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) if (read_mode == SH_SECTION_NONE) { for (modnum = 0; modList[modnum].name != NULL; ++modnum) { if (0 == sl_strncasecmp (line, _(modList[modnum].conf_section), sl_strlen(modList[modnum].conf_section)) ) read_mode = SH_SECTION_OTHER; } } #endif if (read_mode == SH_SECTION_NONE) { sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALHEAD, (long) conf_line); } } /* --- an %schedule directive ------------ */ else if (line[0] == '%' || (line[0] == '!' && line[1] == '%')) { #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) if (line[0] == '!' && 0 == sl_strcasecmp(&(line[2]), _("SCHEDULE_TWO"))) set_dirList(1); else if (0 == sl_strcasecmp(&(line[1]), _("SCHEDULE_TWO"))) set_dirList(2); #else ; #endif } /* ------ no new section -------------- */ else if (read_mode != SH_SECTION_NONE) { if (0 != sh_readconfig_line (line)) { sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALCONF, (long) conf_line); } } } /* while getline() */ nopel: if (0 != cond_depth) sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALDD, _("config file"), (long) conf_line); sl_close (fd); sh_error_fixup(); read_mode = SH_SECTION_NONE; /* reset b/o sighup reload */ SH_FREE(line_in); SL_RETURN( 0, _("sh_readconf_read")); }
static int sh_readconfig_line (char * line) { char * key; const char * value; char * tmp; int i; int good_opt = -1; #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) int modnum, modkey; #endif static const char *dummy = N_("dummy"); static const char *closing[] = { N_("closecommand"), N_("closeaddress"), N_("logmonendgroup"), N_("logmonendhost"), NULL }; static const char *ident[] = { N_("severityreadonly"), N_("severitylogfiles"), N_("severitygrowinglogs"), N_("severityignorenone"), N_("severityignoreall"), N_("severityattributes"), N_("severitydirs"), N_("severityfiles"), N_("severitynames"), N_("severityuser0"), N_("severityuser1"), N_("severityuser2"), N_("severityuser3"), N_("severityuser4"), N_("severityprelink"), NULL }; static int identnum[] = { SH_ERR_T_RO, SH_ERR_T_LOGS, SH_ERR_T_GLOG, SH_ERR_T_NOIG, SH_ERR_T_ALLIG, SH_ERR_T_ATTR, SH_ERR_T_DIR, SH_ERR_T_FILE, SH_ERR_T_NAME, SH_ERR_T_USER0, SH_ERR_T_USER1, SH_ERR_T_USER2, SH_ERR_T_USER3, SH_ERR_T_USER4, SH_ERR_T_PRELINK, }; SL_ENTER(_("sh_readconf_line")); /* convert to lowercase */ tmp = line; while (*tmp != '=' && *tmp != '\0') { *tmp = tolower( (int) *tmp); ++tmp; } key = line; /* interpret line */ value = strchr(line, '='); if (value == NULL || (*value) == '\0') { if (key != NULL) { i = 0; while (closing[i] != NULL) { if (sl_strncmp(key,_(closing[i]),sl_strlen(closing[i])-1) == 0) { value = dummy; goto ok_novalue; } ++i; } TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: not key=value: %s>\n"), line)); } SL_RETURN(good_opt, _("sh_readconf_line")); } else ++value; /* skip leading whitespace */ while ((*value) == ' ' || (*value) == '\t') ++value; if ((*value) == '\0') /* no value */ { if (key != NULL) { TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: not key=value: %s>\n"), line)); } SL_RETURN(good_opt, _("sh_readconf_line")); } ok_novalue: if (!sl_is_suid()) { TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: %s>\n"), line)); } /* Expand shell expressions. This return allocated memory which we must free. * If !defined(SH_EVAL_SHELL), this will reduce to a strdup. */ value = sh_readconf_expand_value(value); if (!value || (*value) == '\0') { TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: empty after shell expansion: %s>\n"), line)); SL_RETURN(good_opt, _("sh_readconf_line")); } #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) if (read_mode == SH_SECTION_OTHER) { for (modnum = 0; modList[modnum].name != NULL; ++modnum) { for (modkey = 0; modList[modnum].conf_table[modkey].the_opt != NULL; ++modkey) { if (sl_strncmp (key, _(modList[modnum].conf_table[modkey].the_opt), sl_strlen(modList[modnum].conf_table[modkey].the_opt) ) == 0) { good_opt = 0; if (0 != modList[modnum].conf_table[modkey].func(value)) sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALS, _(modList[modnum].conf_table[modkey].the_opt), value); if (!sl_is_suid()) { TPT(( 0, FIL__, __LINE__, _("msg=<line = %s, option = %s>\n"), line, _(modList[modnum].conf_table[modkey].the_opt))); } goto outburst; } } } } outburst: #endif if (read_mode == SH_SECTION_THRESHOLD) { i = 0; while (ident[i] != NULL) { if (sl_strncmp (key, _(ident[i]), sl_strlen(ident[i])) == 0) { good_opt = 0; sh_error_set_iv (identnum[i], value); break; } ++i; } } else { i = 0; while (ext_table[i].optname != NULL) { if ((ext_table[i].section == read_mode || ext_table[i].alt_section == read_mode) && sl_strncmp (key, _(ext_table[i].optname), sl_strlen(ext_table[i].optname)) == 0) { good_opt = 0; if (0 != ext_table[i].func (value)) sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_EINVALS, _(ext_table[i].optname), value); break; } ++i; } } SH_FREE((char*)value); SL_RETURN(good_opt, _("sh_readconf_line")); }