int main(int ac, char **av) { if (!av[1]) printf("need config file\n"), exit(1); if (parse_config_file(av[1]) < 0) printf("cannot parse config file\n"), exit(1); char *type; char *header; char *name; int n; while (scanf("%as %as %as", &type, &header, &name) == 3) { switch (type[0]) { case 'n': if (config_number(header, name, "%d", &n) < 0) printf("Cannot parse number %s %s\n", header, name); else printf("res %d\n", n); break; case 's': printf("res %s\n", config_string(header, name)); break; case 'b': printf("res %d\n", config_bool(header, name)); break; default: printf("unknown type %s\n", type); break; } free(type); free(header); free(name); } return 0; }
static BOOL STDCALL _main_console_handler(DWORD control_type) { const char* control_name = "UNKNOWN"; bool post_terminate = false; bool handled = true; switch (control_type) { case CTRL_C_EVENT: control_name = "CTRL_C"; post_terminate = true; break; case CTRL_BREAK_EVENT: control_name = "CTRL_BREAK"; break; case CTRL_CLOSE_EVENT: control_name = "CTRL_CLOSE"; post_terminate = true; break; case CTRL_LOGOFF_EVENT: control_name = "CTRL_LOGOFF"; post_terminate = !config_bool(HASH_APPLICATION, HASH_DAEMON); break; case CTRL_SHUTDOWN_EVENT: control_name = "CTRL_SHUTDOWN"; post_terminate = true; break; default: handled = false; break; } log_infof(0, STRING_CONST("Caught console control: %s (%d)"), control_name, control_type); if (post_terminate) { /*lint -e{970} */ unsigned long level = 0, flags = 0; system_post_event(FOUNDATIONEVENT_TERMINATE); GetProcessShutdownParameters(&level, &flags); SetProcessShutdownParameters(level, SHUTDOWN_NORETRY); thread_sleep(1000); } return handled; }
static int config_bool(snd_config_t *n, int doit) { const char *str; long val; long long lval; switch (snd_config_get_type(n)) { case SND_CONFIG_TYPE_INTEGER: snd_config_get_integer(n, &val); if (val < 0 || val > 1) return -1; return val; case SND_CONFIG_TYPE_INTEGER64: snd_config_get_integer64(n, &lval); if (lval < 0 || lval > 1) return -1; return (int) lval; case SND_CONFIG_TYPE_STRING: snd_config_get_string(n, &str); break; case SND_CONFIG_TYPE_COMPOUND: if (!force_restore || !doit) return -1; n = snd_config_iterator_entry(snd_config_iterator_first(n)); return config_bool(n, doit); default: return -1; } if (strcmp(str, "on") == 0 || strcmp(str, "true") == 0) return 1; if (strcmp(str, "off") == 0 || strcmp(str, "false") == 0) return 0; return -1; }
static void client_srv_passive(char *arg) { int h1, h2, h3, h4, p1, p2; u_int32_t addr, ladr; u_int16_t port; int incr; if (arg == NULL) /* Basic sanity check */ return; /* ** Read the port. According to RFC 1123, 4.1.2.6, ** we have to scan the string for the first digit. */ while (*arg < '0' || *arg > '9') arg++; if (sscanf(arg, "%d,%d,%d,%d,%d,%d", &h1, &h2, &h3, &h4, &p1, &p2) != 6) { syslog_error("bad PASV 277 response from server for %s", ctx.cli_ctrl->peer); client_respond(425, NULL, "Can't open data connection"); client_data_reset(MOD_RESET); ctx.expect = EXP_IDLE; return; } addr = (u_int32_t) ((h1 << 24) + (h2 << 16) + (h3 << 8) + h4); port = (u_int16_t) ((p1 << 8) + p2); syslog_write(T_DBG, "got SRV-PASV %s:%d for %s:%d", socket_addr2str(addr), port, ctx.cli_ctrl->peer, ctx.cli_ctrl->port); /* ** should we bind a rand(port-range) or increment? */ incr = !config_bool(NULL,"SockBindRand", 0); /* ** Open a connection to the server at the given port */ ladr = socket_sck2addr(ctx.srv_ctrl->sock, LOC_END, NULL); if (socket_d_connect(addr, port, ladr, ctx.srv_lrng, ctx.srv_urng, &(ctx.srv_data), "Srv-Data", incr) == 0) { syslog_error("can't connect Srv-Data for %s", ctx.cli_ctrl->peer); client_respond(425, NULL, "Can't open data connection"); client_data_reset(MOD_RESET); ctx.expect = EXP_IDLE; return; } /* ** Finally send the original command from the client */ client_xfer_fireup(); }
/* Use getopt_long struct option array to process config file */ void config_options(struct option *opts, int (*func)(int)) { for (; opts->name; opts++) { if (!opts->has_arg) { if (config_bool("global", opts->name) != 1) continue; if (opts->flag) { *(opts->flag) = opts->val; continue; } } else { char *s = config_string("global", opts->name); if (s == NULL) continue; optarg = s; } func(opts->val); } }
int main(__unused int argc, char *argv[]) { char pkgpath[MAXPATHLEN]; bool yes = false; snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg", getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE); if (access(pkgpath, X_OK) == -1) { /* * To allow 'pkg -N' to be used as a reliable test for whether * a system is configured to use pkg, don't bootstrap pkg * when that argument is given as argv[1]. */ if (argv[1] != NULL && strcmp(argv[1], "-N") == 0) errx(EXIT_FAILURE, "pkg is not installed"); /* * Do not ask for confirmation if either of stdin or stdout is * not tty. Check the environment to see if user has answer * tucked in there already. */ config_init(); config_bool(ASSUME_ALWAYS_YES, &yes); if (!yes) { printf("%s", confirmation_message); if (!isatty(fileno(stdin))) exit(EXIT_FAILURE); if (pkg_query_yes_no() == 0) exit(EXIT_FAILURE); } if (bootstrap_pkg() != 0) exit(EXIT_FAILURE); config_finish(); } execv(pkgpath, argv); /* NOT REACHED */ return (EXIT_FAILURE); }
int config_trigger(const char *header, const char *base, struct bucket_conf *bc) { char *s; char *name; int n; asprintf(&name, "%s-threshold", base); s = config_string(header, name); if (s) { if (bucket_conf_init(bc, s) < 0) { unparseable("trigger", header, name); return -1; } } free(name); asprintf(&name, "%s-trigger", base); s = config_string(header, name); if (s) { /* no $PATH */ if (trigger_check(s) != 0) { SYSERRprintf("Trigger `%s' not executable\n", s); exit(1); } bc->trigger = s; } free(name); bc->log = 0; asprintf(&name, "%s-log", base); n = config_bool(header, name); if (n >= 0) bc->log = n; free(name); return 0; }
static void client_xfer_fireup(void) { u_int32_t ladr = INADDR_ANY; int incr; /* ** should we bind a rand(port-range) or increment? */ incr = !config_bool(NULL,"SockBindRand", 0); /* ** If appropriate, connect to the client's data port */ if (ctx.cli_mode == MOD_ACT_FTP) { /* ** TransProxy mode: check if we can use our real ** ip instead of the server's one as our local ip, ** we pre-bind the socket/ports to before connect. */ if(config_bool(NULL, "AllowTransProxy", 0)) { ladr = config_addr(NULL, "Listen", (u_int32_t)INADDR_ANY); } if(INADDR_ANY == ladr) { ladr = socket_sck2addr(ctx.cli_ctrl->sock, LOC_END, NULL); } if (socket_d_connect(ctx.cli_addr, ctx.cli_port, ladr, ctx.act_lrng, ctx.act_urng, &(ctx.cli_data), "Cli-Data", incr) == 0) { syslog_error("can't connect Cli-Data for %s", ctx.cli_ctrl->peer); client_respond(425, NULL, "Can't open data connection"); client_data_reset(MOD_RESET); ctx.expect = EXP_IDLE; return; } } /* ** Send the original command from the client */ if (ctx.xfer_arg[0] != '\0') { socket_printf(ctx.srv_ctrl, "%s %s\r\n", ctx.xfer_cmd, ctx.xfer_arg); syslog_write(T_INF, "'%s %s' sent for %s", ctx.xfer_cmd, ctx.xfer_arg, ctx.cli_ctrl->peer); } else { socket_printf(ctx.srv_ctrl, "%s\r\n", ctx.xfer_cmd); syslog_write(T_INF, "'%s' sent for %s", ctx.xfer_cmd, ctx.cli_ctrl->peer); } /* ** Prepare the handling and statistics buffers */ memset(ctx.xfer_rep, 0, sizeof(ctx.xfer_rep)); ctx.xfer_beg = time(NULL); ctx.expect = EXP_XFER; /* Expect 226 complete */ }
static void client_srv_ctrl_read(char *str) { int code, c1, c2, c3; char *arg; if (str == NULL) /* Basic sanity check */ return; syslog_write(T_DBG, "from Server-PI (%d): '%.512s'", ctx.srv_ctrl->sock, str); #if defined(COMPILE_DEBUG) debug(1, "from Server-PI (%d): '%.512s'", ctx.srv_ctrl->sock, str); #endif /* ** Intermediate responses can usually be forwarded */ if (*str < '2' || *str > '5' || str[3] != ' ') { /* ** If this is the destination host's ** welcome message let's discard it. */ if (ctx.expect == EXP_CONN) return; if (ctx.expect == EXP_USER && UAUTH_NONE != ctx.auth_mode) return; #if defined(COMPILE_DEBUG) debug(2, "'%.4s'... forwarded to %s %d=%s", str, ctx.cli_ctrl->ctyp, ctx.cli_ctrl->sock, ctx.cli_ctrl->peer); #endif socket_printf(ctx.cli_ctrl, "%s\r\n", str); return; } /* ** Consider only valid final response codes */ if ((code = atoi(str)) < 200 || code > 599) { syslog_error("bad response %d from server for %s", code, ctx.srv_ctrl->peer); return; } c1 = code / 100; c2 = (code % 100) / 10; c3 = code % 10; for (arg = str + 3; *arg == ' '; arg++) ; /* ** We have a response code, go see what we expected */ switch (ctx.expect) { case EXP_CONN: /* ** Waiting for a 220 Welcome */ if (c1 == 2) { socket_printf(ctx.srv_ctrl, "USER %s\r\n", ctx.username); ctx.expect = EXP_USER; } else { if(UAUTH_NONE != ctx.auth_mode) { client_respond(530, NULL, "Login incorrect"); } else { socket_printf(ctx.cli_ctrl, "%s\r\n", str); } ctx.expect = EXP_IDLE; ctx.cli_ctrl->kill = 1; } break; case EXP_USER: /* ** Only the following codes are useful: ** 230=logged in, ** 331=need password, ** 332=need password+account */ if(UAUTH_NONE != ctx.auth_mode) { /* ** logged in, NO password needed */ if(c1 == 2 && c2 == 3) { client_respond(230, NULL, "User logged in, proceed."); ctx.expect = EXP_IDLE; break; } else /* ** OK, password (+account) needed */ if(c1 == 3 && c2 == 3) { if(ctx.userpass) { socket_printf(ctx.srv_ctrl, "PASS %s\r\n", ctx.userpass); misc_free(FL, ctx.userpass); ctx.userpass = NULL; } else { socket_printf(ctx.srv_ctrl, "PASS \r\n"); } ctx.expect = EXP_PTHR; break; } } /* ** pass server response through to client */ socket_printf(ctx.cli_ctrl, "%s\r\n", str); if (c1 != 2 && c1 != 3) { ctx.cli_ctrl->kill = 1; } ctx.expect = EXP_IDLE; break; case EXP_ABOR: if (c1 == 2) { client_data_reset(MOD_RESET); ctx.expect = EXP_IDLE; } break; case EXP_PASV: if (code == 227 && *arg != '\0') { client_srv_passive(arg); } else { socket_printf(ctx.cli_ctrl, "%s\r\n", str); client_data_reset(MOD_RESET); ctx.expect = EXP_IDLE; } break; case EXP_PORT: if (code == 200) { client_xfer_fireup(); } else { socket_printf(ctx.cli_ctrl, "%s\r\n", str); client_data_reset(MOD_RESET); ctx.expect = EXP_IDLE; } break; case EXP_XFER: /* ** Distinguish between success and failure */ if (c1 == 2) { misc_strncpy(ctx.xfer_rep, str, sizeof(ctx.xfer_rep)); } else { socket_printf(ctx.cli_ctrl, "%s\r\n", str); if(config_bool(NULL,"FailResetsPasv", 0)) { client_data_reset(MOD_RESET); } else { client_data_reset(ctx.cli_mode); } } ctx.expect = EXP_IDLE; break; case EXP_PTHR: socket_printf(ctx.cli_ctrl, "%s\r\n", str); ctx.expect = EXP_IDLE; break; case EXP_IDLE: socket_printf(ctx.cli_ctrl, "%s\r\n", str); if (code == 421) { syslog_write(T_WRN, "server closed connection " "for %s", ctx.cli_ctrl->peer); ctx.cli_ctrl->kill = 1; } else { syslog_write(T_WRN, "bogus '%.512s' from " "Server-PI for %s", ctx.cli_ctrl->peer, str); } break; } }
static int client_setup_file(CONTEXT *ctx, char *who) { char *p; u_int16_t l, u; /* ** little bit sanity check */ if( !(ctx && who && *who)) { return -1; } /* ** Inform the auditor that we are using the config file */ syslog_write(U_INF, "reading data for '%s' from cfg-file", who); /* ** Evaluate DestinationAddress, except we have magic_addr */ if (INADDR_ANY != ctx->magic_addr) { ctx->srv_addr = ctx->magic_addr; } else { ctx->srv_addr = config_addr(who, "DestinationAddress", INADDR_ANY); #if defined(COMPILE_DEBUG) debug(2, "file DestAddr for %s: '%s'", ctx->cli_ctrl->peer, socket_addr2str(ctx->srv_addr)); #endif } /* ** Evaluate DestinationPort, except we have magic_port */ if (INPORT_ANY != ctx->magic_port) { ctx->srv_port = ctx->magic_port; } else { ctx->srv_port = config_port(who, "DestinationPort", IPPORT_FTP); #if defined(COMPILE_DEBUG) debug(2, "file DestPort for %s: %d", ctx->cli_ctrl->peer, (int) ctx->srv_port); #endif } /* ** Evaluate the destination transfer mode */ p = config_str(who, "DestinationTransferMode", "client"); if(0 == strcasecmp(p, "active")) { ctx->srv_mode = MOD_ACT_FTP; } else if(0 == strcasecmp(p, "passive")) { ctx->srv_mode = MOD_PAS_FTP; } else if(0 == strcasecmp(p, "client")) { ctx->srv_mode = MOD_CLI_FTP; } else { syslog_error("can't eval DestMode for %s", ctx->cli_ctrl->peer); return -1; } #if defined(COMPILE_DEBUG) debug(2, "file DestMode for %s: %s", ctx->cli_ctrl->peer, p); #endif /* ** Evaluate min/max destination port range */ l = config_port(who, "DestinationMinPort", INPORT_ANY); u = config_port(who, "DestinationMaxPort", INPORT_ANY); if (l > 0 && u > 0 && u >= l) { ctx->srv_lrng = l; ctx->srv_urng = u; } else { ctx->srv_lrng = INPORT_ANY; ctx->srv_urng = INPORT_ANY; } #if defined(COMPILE_DEBUG) debug(2, "file DestRange for %s: %u-%u", ctx->cli_ctrl->peer, ctx->srv_lrng, ctx->srv_urng); #endif /* ** Evaluate min/max active port range */ l = config_port(who, "ActiveMinDataPort", INPORT_ANY); u = config_port(who, "ActiveMaxDataPort", INPORT_ANY); if (l > 0 && u > 0 && u >= l) { ctx->act_lrng = l; ctx->act_urng = u; } else { /* do not try to bind a port < 1024 if running as UID != 0 */ if(0 == getuid()) { ctx->act_lrng = (IPPORT_FTP - 1); ctx->act_urng = (IPPORT_FTP - 1); } else { ctx->act_lrng = INPORT_ANY; ctx->act_urng = INPORT_ANY; } } #if defined(COMPILE_DEBUG) debug(2, "file ActiveRange for %s: %u-%u", ctx->cli_ctrl->peer, ctx->act_lrng, ctx->act_urng); #endif /* ** Evaluate min/max passive port range */ l = config_port(who, "PassiveMinDataPort", INPORT_ANY); u = config_port(who, "PassiveMaxDataPort", INPORT_ANY); if (l > 0 && u > 0 && u >= l) { ctx->pas_lrng = l; ctx->pas_urng = u; } else { ctx->pas_lrng = INPORT_ANY; ctx->pas_urng = INPORT_ANY; } #if defined(COMPILE_DEBUG) debug(2, "file PassiveRange for %s: %u-%u", ctx->cli_ctrl->peer, ctx->pas_lrng, ctx->pas_urng); #endif /* ** Setup other configuration options */ ctx->same_adr = config_bool(who, "SameAddress", 1); ctx->timeout = config_int (who, "TimeOut", 900); #if defined(COMPILE_DEBUG) debug(2, "file SameAddress for %s: %s", ctx->cli_ctrl->peer, ctx->same_adr ? "yes" : "no"); debug(2, "file TimeOut for %s: %d", ctx->cli_ctrl->peer, ctx->timeout); #endif /* ** Adjust the allow/deny flags for the commands */ p = config_str(who, "ValidCommands", NULL); cmds_set_allow(p); return 0; }
void client_run(void) { int sock, need, diff; char str[MAX_PATH_SIZE * 2]; char *p, *q; FILE *fp; BUF *buf; /* ** Setup client signal handling (mostly graceful exit) */ signal(SIGINT, client_signal); signal(SIGTERM, client_signal); signal(SIGQUIT, client_signal); signal(SIGHUP, client_signal); signal(SIGCHLD, SIG_IGN); signal(SIGUSR1, SIG_IGN); /* ** Prepare our general client context */ memset(&ctx, 0, sizeof(ctx)); ctx.sess_beg = time(NULL); ctx.cli_mode = MOD_ACT_FTP; ctx.expect = EXP_IDLE; ctx.timeout = config_int(NULL, "TimeOut", 900); sock = fileno(stdin); /* "recover" our socket */ /* ** Check whether a DenyMessage file exists. This ** indicates that we are currently not willing ** to serve any clients. */ p = config_str(NULL, "DenyMessage", NULL); if (p != NULL && (fp = fopen(p, "r")) != NULL) { while (fgets(str, sizeof(str) - 4, fp) != NULL) { p = socket_msgline(str); if ((q = strchr(p, '\n')) != NULL) strcpy(q, "\r\n"); else strcat(p, "\r\n"); send(sock, "421-", 4, 0); send(sock, p, strlen(p), 0); } fclose(fp); if ((p = config_str(NULL, "DenyString", NULL)) != NULL) p = socket_msgline(p); else p = "Service not available"; send(sock, "421 ", 4, 0); send(sock, p, strlen(p), 0); send(sock, ".\r\n", 3, 0); p = socket_addr2str(socket_sck2addr(sock, REM_END, NULL)); close(sock); syslog_write(U_ERR, "reject: '%s' (DenyMessage)", p); exit(EXIT_SUCCESS); } /* ** Create a High Level Socket for the client's User-PI */ if ((ctx.cli_ctrl = socket_init(sock)) == NULL) misc_die(FL, "client_run: ?cli_ctrl?"); ctx.cli_ctrl->ctyp = "Cli-Ctrl"; /* ** Announce the connection request */ syslog_write(U_INF, "connect from %s", ctx.cli_ctrl->peer); /* ** Display the welcome message (invite the user to login) */ if ((p = config_str(NULL, "WelcomeString", NULL)) == NULL) p = "%h FTP server (Version %v - %b) ready"; misc_strncpy(str, socket_msgline(p), sizeof(str)); client_respond(220, config_str(NULL, "WelcomeMessage", NULL), str); /* ** Enter the client mainloop */ while (close_flag == 0) { /* ** We need to go into select() only ** if all input has been processed ** or ** we wait for more data to get a line ** complete (partially sent, no EOL). ** ** (data buffers are never splited) */ need = 1; if (ctx.cli_ctrl && ctx.cli_ctrl->rbuf) need = 0; if (ctx.srv_ctrl && ctx.srv_ctrl->rbuf) need = 0; if((ctx.cli_ctrl && ctx.cli_ctrl->more>0) || (ctx.srv_ctrl && ctx.srv_ctrl->more>0)) need = 1; /* ** use higher priority to writes; ** read only if nothing to write... */ if(ctx.srv_data && ctx.cli_data) { if(ctx.srv_data->wbuf) { ctx.cli_data->more = -1; } else { ctx.cli_data->more = 0; } if(ctx.cli_data->wbuf) { ctx.srv_data->more = -1; } else { ctx.srv_data->more = 0; } } if (need != 0) { if (socket_exec(ctx.timeout, &close_flag) <= 0) break; /* Timed out or worse */ } #if defined(COMPILE_DEBUG) debug(4, "client-loop ..."); #endif /* ** Check if any zombie sockets can be removed */ if (ctx.cli_ctrl != NULL && ctx.cli_ctrl->sock == -1) close_flag = 1; /* Oops, forget it ... */ if (ctx.srv_ctrl != NULL && ctx.srv_ctrl->sock == -1) { #if defined(COMPILE_DEBUG) debug(3, "about to destroy Srv-Ctrl"); #endif /* ** If we have any open data connections, ** make really sure they don't survive. */ if (ctx.cli_data != NULL) ctx.cli_data->kill = 1; if (ctx.srv_data != NULL) ctx.srv_data->kill = 1; /* ** Our client should be informed */ if (ctx.cli_ctrl->kill == 0) { client_respond(421, NULL, "Service not available, " "closing control connection"); } /* ** Don't forget to remove the dead socket */ socket_kill(ctx.srv_ctrl); ctx.srv_ctrl = NULL; } if (ctx.cli_data != NULL && ctx.cli_data->sock == -1) { #if defined(COMPILE_DEBUG) debug(3, "about to destroy Cli-Data"); #endif /* ** If we have an outstanding server reply ** (e.g. 226 Transfer complete), send it. */ if (ctx.xfer_rep[0] != '\0') { socket_printf(ctx.cli_ctrl, "%s\r\n", ctx.xfer_rep); memset(ctx.xfer_rep, 0, sizeof(ctx.xfer_rep)); } else { if(ctx.expect == EXP_XFER) ctx.expect = EXP_PTHR; } /* ** Good time for statistics and data reset */ if (ctx.xfer_beg == 0) ctx.xfer_beg = time(NULL); diff = (int) (time(NULL) - ctx.xfer_beg); if (diff < 1) diff = 1; /* ** print our current statistic */ syslog_write(U_INF, "Transfer for %s %s: %s '%s' %s %u/%d byte/sec", ctx.cli_ctrl->peer, ctx.cli_data->ernr ? "failed" : "completed", ctx.xfer_cmd, ctx.xfer_arg, ctx.cli_data->rcnt ? "sent" : "read", ctx.cli_data->rcnt ? ctx.cli_data->rcnt : ctx.cli_data->wcnt, diff); /* ** update session statistics data */ if(ctx.cli_data->rcnt) ctx.xfer_rsec += diff; ctx.xfer_rcnt += ctx.cli_data->rcnt; if(ctx.cli_data->wcnt) ctx.xfer_wsec += diff; ctx.xfer_wcnt += ctx.cli_data->wcnt; /* ** reset data transfer state */ client_data_reset(MOD_RESET); /* ** Doom the corresponding server socket */ if (ctx.srv_data != NULL) ctx.srv_data->kill = 1; /* ** Don't forget to remove the dead socket */ socket_kill(ctx.cli_data); ctx.cli_data = NULL; } if (ctx.srv_data != NULL && ctx.srv_data->sock == -1) { #if defined(COMPILE_DEBUG) debug(3, "about to destroy Srv-Data"); #endif /* ** Doom the corresponding client socket if an ** error occured, FailResetsPasv=yes or we ** expect other response than PASV (Netscape!) */ if(ctx.cli_data != NULL) { if(0 != ctx.srv_data->ernr) { ctx.cli_data->ernr = -1; ctx.cli_data->kill = 1; } if(config_bool(NULL,"FailResetsPasv", 0)) { ctx.cli_data->kill = 1; } else if(ctx.expect != EXP_PASV) { ctx.cli_data->kill = 1; } } /* ** Don't forget to remove the dead socket */ socket_kill(ctx.srv_data); ctx.srv_data = NULL; } /* ** Serve the control connections */ if (ctx.cli_ctrl != NULL && ctx.cli_ctrl->rbuf != NULL) { if (socket_gets(ctx.cli_ctrl, str, sizeof(str)) != NULL) client_cli_ctrl_read(str); } if (ctx.srv_ctrl != NULL && ctx.srv_ctrl->rbuf != NULL) { if (socket_gets(ctx.srv_ctrl, str, sizeof(str)) != NULL) client_srv_ctrl_read(str); } /* ** Serve the data connections. This is a bit tricky, ** since all we do is move the buffer pointers. */ if (ctx.cli_data != NULL && ctx.srv_data != NULL) { if (ctx.cli_data->rbuf != NULL) { #if defined(COMPILE_DEBUG) debug(2, "Cli-Data -> Srv-Data"); #endif if (ctx.srv_data->wbuf == NULL) { ctx.srv_data->wbuf = ctx.cli_data->rbuf; } else { for (buf = ctx.srv_data->wbuf; buf && buf->next; buf = buf->next) ; buf->next = ctx.cli_data->rbuf; } ctx.cli_data->rbuf = NULL; } if (ctx.srv_data->rbuf != NULL) { #if defined(COMPILE_DEBUG) debug(2, "Srv-Data -> Cli-Data"); #endif if (ctx.cli_data->wbuf == NULL) { ctx.cli_data->wbuf = ctx.srv_data->rbuf; } else { for (buf = ctx.cli_data->wbuf; buf && buf->next; buf = buf->next) ; buf->next = ctx.srv_data->rbuf; } ctx.srv_data->rbuf = NULL; } } /* at this point the main loop resumes ... */ } /* ** Display basic session statistics... ** in secs since session begin ** downloads / read (xfer-reads from server) ** uploads / send (xfer-sends from server) */ syslog_write(U_INF, "closing connect from %s after %d secs - " "read %d/%d, sent %d/%d byte/sec", ctx.cli_ctrl ? ctx.cli_ctrl->peer : "unknown peer", time(NULL)-ctx.sess_beg, ctx.xfer_wcnt, ctx.xfer_wsec, ctx.xfer_rcnt, ctx.xfer_rsec); /* ** Free allocated memory */ ctx.magic_auth = NULL; if (ctx.userauth != NULL) { misc_free(FL, ctx.userauth); ctx.userauth = NULL; } if (ctx.username != NULL) { misc_free(FL, ctx.username); ctx.username = NULL; } if(ctx.userpass != NULL) { misc_free(FL, ctx.userpass); ctx.userpass = NULL; } #if defined(COMPILE_DEBUG) debug(1, "}}}}} %s client-exit", misc_getprog()); #endif exit(EXIT_SUCCESS); }
void client_srv_open(void) { struct sockaddr_in saddr; u_int16_t lprt, lowrng, res; int sock, incr, retry; /* ** should we bind a rand(port-range) or increment? */ incr = !config_bool(NULL,"SockBindRand", 0); /* ** mark socket invalid */ sock = -1; /* ** Forward connection to destination */ retry = MAX_RETRIES; lprt = ctx.srv_lrng; while(0 <= retry--) { /* ** First of all, get a socket */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { syslog_error("Srv-Ctrl: can't create socket for %s", ctx.cli_ctrl->peer); exit(EXIT_FAILURE); } socket_opts(sock, SK_CONTROL); /* ** check if we have to take care to a port range */ if( !(INPORT_ANY == ctx.srv_lrng && INPORT_ANY == ctx.srv_urng)) { u_int32_t ladr = INADDR_ANY; /* ** bind the socket, taking care of a given port range */ if(incr) { lowrng = lprt; #if defined(COMPILE_DEBUG) debug(2, "Srv-Ctrl: " "about to bind to %s:range(%d-%d)", socket_addr2str(ladr), lowrng, ctx.srv_urng); #endif res = socket_d_bind(sock, ladr, lowrng, ctx.srv_urng, incr); } else { lowrng = ctx.srv_lrng; #if defined(COMPILE_DEBUG) debug(2, "Srv-Ctrl: " "about to bind to %s:range(%d-%d)", socket_addr2str(ladr), lowrng, ctx.srv_urng); #endif res = socket_d_bind(sock, ladr, lowrng, ctx.srv_urng, incr); } if (INPORT_ANY == res) { /* nothing found? */ close(sock); syslog_error("Srv-Ctrl: can't bind to" " %s:%d for %s", socket_addr2str(ladr), (int)lprt, ctx.cli_ctrl->peer); exit(EXIT_FAILURE); } else { lprt = res; } } else lprt = INPORT_ANY; /* ** Okay, now try the actual connect to the server */ memset(&saddr, 0, sizeof(saddr)); saddr.sin_addr.s_addr = htonl(ctx.srv_addr); saddr.sin_family = AF_INET; saddr.sin_port = htons(ctx.srv_port); if (connect(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { #if defined(COMPILE_DEBUG) debug(2, "Srv-Ctrl: connect failed with '%s'", strerror(errno)); #endif close(sock); sock = -1; /* check if is makes sense to retry? ** perhaps we only need an other ** local port (EADDRNOTAVAIL) for ** this destination? */ if( !(EINTR == errno || EAGAIN == errno || EADDRINUSE == errno || EADDRNOTAVAIL == errno)) { /* ** an other (real) error ocurred */ syslog_error("Srv-Ctrl: " "can't connect %s:%d for %s", socket_addr2str(ctx.srv_addr), (int) ctx.srv_port, ctx.cli_ctrl->peer); exit(EXIT_FAILURE); } if(incr && INPORT_ANY != lprt) { /* increment lower range if we use ** increment mode and have a range */ if(lprt < ctx.srv_urng) { lprt++; } else { /* ** no more ports in range we can try */ syslog_error("Srv-Ctrl: " "can't connect %s:%d for %s", socket_addr2str(ctx.srv_addr), (int) ctx.srv_port, ctx.cli_ctrl->peer); exit(EXIT_FAILURE); } } } else break; } /* ** check if we have a valid, connected socket */ if(-1 == sock) { syslog_error("Srv-Ctrl: can't connect %s:%d for %s", socket_addr2str(ctx.srv_addr), (int) ctx.srv_port, ctx.cli_ctrl->peer); exit(EXIT_FAILURE); } if ((ctx.srv_ctrl = socket_init(sock)) == NULL) misc_die(FL, "cmds_user: ?srv_ctrl?"); ctx.srv_ctrl->ctyp = "Srv-Ctrl"; #if defined(COMPILE_DEBUG) debug(2, "Srv-Ctrl is %s:%d", ctx.srv_ctrl->peer, (int) ctx.srv_port); #endif ctx.expect = EXP_CONN; /* Expect Welcome */ }
int mem_config_line( AVP *av ) { MTYPE *mt; char *d; int t; if( !( d = strchr( av->att, '.' ) ) ) { // just the singles if( attIs( "maxMb" ) || attIs( "maxSize" ) ) ctl->mem->max_kb = 1024 * atoi( av->val ); else if( attIs( "maxKb") ) ctl->mem->max_kb = atoi( av->val ); else if( attIs( "interval" ) || attIs( "msec" ) ) ctl->mem->interval = atoi( av->val ); else if( attIs( "hashSize" ) ) ctl->mem->hashsize = atoi( av->val ); else if( attIs( "stackSize" ) ) { // gets converted to KB ctl->mem->stacksize = atoi( av->val ); debug( "Stack size set to %d KB.", ctl->mem->stacksize ); } else if( attIs( "gc" ) ) ctl->mem->gc_enabled = config_bool( av ); else if( attIs( "gcThresh" ) ) { t = atoi( av->val ); if( !t ) t = DEFAULT_GC_THRESH; debug( "Garbage collection threshold set to %d stats intervals.", t ); ctl->mem->gc_thresh = t; } else if( attIs( "gcGaugeThresh" ) ) { t = atoi( av->val ); if( !t ) t = DEFAULT_GC_GG_THRESH; debug( "Gauge garbage collection threshold set to %d stats intervals.", t ); ctl->mem->gc_gg_thresh = t; } else return -1; return 0; } *d++ = '\0'; // after this, it's per-type control if( !strncasecmp( av->att, "hosts.", 6 ) ) mt = ctl->mem->hosts; else if( !strncasecmp( av->att, "iobufs.", 7 ) ) mt = ctl->mem->iobufs; else if( !strncasecmp( av->att, "points.", 7 ) ) mt = ctl->mem->points; else if( !strncasecmp( av->att, "dhash.", 6 ) ) mt = ctl->mem->dhash; else if( !strncasecmp( av->att, "iolist.", 7 ) ) mt = ctl->mem->iolist; else if( !strncasecmp( av->att, "token.", 6 ) ) mt = ctl->mem->token; else return -1; if( !strcasecmp( d, "block" ) ) { mt->alloc_ct = (uint32_t) strtoul( av->val, NULL, 10 ); debug( "Allocation block for %s set to %u", av->att, mt->alloc_ct ); } else return -1; // done this way because GC might become a thing return 0; }
static int client_setup_file(CONTEXT *ctx, char *who) { char *p; u_int16_t l, u; /* ** little bit sanity check */ if( !(ctx && who && *who)) { return -1; } /* ** Inform the auditor that we are using the config file */ syslog_write(U_INF, "[ %s ] reading data for '%s' from cfg-file", ctx->cli_ctrl->peer, who); /* ** Evaluate DestinationAddress, except we have magic_addr */ if (INADDR_ANY != ctx->magic_addr) { ctx->srv_addr = ctx->magic_addr; } else { ctx->srv_addr = config_addr(who, "DestinationAddress", INADDR_ANY); #if defined(COMPILE_DEBUG) debug(2, "[ %s ] file DestAddr for %s: '%s'", ctx->cli_ctrl->peer, ctx->cli_ctrl->peer, socket_addr2str(ctx->srv_addr)); #endif } /* ** Evaluate DestinationPort, except we have magic_port */ if (INPORT_ANY != ctx->magic_port) { ctx->srv_port = ctx->magic_port; } else { ctx->srv_port = config_port(who, "DestinationPort", IPPORT_FTP); #if defined(COMPILE_DEBUG) debug(2, "[ %s ] file DestPort for %s: %d", ctx->cli_ctrl->peer, ctx->cli_ctrl->peer, (int) ctx->srv_port); #endif } /* ** Evaluate the destination transfer mode */ p = config_str(who, "DestinationTransferMode", "client"); if(0 == strcasecmp(p, "active")) { ctx->srv_mode = MOD_ACT_FTP; } else if(0 == strcasecmp(p, "passive")) { ctx->srv_mode = MOD_PAS_FTP; } else if(0 == strcasecmp(p, "client")) { ctx->srv_mode = MOD_CLI_FTP; } else { syslog_error("can't eval DestMode for %s", ctx->cli_ctrl->peer); return -1; } #if defined(COMPILE_DEBUG) debug(2, "file DestMode for %s: %s", ctx->cli_ctrl->peer, p); #endif /* ** Evaluate min/max destination port range */ l = config_port(who, "DestinationMinPort", INPORT_ANY); u = config_port(who, "DestinationMaxPort", INPORT_ANY); if (l > 0 && u > 0 && u >= l) { ctx->srv_lrng = l; ctx->srv_urng = u; } else { ctx->srv_lrng = INPORT_ANY; ctx->srv_urng = INPORT_ANY; } #if defined(COMPILE_DEBUG) debug(2, "file DestRange for %s: %u-%u", ctx->cli_ctrl->peer, ctx->srv_lrng, ctx->srv_urng); #endif /* ** Evaluate min/max active port range */ l = config_port(who, "ActiveMinDataPort", INPORT_ANY); u = config_port(who, "ActiveMaxDataPort", INPORT_ANY); if (l > 0 && u > 0 && u >= l) { ctx->act_lrng = l; ctx->act_urng = u; } else { /* do not try to bind a port < 1024 if running as UID != 0 */ if(0 == getuid()) { ctx->act_lrng = (IPPORT_FTP - 1); ctx->act_urng = (IPPORT_FTP - 1); } else { ctx->act_lrng = INPORT_ANY; ctx->act_urng = INPORT_ANY; } } #if defined(COMPILE_DEBUG) debug(2, "file ActiveRange for %s: %u-%u", ctx->cli_ctrl->peer, ctx->act_lrng, ctx->act_urng); #endif /* ** Evaluate min/max passive port range */ l = config_port(who, "PassiveMinDataPort", INPORT_ANY); u = config_port(who, "PassiveMaxDataPort", INPORT_ANY); if (l > 0 && u > 0 && u >= l) { ctx->pas_lrng = l; ctx->pas_urng = u; } else { ctx->pas_lrng = INPORT_ANY; ctx->pas_urng = INPORT_ANY; } #if defined(COMPILE_DEBUG) debug(2, "file PassiveRange for %s: %u-%u", ctx->cli_ctrl->peer, ctx->pas_lrng, ctx->pas_urng); #endif /* ** Setup other configuration options */ ctx->same_adr = config_bool(who, "SameAddress", 1); ctx->timeout = config_int (who, "TimeOut", 900); #if defined(COMPILE_DEBUG) debug(2, "file SameAddress for %s: %s", ctx->cli_ctrl->peer, ctx->same_adr ? "yes" : "no"); debug(2, "file TimeOut for %s: %d", ctx->cli_ctrl->peer, ctx->timeout); #endif /*** Adjust the allow/deny flags for the commands ** Fred patch */ char dest[17]; char ipdest[17]; char ipsrc[17]; strcpy (ipsrc,ctx->cli_ctrl->peer); strcpy (ipdest, socket_addr2str(ctx->srv_addr)); syslog_write(U_INF, "\n"); syslog_write(U_INF, "[ %s ] Fred Patch rules dest: %s src: %s", ipsrc, ipdest, ipsrc); char groupname[]="group"; char commandename[]="ValidCommands"; char *group; FILE *fp; group = "group1"; int ix; int ix2; u_int32_t dnsaddr; for(ix=1; group != NULL; ix++) { sprintf (&groupname[5],"%d",ix); group = config_str(who, groupname, NULL); } syslog_write(U_INF, "[ %s ] Number of groups: %d", ipsrc, ix-2); for (ix2=1; ix2 <= ix-2; ix2++) { sprintf (&groupname[5],"%d",ix2); group = config_str(who, groupname, NULL); syslog_write(U_INF, "[ %s ] Reading: %s",ipsrc, group ); if ((fp = fopen(group, "r")) == NULL) { syslog_write(U_INF, "File not found"); return 0; } else { fseek(fp, 0, SEEK_SET); while (fgets(dest, 17 , fp) != NULL) { // Pour une IP // Correction Bug Ligne sans \n dest[16] = '\n'; char *c = strchr (dest, '\n'); *c = 0; /* Dns resolution */ if (ipdest != dest) { dnsaddr = socket_str2addr(dest, INADDR_ANY); if (dnsaddr != 0) strcpy (dest, socket_addr2str(dnsaddr)); } if (strcmp(dest,ipdest) == 0 || strcmp(dest,ipsrc) == 0) { sprintf (&commandename[13],"%d",ix); p = config_str(who,commandename, NULL); cmds_set_allow(p); syslog_write(U_INF, "[ %s ] Apply rules for: %s dst: %s",ipsrc, ipsrc, ipdest); syslog_write(U_INF, "[ %s ] Server match %s ",ipsrc, group ); syslog_write(U_INF, "\n"); fclose(fp); return 0; } // Network if (strchr(dest, 'x') != NULL) { char *c = strchr(dest, 'x'); *c = 0; int longueur; longueur = strlen(dest); if (strncmp(dest,ipdest,longueur) == 0 || strncmp(dest,ipsrc,longueur) == 0) { sprintf (&commandename[13],"%d",ix); p = config_str(who,commandename, NULL); cmds_set_allow(p); syslog_write(U_INF, "[ %s ] Apply rules for Network: %s src: %s",ipsrc, ipdest, ipsrc); syslog_write(U_INF, "[ %s ] Server match %s ",ipsrc, group ); syslog_write(U_INF, "\n"); fclose(fp); return 0; } } } fclose(fp); } } syslog_write(U_INF, "[ %s ] Oh, Oh, no rule found -> defaultrules", ipsrc) ; p = config_str(who, "defaultrules", NULL); cmds_set_allow(p); return 0; }