static int options_apply(ProxyContext * const proxy_context) { if (proxy_context->resolver_ip == NULL || *proxy_context->resolver_ip == 0) { logger_noformat(proxy_context, LOG_ERR, "Resolver IP address required"); #ifdef _WIN32 logger_noformat(proxy_context, LOG_ERR, "Consult http://dnscrypt.org for details."); #else logger_noformat(proxy_context, LOG_ERR, "Please consult the dnscrypt-proxy(8) man page for details."); #endif exit(1); } if (proxy_context->provider_name == NULL || *proxy_context->provider_name == 0) { logger_noformat(proxy_context, LOG_ERR, "Provider name required"); exit(1); } if (options_check_protocol_versions(proxy_context->provider_name) != 0) { logger_noformat(proxy_context, LOG_ERR, "Unsupported server protocol version"); exit(1); } if (proxy_context->provider_publickey_s == NULL) { logger_noformat(proxy_context, LOG_ERR, "Provider key required"); exit(1); } if (dnscrypt_fingerprint_to_key(proxy_context->provider_publickey_s, proxy_context->provider_publickey) != 0) { logger_noformat(proxy_context, LOG_ERR, "Invalid provider key"); exit(1); } if (proxy_context->daemonize) { do_daemonize(); } #ifndef _WIN32 if (proxy_context->pid_file != NULL && pid_file_create(proxy_context->pid_file, proxy_context->user_id != (uid_t) 0) != 0) { logger_error(proxy_context, "Unable to create pid file"); } #endif if (proxy_context->log_file != NULL && (proxy_context->log_fd = open(proxy_context->log_file, O_WRONLY | O_APPEND | O_CREAT, (mode_t) 0600)) == -1) { logger_error(proxy_context, "Unable to open log file"); exit(1); } if (proxy_context->log_fd == -1 && proxy_context->daemonize) { logger_open_syslog(proxy_context); } return 0; }
static int options_apply(ProxyContext * const proxy_context) { if (proxy_context->resolver_ip == NULL) { options_usage(); exit(1); } if (proxy_context->provider_name == NULL || *proxy_context->provider_name == 0) { logger_noformat(proxy_context, LOG_ERR, "Provider name required"); exit(1); } if (proxy_context->provider_publickey_s == NULL) { logger_noformat(proxy_context, LOG_ERR, "Provider key required"); exit(1); } if (dnscrypt_fingerprint_to_key(proxy_context->provider_publickey_s, proxy_context->provider_publickey) != 0) { logger_noformat(proxy_context, LOG_ERR, "Invalid provider key"); exit(1); } if (proxy_context->daemonize) { do_daemonize(); } #ifndef _WIN32 if (proxy_context->pid_file != NULL && pid_file_create(proxy_context->pid_file, proxy_context->user_id != (uid_t) 0) != 0) { logger_error(proxy_context, "Unable to create pid file"); } #endif if (proxy_context->log_file != NULL && (proxy_context->log_fd = open(proxy_context->log_file, O_WRONLY | O_APPEND | O_CREAT, (mode_t) 0600)) == -1) { logger_error(proxy_context, "Unable to open log file"); exit(1); } if (proxy_context->log_fd == -1 && proxy_context->daemonize) { logger_open_syslog(proxy_context); } return 0; }
int run_client(int tunfd, const char *peer_addr_pair) { struct timeval timeo; int sockfd, rc; fd_set rset; char s_peer_addr[44]; if ((rc = v4pair_to_sockaddr(peer_addr_pair, ':', &peer_addr)) == 0) { /* DNS resolve OK, start service normally. */ last_recv = time(NULL); inet_ntop(peer_addr.sin_family, &peer_addr.sin_addr, s_peer_addr, sizeof(s_peer_addr)); printf("Mini virtual tunnelling client to %s:%u, interface: %s.\n", s_peer_addr, ntohs(peer_addr.sin_port), config.devname); } else if (rc == -EAGAIN && config.wait_dns) { /* Resolve later (last_recv = 0). */ last_recv = 0; printf("Mini virtual tunnelling client, interface: %s. \n", config.devname); printf("WARNING: DNS resolution of '%s' temporarily unavailable, " "resolving later.\n", peer_addr_pair); } else if (rc == -EINVAL) { fprintf(stderr, "*** Invalid address pair '%s'.\n", peer_addr_pair); return -1; } else { fprintf(stderr, "*** Cannot resolve address pair '%s'.\n", peer_addr_pair); return -1; } /* The initial tunnelling connection. */ if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { fprintf(stderr, "*** socket() failed: %s.\n", strerror(errno)); exit(1); } set_nonblock(sockfd); /* Run in background. */ if (config.in_background) do_daemonize(); if (config.pid_file) { FILE *fp; if ((fp = fopen(config.pid_file, "w"))) { fprintf(fp, "%d\n", (int)getpid()); fclose(fp); } } /* For triggering the first keep-alive packet to be sent. */ last_keepalive = 0; for (;;) { FD_ZERO(&rset); FD_SET(tunfd, &rset); FD_SET(sockfd, &rset); timeo.tv_sec = 2; timeo.tv_usec = 0; rc = select((tunfd > sockfd ? tunfd : sockfd) + 1, &rset, NULL, NULL, &timeo); if (rc < 0) { fprintf(stderr, "*** select(): %s.\n", strerror(errno)); return -1; } current_ts = time(NULL); if (last_recv > current_ts) last_recv = current_ts; if (last_keepalive > current_ts) last_keepalive = current_ts; /* Packet transmission timed out, send keep-alive packet. */ if (current_ts - last_keepalive > config.keepalive_timeo) { peer_keepalive(sockfd); } /* Connection timed out, try reconnecting. */ if (current_ts - last_recv > config.reconnect_timeo) { while (v4pair_to_sockaddr(peer_addr_pair, ':', &peer_addr) < 0) { fprintf(stderr, "Failed to resolve '%s', retrying.\n", peer_addr_pair); sleep(5); } /* Reconnected OK. Reopen the socket for a different local port. */ close(sockfd); if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { fprintf(stderr, "*** socket() failed: %s.\n", strerror(errno)); exit(1); } last_keepalive = 0; last_recv = current_ts; inet_ntop(peer_addr.sin_family, &peer_addr.sin_addr, s_peer_addr, sizeof(s_peer_addr)); printf("Reconnected to %s:%u.\n", s_peer_addr, ntohs(peer_addr.sin_port)); continue; } /* No result from select(), do nothing. */ if (rc == 0) continue; if (FD_ISSET(sockfd, &rset)) { rc = network_receiving(tunfd, sockfd); } if (FD_ISSET(tunfd, &rset)) { rc = tunnel_receiving(tunfd, sockfd); } } return 0; }
static int options_apply(ProxyContext * const proxy_context) { if (proxy_context->client_key_file != NULL) { if (proxy_context->ephemeral_keys != 0) { logger_noformat(proxy_context, LOG_ERR, "--client-key and --ephemeral-keys are mutually exclusive"); exit(1); } if (options_use_client_key_file(proxy_context) != 0) { logger(proxy_context, LOG_ERR, "Client key file [%s] could not be used", proxy_context->client_key_file); exit(1); } } if (proxy_context->resolver_name != NULL) { if (proxy_context->resolvers_list == NULL) { logger_noformat(proxy_context, LOG_ERR, "Resolvers list (-L command-line switch) required"); exit(1); } if (options_use_resolver_name(proxy_context) != 0) { logger(proxy_context, LOG_ERR, "Resolver name (-R command-line switch) required. " "See [%s] for a list of public resolvers.", proxy_context->resolvers_list); exit(1); } } if (proxy_context->resolver_ip == NULL || *proxy_context->resolver_ip == 0 || proxy_context->provider_name == NULL || *proxy_context->provider_name == 0 || proxy_context->provider_publickey_s == NULL || *proxy_context->provider_publickey_s == 0) { logger_noformat(proxy_context, LOG_ERR, "Resolver information required."); logger_noformat(proxy_context, LOG_ERR, "The easiest way to do so is to provide a resolver name."); logger_noformat(proxy_context, LOG_ERR, "Example: dnscrypt-proxy -R mydnsprovider"); logger(proxy_context, LOG_ERR, "See the file [%s] for a list of compatible public resolvers", proxy_context->resolvers_list); logger_noformat(proxy_context, LOG_ERR, "The name is the first column in this table."); logger_noformat(proxy_context, LOG_ERR, "Alternatively, an IP address, a provider name " "and a provider key can be supplied."); #ifdef _WIN32 logger_noformat(proxy_context, LOG_ERR, "Consult https://dnscrypt.org " "and https://github.com/jedisct1/dnscrypt-proxy/blob/master/README-WINDOWS.markdown " "for details."); #else logger_noformat(proxy_context, LOG_ERR, "Please consult https://dnscrypt.org " "and the dnscrypt-proxy(8) man page for details."); #endif exit(1); } if (proxy_context->provider_name == NULL || *proxy_context->provider_name == 0) { logger_noformat(proxy_context, LOG_ERR, "Provider name required"); exit(1); } if (options_check_protocol_versions(proxy_context->provider_name) != 0) { logger_noformat(proxy_context, LOG_ERR, "Unsupported server protocol version"); exit(1); } if (proxy_context->provider_publickey_s == NULL) { logger_noformat(proxy_context, LOG_ERR, "Provider key required"); exit(1); } if (dnscrypt_fingerprint_to_key(proxy_context->provider_publickey_s, proxy_context->provider_publickey) != 0) { logger_noformat(proxy_context, LOG_ERR, "Invalid provider key"); exit(1); } if (proxy_context->daemonize != 0) { if (proxy_context->log_file == NULL) { proxy_context->syslog = 1; } do_daemonize(); } #ifndef _WIN32 if (proxy_context->pid_file != NULL && pid_file_create(proxy_context->pid_file, proxy_context->user_id != (uid_t) 0) != 0) { logger_error(proxy_context, "Unable to create pid file"); exit(1); } #endif if (proxy_context->log_file != NULL && proxy_context->syslog != 0) { logger_noformat(proxy_context, LOG_ERR, "--logfile and --syslog are mutually exclusive"); exit(1); } if (proxy_context->log_file != NULL && (proxy_context->log_fp = fopen(proxy_context->log_file, "a")) == NULL) { logger_error(proxy_context, "Unable to open log file"); exit(1); } if (proxy_context->syslog != 0) { assert(proxy_context->log_fp == NULL); logger_open_syslog(proxy_context); } return 0; }
/** * Main entry point */ int main(int argc, char **argv) { TRACE_FUNC_START(); int rc; /* accept command-line arguments */ while ( (rc = getopt(argc, argv, "a:b:hsdf:")) != -1) { switch(rc) { case 'a': pc_info.rshell_args = (int8_t *)strdup(optarg); if (NULL == pc_info.rshell_args) { TRACE_ERR("Can't strdup remote shell args!!\n"); } break; case 'b': pc_info.batch_size = atoi(optarg); TRACE_DEBUG_LOG("Taking batch_size as %d\n", pc_info.batch_size); break; case 'd': pc_info.daemonize = 1; break; case 'h': print_help(*argv); break; case 'f': pc_info.lua_startup_file = (uint8_t *)strdup(optarg); if (NULL == pc_info.lua_startup_file) { TRACE_ERR("Can't strdup string for lua_startup_file: %s\n", strerror(errno)); } TRACE_DEBUG_LOG("Taking file %s as startup\n", pc_info.lua_startup_file); load_lua_file(optarg); break; case 's': pc_info.rshell = 1; break; default: print_help(*argv); break; } } /* init_modules */ init_modules(); /* check if rshell and daemonize are both enabled */ if (pc_info.daemonize && pc_info.rshell) { fprintf(stdout, "You cannot create a daemon process and " "a remote shell at the same time!\n"); fflush(stdout); print_help(*argv); return EXIT_FAILURE; } /* warp to remote shell, if asked */ if (pc_info.rshell) { if (pc_info.rshell_args == NULL) fprintf(stdout, "Using localhost and port %d by default\n", BRICKS_LISTEN_PORT); lua_kickoff(LUA_EXE_REMOTE_SHELL, pc_info.rshell_args); return EXIT_SUCCESS; } /* daemonize, if asked */ if ((pc_info.daemonize && (rc=do_daemonize()) == 0) || !pc_info.daemonize) { if (mark_pid_file(pv.pid_file) != 0) { TRACE_FUNC_END(); TRACE_ERR("Can't lock the pid file.\n" "Is a previous bricks daemon already running??\n"); } export_global_socket(); lua_kickoff((pc_info.daemonize) ? LUA_EXE_SCRIPT : LUA_EXE_HOME_SHELL, NULL); } /* initialize file printing mini-module */ print_status_file(); /* * if the user wants to daemonize and the process * is the child, then jump to accepting requests... */ if (pc_info.daemonize && rc == 0) { start_listening_reqs(); } TRACE_FUNC_END(); clean_exit(EXIT_SUCCESS); /* control will never come here */ return EXIT_SUCCESS; }
int main(int argc, char **argv) { static struct option long_options[] = { {"config-file", required_argument, NULL, 'f'}, {"verbose", no_argument, NULL, 'v'}, {"monitoring-history", no_argument, NULL, 'm'}, {"daemonize", no_argument, NULL, 'd'}, {"pid-file", required_argument, NULL, 'p'}, {NULL, 0, NULL, 0} }; int optindex; int c, ret; bool daemonize = false; FILE *fd; char standby_version[MAXVERSIONSTR], *ret_ver; progname = get_progname(argv[0]); if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(progname); exit(SUCCESS); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { printf("%s %s (PostgreSQL %s)\n", progname, REPMGR_VERSION, PG_VERSION); exit(SUCCESS); } } while ((c = getopt_long(argc, argv, "f:v:mdp:", long_options, &optindex)) != -1) { switch (c) { case 'f': config_file = optarg; break; case 'v': verbose = true; break; case 'm': monitoring_history = true; break; case 'd': daemonize = true; break; case 'p': pid_file = optarg; break; default: usage(); exit(ERR_BAD_CONFIG); } } if (daemonize) { do_daemonize(); } if (pid_file) { check_and_create_pid_file(pid_file); } #ifndef WIN32 setup_event_handlers(); #endif /* * Read the configuration file: repmgr.conf */ parse_config(config_file, &local_options); if (local_options.node == -1) { log_err(_("Node information is missing. " "Check the configuration file, or provide one if you have not done so.\n")); terminate(ERR_BAD_CONFIG); } fd = freopen("/dev/null", "r", stdin); if (fd == NULL) { fprintf(stderr, "error reopening stdin to '/dev/null': %s", strerror(errno)); } fd = freopen("/dev/null", "w", stdout); if (fd == NULL) { fprintf(stderr, "error reopening stdout to '/dev/null': %s", strerror(errno)); } logger_init(&local_options, progname, local_options.loglevel, local_options.logfacility); if (verbose) logger_min_verbose(LOG_INFO); if (log_type == REPMGR_SYSLOG) { fd = freopen("/dev/null", "w", stderr); if (fd == NULL) { fprintf(stderr, "error reopening stderr to '/dev/null': %s", strerror(errno)); } } xsnprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, local_options.cluster_name); log_info(_("%s Connecting to database '%s'\n"), progname, local_options.conninfo); my_local_conn = establish_db_connection(local_options.conninfo, true); /* should be v9 or better */ log_info(_("%s Connected to database, checking its state\n"), progname); ret_ver = pg_version(my_local_conn, standby_version); if (ret_ver == NULL || strcmp(standby_version, "") == 0) { if (ret_ver != NULL) log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); terminate(ERR_BAD_CONFIG); } /* * MAIN LOOP This loops cicles once per failover and at startup * Requisites: - my_local_conn needs to be already setted with an active * connection - no master connection */ do { /* * Set my server mode, establish a connection to primary and start * monitor */ ret = is_witness(my_local_conn, repmgr_schema, local_options.cluster_name, local_options.node); if (ret == 1) my_local_mode = WITNESS_MODE; else if (ret == 0) { ret = is_standby(my_local_conn); if (ret == 1) my_local_mode = STANDBY_MODE; else if (ret == 0) /* is the master */ my_local_mode = PRIMARY_MODE; } /* * XXX we did this before changing is_standby() to return int; we * should not exit at this point, but for now we do until we have a * better strategy */ if (ret == -1) terminate(1); switch (my_local_mode) { case PRIMARY_MODE: primary_options.node = local_options.node; strncpy(primary_options.conninfo, local_options.conninfo, MAXLEN); primary_conn = my_local_conn; check_cluster_configuration(my_local_conn); check_node_configuration(); if (reload_config(config_file, &local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); primary_conn = my_local_conn; update_registration(); } log_info(_("%s Starting continuous primary connection check\n"), progname); /* * Check that primary is still alive, and standbies are * sending info */ /* * Every local_options.monitor_interval_secs seconds, do * master checks XXX Check that standbies are sending info */ do { if (check_connection(primary_conn, "master")) { /* * CheckActiveStandbiesConnections(); * CheckInactiveStandbies(); */ sleep(local_options.monitor_interval_secs); } else { /* * XXX May we do something more verbose ? */ terminate(1); } if (got_SIGHUP) { /* * if we can reload, then could need to change * my_local_conn */ if (reload_config(config_file, &local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); primary_conn = my_local_conn; if (*local_options.logfile) { FILE *fd; fd = freopen(local_options.logfile, "a", stderr); if (fd == NULL) { fprintf(stderr, "error reopening stderr to '%s': %s", local_options.logfile, strerror(errno)); } } update_registration(); } got_SIGHUP = false; } } while (!failover_done); break; case WITNESS_MODE: case STANDBY_MODE: /* I need the id of the primary as well as a connection to it */ log_info(_("%s Connecting to primary for cluster '%s'\n"), progname, local_options.cluster_name); primary_conn = get_master_connection(my_local_conn, repmgr_schema, local_options.cluster_name, &primary_options.node, NULL); if (primary_conn == NULL) { terminate(ERR_BAD_CONFIG); } check_cluster_configuration(my_local_conn); check_node_configuration(); if (reload_config(config_file, &local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); update_registration(); } /* * Every local_options.monitor_interval_secs seconds, do * checks */ if (my_local_mode == WITNESS_MODE) { log_info(_("%s Starting continuous witness node monitoring\n"), progname); } else if (my_local_mode == STANDBY_MODE) { log_info(_("%s Starting continuous standby node monitoring\n"), progname); } do { if (my_local_mode == WITNESS_MODE) witness_monitor(); else if (my_local_mode == STANDBY_MODE) standby_monitor(); sleep(local_options.monitor_interval_secs); if (got_SIGHUP) { /* * if we can reload, then could need to change * my_local_conn */ if (reload_config(config_file, &local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); update_registration(); } got_SIGHUP = false; } } while (!failover_done); break; default: log_err(_("%s: Unrecognized mode for node %d\n"), progname, local_options.node); } failover_done = false; } while (true); /* close the connection to the database and cleanup */ close_connections(); /* Shuts down logging system */ logger_shutdown(); return 0; }
int main(int argc, char *argv[]) { unsigned char tox_id[TOX_ADDRESS_SIZE]; unsigned char tox_printable_id[TOX_ADDRESS_SIZE * 2 + 1]; TOX_ERR_NEW tox_new_err; int oc; size_t save_size = 0; uint8_t *save_data = NULL; allowed_toxid *allowed_toxid_obj = NULL; log_init(); while ((oc = getopt(argc, argv, "L:pi:C:s:P:dqhSF:DU:")) != -1) { switch(oc) { case 'L': /* Local port forwarding */ client_mode = 1; client_local_port_mode = 1; if(parse_local_port_forward(optarg, &local_port, &remote_host, &remote_port) < 0) { log_printf(L_ERROR, "Invalid value for -L option - use something like -L 22:127.0.0.1:22\n"); exit(1); } if(min_log_level == L_UNSET) { min_log_level = L_INFO; } log_printf(L_DEBUG, "Forwarding remote port %d to local port %d\n", remote_port, local_port); break; case 'P': /* Pipe forwarding */ client_mode = 1; client_pipe_mode = 1; if(parse_pipe_port_forward(optarg, &remote_host, &remote_port) < 0) { log_printf(L_ERROR, "Invalid value for -P option - use something like -P 127.0.0.1:22\n"); exit(1); } if(min_log_level == L_UNSET) { min_log_level = L_ERROR; } log_printf(L_INFO, "Forwarding remote port %d to stdin/out\n", remote_port); break; case 'p': /* Ping */ client_mode = 1; ping_mode = 1; if(min_log_level == L_UNSET) { min_log_level = L_INFO; } break; case 'i': /* Tox ID */ server_whitelist_mode = 1; log_printf(L_DEBUG, "Server whitelist mode enabled"); allowed_toxid_obj = (allowed_toxid *)calloc(sizeof(allowed_toxid), 1); if(!allowed_toxid_obj) { log_printf(L_ERROR, "Could not allocate memory for allowed_toxid"); exit(1); } remote_tox_id = optarg; if(!string_to_id(allowed_toxid_obj->toxid, optarg)) { log_printf(L_ERROR, "Invalid Tox ID"); exit(1); } LL_APPEND(allowed_toxids, allowed_toxid_obj); break; case 'C': /* Config directory */ strncpy(config_path, optarg, sizeof(config_path) - 1); if(optarg[strlen(optarg) - 1] != '/') { int optarg_len = strlen(optarg); config_path[optarg_len] = '/'; config_path[optarg_len + 1] = '\0'; } load_saved_toxid_in_client_mode = 1; break; case 's': /* Shared secret */ use_shared_secret = 1; memset(shared_secret, 0, TOX_MAX_FRIEND_REQUEST_LENGTH); strncpy(shared_secret, optarg, TOX_MAX_FRIEND_REQUEST_LENGTH-1); break; case 'd': min_log_level = L_DEBUG; break; case 'q': min_log_level = L_ERROR; break; case 'S': use_syslog = 1; break; case 'D': daemonize = 1; use_syslog = 1; break; case 'F': pidfile = optarg; break; case 'U': daemon_username = optarg; break; case '?': case 'h': default: print_version(); help(); exit(1); } } if(!client_mode && min_log_level == L_UNSET) { min_log_level = L_INFO; } if(!client_mode && server_whitelist_mode) { log_printf(L_INFO, "Server in ToxID whitelisting mode - only clients listed with -i can connect"); } if(daemonize) { do_daemonize(); } atexit(cleanup); print_version(); /* Bootstrap tox */ tox_options_default(&tox_options); if((!client_mode) || load_saved_toxid_in_client_mode) { uint8_t *save_data = NULL; save_size = load_save(&save_data); if(save_data && save_size) { tox_options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; tox_options.savedata_data = save_data; tox_options.savedata_length = save_size; } } tox = tox_new(&tox_options, &tox_new_err); if(tox == NULL) { log_printf(L_DEBUG, "tox_new() failed (%u) - trying without proxy\n", tox_new_err); if((tox_options.proxy_type != TOX_PROXY_TYPE_NONE) || (tox_options.proxy_type = TOX_PROXY_TYPE_NONE, (tox = tox_new(&tox_options, &tox_new_err)) == NULL)) { log_printf(L_DEBUG, "tox_new() failed (%u) - trying without IPv6\n", tox_new_err); if(!tox_options.ipv6_enabled || (tox_options.ipv6_enabled = 0, (tox = tox_new(&tox_options, &tox_new_err)) == NULL)) { log_printf(L_DEBUG, "tox_new() failed (%u) - trying with Tor\n", tox_new_err); if((tox_options.proxy_type = TOX_PROXY_TYPE_SOCKS5, tox_options.proxy_host="127.0.0.1", tox_options.proxy_port=9050, (tox = tox_new(&tox_options, &tox_new_err)) == NULL)) { log_printf(L_ERROR, "tox_new() failed (%u) - exiting\n", tox_new_err); exit(1); } } } } if(save_size && save_data) { free(save_data); } set_tox_username(tox); tox_callback_self_connection_status(tox, handle_connection_status_change, NULL); do_bootstrap(tox); if(client_mode) { tox_self_get_address(tox, tox_id); id_to_string(tox_printable_id, tox_id); tox_printable_id[TOX_ADDRESS_SIZE * 2] = '\0'; log_printf(L_DEBUG, "Generated Tox ID: %s\n", tox_printable_id); if(!remote_tox_id) { log_printf(L_ERROR, "Tox id is required in client mode. Use -i 58435984ABCDEF475...\n"); exit(1); } do_client_loop(remote_tox_id); } else { write_save(tox); if(!use_shared_secret) { log_printf(L_WARNING, "Shared secret authentication is not used - skilled attackers may connect to your tuntox server"); } tox_self_get_address(tox, tox_id); memset(tox_printable_id, '\0', sizeof(tox_printable_id)); id_to_string(tox_printable_id, tox_id); tox_printable_id[TOX_ADDRESS_SIZE * 2] = '\0'; log_printf(L_INFO, "Using Tox ID: %s\n", tox_printable_id); tox_callback_friend_request(tox, accept_friend_request, NULL); do_server_loop(); } return 0; }
int main(int argc, char *argv[]) { int c; int log_method = L_STDERR_SYSLOG; char *logfile = PATH_RADVD_LOG; int facility = LOG_FACILITY; char *username = NULL; char *chrootdir = NULL; int configtest = 0; int daemonize = 1; char const *pname = ((pname = strrchr(argv[0], '/')) != NULL) ? pname + 1 : argv[0]; srand((unsigned int)time(NULL)); char const *conf_path = PATH_RADVD_CONF; char const *daemon_pid_file_ident = PATH_RADVD_PID; /* parse args */ #define OPTIONS_STR "d:C:l:m:p:t:u:vhcn" #ifdef HAVE_GETOPT_LONG int opt_idx; while ((c = getopt_long(argc, argv, OPTIONS_STR, prog_opt, &opt_idx)) > 0) #else while ((c = getopt(argc, argv, OPTIONS_STR)) > 0) #endif { switch (c) { case 'C': conf_path = optarg; break; case 'd': set_debuglevel(atoi(optarg)); break; case 'f': facility = atoi(optarg); break; case 'l': logfile = optarg; break; case 'p': daemon_pid_file_ident = optarg; break; case 'm': if (!strcmp(optarg, "syslog")) { log_method = L_SYSLOG; } else if (!strcmp(optarg, "stderr_syslog")) { log_method = L_STDERR_SYSLOG; } else if (!strcmp(optarg, "stderr")) { log_method = L_STDERR; } else if (!strcmp(optarg, "logfile")) { log_method = L_LOGFILE; } else if (!strcmp(optarg, "none")) { log_method = L_NONE; } else { fprintf(stderr, "%s: unknown log method: %s\n", pname, optarg); exit(1); } break; case 't': chrootdir = strdup(optarg); break; case 'u': username = strdup(optarg); break; case 'v': version(); break; case 'c': configtest = 1; break; case 'n': daemonize = 0; break; case 'h': usage(pname); #ifdef HAVE_GETOPT_LONG case ':': fprintf(stderr, "%s: option %s: parameter expected\n", pname, prog_opt[opt_idx].name); exit(1); #endif case '?': exit(1); } } /* TODO: Seems like this chroot'ing should happen *after* daemonizing for * the sake of the PID file. */ if (chrootdir) { if (!username) { fprintf(stderr, "Chroot as root is not safe, exiting\n"); exit(1); } if (chroot(chrootdir) == -1) { perror("chroot"); exit(1); } if (chdir("/") == -1) { perror("chdir"); exit(1); } /* username will be switched later */ } if (configtest) { set_debuglevel(1); log_method = L_STDERR; } if (log_open(log_method, pname, logfile, facility) < 0) { perror("log_open"); exit(1); } if (!configtest) { flog(LOG_INFO, "version %s started", VERSION); } /* check that 'other' cannot write the file * for non-root, also that self/own group can't either */ if (check_conffile_perm(username, conf_path) != 0) { if (get_debuglevel() == 0) { flog(LOG_ERR, "exiting, permissions on conf_file invalid"); exit(1); } else flog(LOG_WARNING, "Insecure file permissions, but continuing anyway"); } /* parse config file */ struct Interface *ifaces = NULL; if ((ifaces = readin_config(conf_path)) == 0) { flog(LOG_ERR, "exiting, failed to read config file"); exit(1); } if (configtest) { free_ifaces(ifaces); exit(0); } /* get a raw socket for sending and receiving ICMPv6 messages */ int sock = open_icmpv6_socket(); if (sock < 0) { perror("open_icmpv6_socket"); exit(1); } /* if we know how to do it, check whether forwarding is enabled */ if (check_ip6_forwarding()) { flog(LOG_WARNING, "IPv6 forwarding seems to be disabled, but continuing anyway"); } int const pidfd = open_and_lock_pid_file(daemon_pid_file_ident); /* * okay, config file is read in, socket and stuff is setup, so * lets fork now... */ if (daemonize) { pid_t pid = do_daemonize(log_method, daemon_pid_file_ident); if (pid != 0 && pid != -1) { /* We want to see clean output from valgrind, so free username, chrootdir, * and ifaces in the child process. */ if (ifaces) free_ifaces(ifaces); if (username) free(username); if (chrootdir) free(chrootdir); exit(0); } } else { if (0 != write_pid_file(daemon_pid_file_ident, getpid())) { flog(LOG_ERR, "failure writing pid file detected"); exit(-1); } } check_pid_file(daemon_pid_file_ident); #ifdef __linux__ /* for privsep */ { dlog(LOG_DEBUG, 3, "initializing privsep"); int pipefds[2]; if (pipe(pipefds) != 0) { flog(LOG_ERR, "Couldn't create privsep pipe."); return -1; } pid_t pid = fork(); if (pid == -1) { flog(LOG_ERR, "Couldn't fork for privsep."); return -1; } if (pid == 0) { /* We want to see clean output from valgrind, so free username, chrootdir, * and ifaces in the child process. */ if (ifaces) free_ifaces(ifaces); if (username) free(username); if (chrootdir) free(chrootdir); close(pipefds[1]); privsep_init(pipefds[0]); _exit(0); } dlog(LOG_DEBUG, 3, "radvd privsep PID is %d", pid); /* Continue execution (will drop privileges soon) */ close(pipefds[0]); privsep_set_write_fd(pipefds[1]); } #endif if (username) { if (drop_root_privileges(username) < 0) { perror("drop_root_privileges"); flog(LOG_ERR, "unable to drop root privileges"); exit(1); } dlog(LOG_DEBUG, 3, "running as user: %s", username); } setup_ifaces(sock, ifaces); ifaces = main_loop(sock, ifaces, conf_path); stop_adverts(sock, ifaces); flog(LOG_INFO, "removing %s", daemon_pid_file_ident); unlink(daemon_pid_file_ident); close(pidfd); if (ifaces) free_ifaces(ifaces); if (chrootdir) free(chrootdir); if (username) free(username); flog(LOG_INFO, "returning from radvd main"); log_close(); return 0; }
int main(int argc, char **argv) { /* initial configuration, will be overridden by config file and command line options */ first_init = 1; running = 0; // will be set to != 0 once honeytrap set up itself /* save command line arguments */ arg_c = argc; arg_v = argv; /* the following are default values - change them in your configuration file */ daemonize = 1; // default is to daemonize #ifdef USE_PCAP_MON promisc_mode = 0; // no promisc mode pcap_offset = 0; // will be set after link type is determined #endif log_level = LOG_NOTICE; // default log level logfile_fd = STDOUT_FILENO;// default logfile, stdout will be replaced by logfile_fd u_id = 0; // root privileges per default g_id = 0; conn_timeout = 120; // 2 minutes connect timeout read_timeout = 1; // 1 second read timeout m_read_timeout = 60; // 1 minute read timeout for mirror connections read_limit = 0; // 0 means no read limit conffile_name = strdup("/etc/honeytrap/honeytrap.conf"); pidfile_name = strdup("/var/run/honeytrap.pid"); logfile_name = strdup("/var/log/honeytrap.log"); response_dir = strdup("/etc/honeytrap/responses"); plugin_dir = strdup("/etc/honeytrap/plugins"); #ifdef USE_PCAP_MON dev = NULL; // network device pointer packet_sniffer = NULL; // pcap device pointer #endif portconf_default = PORTCONF_NONE; eventlist = NULL; // list of timer-based events /* configure honeytrap */ configure(arg_c, arg_v); /* daemonize (detach from console) */ if (daemonize) do_daemonize(); /* now initialize plugins */ init_plugins(); /* create pid file */ create_pid_file(); /* create IPC pipe and queue for port infos */ if (pipe(portinfopipe) == -1) { logmsg(LOG_ERR, 0, " Error - Unable to create port info IPC pipe: %m.\n"); exit(EXIT_FAILURE); } if ((portinfoq = queue_new()) == NULL) { logmsg(LOG_ERR, 0, " Error - Unable to create port info IPC pipe: %m.\n"); exit(EXIT_FAILURE); } /* watch out for incoming connection requests */ if (start_connection_monitor() < 0) clean_exit(EXIT_SUCCESS); return(0); }
int main(int argc, char *argv[]) { int rc, sync[2]; pid_t pid = -1; siginfo_t status; struct mount *mounts = NULL; struct netif *netifs = NULL; struct cgroup *cgroups = NULL; struct user *users = NULL; #if HAVE_LIBCAP_NG struct capability *caps = NULL; #endif char *master; _close_ int master_fd = -1; char ephemeral_dir[] = "/tmp/pflask-ephemeral-XXXXXX"; int clone_flags = CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWPID | #ifdef CLONE_NEWCGROUP CLONE_NEWCGROUP | #endif CLONE_NEWUTS; struct gengetopt_args_info args; if (cmdline_parser(argc, argv, &args) != 0) return 1; for (unsigned int i = 0; i < args.mount_given; i++) { validate_optlist("--mount", args.mount_arg[i]); mount_add_from_spec(&mounts, args.mount_arg[i]); } for (unsigned int i = 0; i < args.netif_given; i++) { clone_flags |= CLONE_NEWNET; if (args.netif_arg != NULL) { validate_optlist("--netif", args.netif_arg[i]); netif_add_from_spec(&netifs, args.netif_arg[i]); } } if (args.user_given && !args.user_map_given) { uid_t uid; gid_t gid; clone_flags |= CLONE_NEWUSER; if (user_get_uid_gid(args.user_arg, &uid, &gid)) { user_add_map(&users, 'u', uid, uid, 1); user_add_map(&users, 'g', gid, gid, 1); } } for (unsigned int i = 0; i < args.user_map_given; i++) { size_t count; uid_t id, host_id; char *start = args.user_map_arg[i], *end = NULL; validate_optlist("--user-map", args.user_map_arg[i]); clone_flags |= CLONE_NEWUSER; id = strtoul(start, &end, 10); if (*end != ':') fail_printf("Invalid value '%s' for --user-map", args.user_map_arg[i]); start = end + 1; host_id = strtoul(start, &end, 10); if (*end != ':') fail_printf("Invalid value '%s' for --user-map", args.user_map_arg[i]); start = end + 1; count = strtoul(start, &end, 10); if (*end != '\0') fail_printf("Invalid value '%s' for --user-map", args.user_map_arg[i]); user_add_map(&users, 'u', id, host_id, count); user_add_map(&users, 'g', id, host_id, count); } for (unsigned int i = 0; i < args.cgroup_given; i++) cgroup_add(&cgroups, args.cgroup_arg[i]); #if HAVE_LIBCAP_NG for (unsigned int i = 0; i < args.caps_given; i++) capability_add(&caps, args.caps_arg[i]); #endif if (args.no_userns_flag) clone_flags &= ~(CLONE_NEWUSER); if (args.no_mountns_flag) clone_flags &= ~(CLONE_NEWNS); if (args.no_netns_flag) clone_flags &= ~(CLONE_NEWNET); if (args.no_ipcns_flag) clone_flags &= ~(CLONE_NEWIPC); if (args.no_utsns_flag) clone_flags &= ~(CLONE_NEWUTS); if (args.no_pidns_flag) clone_flags &= ~(CLONE_NEWPID); if (args.attach_given) { master_fd = recv_pty(args.attach_arg); fail_if(master_fd < 0, "Invalid PID '%u'", args.attach_arg); process_pty(master_fd); return 0; } open_master_pty(&master_fd, &master); if (args.detach_flag) do_daemonize(); sync_init(sync); if (args.ephemeral_flag) { if (!mkdtemp(ephemeral_dir)) sysf_printf("mkdtemp()"); } pid = do_clone(&clone_flags); if (!pid) { closep(&master_fd); rc = prctl(PR_SET_PDEATHSIG, SIGKILL); sys_fail_if(rc < 0, "prctl(PR_SET_PDEATHSIG)"); rc = setsid(); sys_fail_if(rc < 0, "setsid()"); sync_barrier_parent(sync, SYNC_START); sync_close(sync); open_slave_pty(master); setup_user(args.user_arg); if (args.hostname_given) { rc = sethostname(args.hostname_arg, strlen(args.hostname_arg)); sys_fail_if(rc < 0, "Error setting hostname"); } setup_mount(mounts, args.chroot_arg, args.ephemeral_flag ? ephemeral_dir : NULL); if (args.chroot_given) { setup_nodes(args.chroot_arg); setup_ptmx(args.chroot_arg); setup_symlinks(args.chroot_arg); setup_console(args.chroot_arg, master); do_chroot(args.chroot_arg); } if (clone_flags & CLONE_NEWNET) config_netif(); umask(0022); #if HAVE_LIBCAP_NG setup_capabilities(caps); #endif if (args.chdir_given) { rc = chdir(args.chdir_arg); sys_fail_if(rc < 0, "Error changing cwd"); } if (args.chroot_given) { char *term = getenv("TERM"); if (!args.keepenv_flag) clearenv(); setenv("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1); setenv("USER", args.user_arg, 1); setenv("LOGNAME", args.user_arg, 1); if (term) setenv("TERM", term, 1); } for (unsigned int i = 0; i < args.setenv_given; i++) { rc = putenv(strdup(args.setenv_arg[i])); sys_fail_if(rc != 0, "Error setting environment"); } setenv("container", "pflask", 1); if (argc > optind) rc = execvpe(argv[optind], argv + optind, environ); else rc = execle("/bin/bash", "-bash", NULL, environ); sys_fail_if(rc < 0, "Error executing command"); } sync_wait_child(sync, SYNC_START); if (args.chroot_given && (clone_flags & CLONE_NEWUSER)) setup_console_owner(master, users); setup_cgroup(cgroups, pid); setup_netif(netifs, pid); #ifdef HAVE_DBUS register_machine(pid, args.chroot_given ? args.chroot_arg : ""); #endif if (clone_flags & CLONE_NEWUSER) setup_user_map(users, pid); sync_wake_child(sync, SYNC_DONE); sync_close(sync); if (args.detach_flag) serve_pty(master_fd); else process_pty(master_fd); kill(pid, SIGKILL); rc = waitid(P_PID, pid, &status, WEXITED); sys_fail_if(rc < 0, "Error waiting for child"); switch (status.si_code) { case CLD_EXITED: if (status.si_status != 0) err_printf("Child failed with code '%d'", status.si_status); else ok_printf("Child exited"); break; case CLD_KILLED: err_printf("Child was terminated by signal '%d'", status.si_status); break; default: err_printf("Child failed"); break; } sync_close(sync); clean_cgroup(cgroups); if (args.ephemeral_flag) { rc = rmdir(ephemeral_dir); sys_fail_if(rc != 0, "Error deleting ephemeral directory: %s", ephemeral_dir); } cmdline_parser_free(&args); return status.si_status; }
int main(int argc, char *argv[]) { int rc, i; pid_t pid = -1; pid_t ppid = getpid(); uid_t uid = -1; gid_t gid = -1; _free_ char *user = NULL; _free_ char *dest = NULL; _free_ char *change = NULL; _free_ char *env = NULL; _free_ char *cgroup = NULL; _close_ int master_fd = -1; char *master_name; int detach = 0; int keepenv = 0; siginfo_t status; while ((rc = getopt_long(argc, argv, short_opts, long_opts, &i)) !=-1) { switch (rc) { case 'm': validate_optlist("--mount", optarg); add_mount_from_spec(optarg); break; case 'n': clone_flags |= CLONE_NEWNET; if (optarg != NULL) { validate_optlist("--netif", optarg); add_netif_from_spec(optarg); } break; case 'u': clone_flags |= CLONE_NEWUSER; freep(&user); user = strdup(optarg); break; case 'r': freep(&dest); dest = realpath(optarg, NULL); if (dest == NULL) sysf_printf("realpath()"); break; case 'c': freep(&change); change = strdup(optarg); break; case 'g': validate_optlist("--cgroup", optarg); validate_cgroup_spec(optarg); freep(&change); cgroup = strdup(optarg); break; case 'd': detach = 1; break; case 'a': { char *end = NULL; pid = strtol(optarg, &end, 10); if (*end != '\0') fail_printf("Invalid value '%s' for --attach", optarg); break; } case 's': { validate_optlist("--setenv", optarg); if (env != NULL) { char *tmp = env; rc = asprintf(&env, "%s,%s", env, optarg); if (rc < 0) fail_printf("OOM"); freep(&tmp); } else { env = strdup(optarg); } break; } case 'k': keepenv = 1; break; case 'U': clone_flags &= ~(CLONE_NEWUSER); break; case 'M': clone_flags &= ~(CLONE_NEWNS); break; case 'N': clone_flags &= ~(CLONE_NEWNET); break; case 'I': clone_flags &= ~(CLONE_NEWIPC); break; case 'H': clone_flags &= ~(CLONE_NEWUTS); break; case 'P': clone_flags &= ~(CLONE_NEWPID); break; case '?': case 'h': help(); return 0; } } if (pid != -1) { master_fd = recv_pty(pid); if (master_fd < 0) fail_printf("Invalid PID '%u'", pid); pid = -1; goto process_fd; } if (user == NULL) { user = strdup("root"); if (user == NULL) fail_printf("OOM"); } open_master_pty(&master_fd, &master_name); uid = getuid(); gid = getgid(); if (detach == 1) do_daemonize(); pid = do_clone(); if (pid == 0) { closep(&master_fd); open_slave_pty(master_name); rc = setsid(); if (rc < 0) sysf_printf("setsid()"); rc = prctl(PR_SET_PDEATHSIG, SIGKILL); if (rc < 0) sysf_printf("prctl(PR_SET_PDEATHSIG)"); if (clone_flags & CLONE_NEWUSER) map_user_to_user(uid, gid, user); do_cgroup(cgroup, ppid); do_mount(dest); if (dest != NULL) { copy_nodes(dest); make_ptmx(dest); make_symlinks(dest); make_console(dest, master_name); do_chroot(dest); } if (clone_flags & CLONE_NEWNET) setup_loopback(); umask(0022); /* TODO: drop capabilities */ do_user(user); if (change != NULL) { rc = chdir(change); if (rc < 0) sysf_printf("chdir()"); } if (dest != NULL) { char *term = getenv("TERM"); if (keepenv == 0) clearenv(); setenv("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1); setenv("USER", user, 1); setenv("LOGNAME", user, 1); setenv("TERM", term, 1); } if (env != NULL) { size_t i, c; _free_ char **vars = NULL; _free_ char *tmp = strdup(env); if (tmp == NULL) fail_printf("OOM"); c = split_str(tmp, &vars, ","); for (i = 0; i < c; i++) { rc = putenv(strdup(vars[i])); if (rc != 0) sysf_printf("putenv()"); } } setenv("container", "pflask", 1); if (argc > optind) rc = execvpe(argv[optind], argv + optind, environ); else rc = execle("/bin/bash", "-bash", NULL, environ); if (rc < 0) sysf_printf("exec()"); } do_netif(pid); process_fd: if (detach == 1) serve_pty(master_fd); else process_pty(master_fd); if (pid == -1) return 0; kill(pid, SIGKILL); rc = waitid(P_PID, pid, &status, WEXITED); if (rc < 0) sysf_printf("waitid()"); switch (status.si_code) { case CLD_EXITED: if (status.si_status != 0) err_printf("Child failed with code '%d'", status.si_status); else ok_printf("Child exited"); break; case CLD_KILLED: err_printf("Child was terminated"); break; default: err_printf("Child failed"); break; } undo_cgroup(cgroup, ppid); return status.si_status; }