void netstats(void) { if (getuid() == 0) firemon_drop_privs(); pid_read(0); // include all processes printf("Displaying network statistics only for sandboxes using a new network namespace.\n"); // print processes while (1) { // set pid table int i; int itv = 5; // 5 second interval pid_read(0); // todo: preserve the last calculation if any, so we don't have to do get_stats() // start rx/tx measurements for (i = 0; i < MAX_PIDS; i++) { if (pids[i].level == 1) get_stats(i); } // wait 5 seconds firemon_sleep(itv); // grab screen size struct winsize sz; int row = 24; int col = 80; if (!ioctl(0, TIOCGWINSZ, &sz)) { col = sz.ws_col; row = sz.ws_row; } // start printing firemon_clrscr(); char *header = get_header(); if (strlen(header) > col) header[col] = '\0'; printf("%s\n", header); if (row > 0) row--; free(header); // start rx/tx measurements for (i = 0; i < MAX_PIDS; i++) { if (pids[i].level == 1) { get_stats(i); print_proc(i, itv, col); } } } }
void netstats(void) { pid_read(0); // include all processes printf("Displaying network statistics only for sandboxes using a new network namespace.\n"); // print processes while (1) { // set pid table int i; int itv = 5; // 5 second interval pid_read(0); // start rx/tx measurements for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) get_stats(i); } // wait 5 seconds firemon_sleep(itv); // grab screen size struct winsize sz; int row = 24; int col = 80; if (!ioctl(0, TIOCGWINSZ, &sz)) { col = sz.ws_col; row = sz.ws_row; } // start printing firemon_clrscr(); char *header = get_header(); if (strlen(header) > (size_t)col) header[col] = '\0'; printf("%s\n", header); if (row > 0) row--; free(header); // start rx/tx measurements for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) { get_stats(i); print_proc(i, itv, col); } } #ifdef HAVE_GCOV __gcov_flush(); #endif } }
void route(pid_t pid, int print_procs) { pid_read(pid); // print processes int i; for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) { if (print_procs || pid == 0) pid_print_list(i, arg_nowrap); int child = find_child(i); if (child != -1) { char *fname; if (asprintf(&fname, "/proc/%d/net/fib_trie", child) == -1) errExit("asprintf"); extract_if(fname); free(fname); if (asprintf(&fname, "/proc/%d/net/route", child) == -1) errExit("asprintf"); print_route(fname); free(fname); } } } printf("\n"); }
int hanclient_connect_setup(char *pidpath, char *sockfilepath, char *service, char *host){ /* Always give preference to unix domain sockets, they are faster than inet sockets */ if(sockfilepath[0]){ /* Make sure we are running hand (.pid file check). */ if(pid_read(pidpath) == -1){ debug(DEBUG_ACTION, "Cannot establish a unix domain connection, hand is not running, pid path = '%s'.", pidpath); return 1; } sockFilePath = sockfilepath; } else if(service[0]){ /* Make sure we have a host defined */ if(host[0] == 0){ debug(DEBUG_ACTION, "Cannot establish an inet connection, host not defined in config file."); return 1; } inetService = service; inetHost = host; } else{ debug(DEBUG_ACTION, "Can't determine a valid connect method (unix or ip) in the config file to reach the han server."); return 1; } return 0; }
char *pid_check_and_create() { struct stat st; char* pidfile = pid_filename(); pid_t pid = pid_read(pidfile); /* Check PID for existence and liveness. */ if (pid > 0 && pid_running(pid)) { log_server_error("Server PID found, already running.\n"); free(pidfile); return NULL; } else if (stat(pidfile, &st) == 0) { log_server_warning("Removing stale PID file '%s'.\n", pidfile); pid_remove(pidfile); } /* Create a PID file. */ int ret = pid_write(pidfile); if (ret != KNOT_EOK) { log_server_error("Couldn't create a PID file '%s'.\n", pidfile); free(pidfile); return NULL; } return pidfile; }
void x11(pid_t pid, int print_procs) { pid_read(pid); // print processes int i; for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) { if (print_procs || pid == 0) pid_print_list(i, arg_nowrap); char *x11file; // todo: use macro from src/firejail/firejail.h for /run/firejail/x11 directory if (asprintf(&x11file, "/run/firejail/x11/%d", i) == -1) errExit("asprintf"); FILE *fp = fopen(x11file, "r"); if (!fp) { free(x11file); continue; } int display; int rv = fscanf(fp, "%d", &display); if (rv == 1) printf(" DISPLAY :%d\n", display); fclose(fp); free(x11file); } } printf("\n"); }
void tree(pid_t pid) { pid_read(pid); // print processes int i; for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) pid_print_tree(i, 0, arg_nowrap); } printf("\n"); }
void list(void) { pid_read(0); // include all processes // print processes int i; for (i = 0; i < max_pids; i++) { if (i == skip_process) continue; if (pids[i].level == 1) pid_print_list(i, arg_nowrap); } }
void tree(void) { if (getuid() == 0) firemon_drop_privs(); pid_read(0); // include all processes // print processes int i; for (i = 0; i < MAX_PIDS; i++) { if (pids[i].level == 1) pid_print_tree(i, 0, 0); } }
void list(void) { if (getuid() == 0) firemon_drop_privs(); pid_read(0); // include all processes // print processes int i; for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) pid_print_list(i, 0); } }
static int pid_verify(struct pid_file *file) { if ((file->pid = getpid()) == -1) return -1; int pid = pid_read(file); if (pid == 0) return 0; if ((kill(pid, 0) == 0)) return -1; pid_write(file); return 0; }
void cpu(pid_t pid) { if (getuid() == 0) firemon_drop_privs(); pid_read(pid); // print processes int i; for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) { pid_print_list(i, 0); int child = find_child(i); if (child != -1) print_cpu(child); } } }
void cpu(void) { if (getuid() == 0) firemon_drop_privs(); pid_read(0); // include all processes // print processes int i; for (i = 0; i < MAX_PIDS; i++) { if (pids[i].level == 1) { pid_print_list(i, 0); int child = find_child(i); if (child != -1) print_cpu(child); } } }
void seccomp(pid_t pid) { if (getuid() == 0) firemon_drop_privs(); pid_read(pid); // include all processes // print processes int i; for (i = 0; i < max_pids; i++) { if (pids[i].level == 1) { pid_print_list(i, 0); int child = find_child(i); if (child != -1) print_seccomp(child); } } printf("\n"); }
void procevent(pid_t pid) { // need to be root for this if (getuid() != 0) { fprintf(stderr, "Error: you need to be root to get process events\n"); exit(1); } // read and print sandboxed processes pid_read(pid); procevent_print_pids(); // monitor using netlink int sock = procevent_netlink_setup(); if (sock < 0) { fprintf(stderr, "Error: cannot open netlink socket\n"); exit(1); } procevent_monitor(sock,pid); // it will never return from here }
/*===========================================================================* * read_hook * *===========================================================================*/ int read_hook(struct inode *node, off_t off, char **ptr, size_t *len, cbdata_t cbdata) { /* Regular file read hook. Call the appropriate callback function to * generate and return the data. */ buf_init(off, *len); /* Populate the buffer with the proper content. */ if (get_inode_index(node) != NO_INDEX) { pid_read(node); } else { ((void (*) (void)) cbdata)(); } *len = buf_get(ptr); return OK; }
void interface(pid_t pid) { if (getuid() != 0) { fprintf(stderr, "Error: you need to be root to run this command\n"); exit(1); } pid_read(pid); // a pid of 0 will include all processes // print processes int i; for (i = 0; i < MAX_PIDS; i++) { if (pids[i].level == 1) { pid_print_list(i, 0); int child = find_child(i); if (child != -1) { print_sandbox(child); } } } }
void arp(pid_t pid) { if (getuid() == 0) firemon_drop_privs(); pid_read(pid); // print processes int i; for (i = 0; i < MAX_PIDS; i++) { if (pids[i].level == 1) { pid_print_list(i, 0); int child = find_child(i); if (child != -1) { char *fname; if (!asprintf(&fname, "/proc/%d/net/arp", child) == -1) errExit("asprintf"); print_arp(fname); free(fname); printf("\n"); } } } }
void top(void) { if (getuid() == 0) firemon_drop_privs(); while (1) { // clear linked list head_clear(); // set pid table int i; int itv = 5; // 5 second interval pid_read(0); // start cpu measurements unsigned utime; unsigned stime; for (i = 0; i < MAX_PIDS; i++) { if (pids[i].level == 1) pid_store_cpu(i, 0, &utime, &stime); } // wait 5 seconds firemon_sleep(itv); // grab screen size struct winsize sz; int row = 24; int col = 80; if (!ioctl(0, TIOCGWINSZ, &sz)) { col = sz.ws_col; row = sz.ws_row; } // start printing firemon_clrscr(); char *header = get_header(); if (strlen(header) > col) header[col] = '\0'; printf("%s\n", header); if (row > 0) row--; free(header); // find system uptime FILE *fp = fopen("/proc/uptime", "r"); if (fp) { float f; int rv = fscanf(fp, "%f", &f); (void) rv; sysuptime = (unsigned long long) f; fclose(fp); } // print processes for (i = 0; i < MAX_PIDS; i++) { if (pids[i].level == 1) { float cpu = 0; int cnt = 0; // process count char *line = print_top(i, 0, &utime, &stime, itv, &cpu, &cnt); if (line) head_add(cpu, line); } } head_print(col, row); } }
int main(int argc, char *argv[]) { int longindex; int optchar; String p; KeyEntryPtr_t e; zoneMapPtr_t zm; /* Set the program name */ progName=argv[0]; /* Parse the arguments. */ while((optchar=getopt_long(argc, argv, SHORT_OPTIONS, longOptions, &longindex)) != EOF) { /* Handle each argument. */ switch(optchar) { /* Was it a long option? */ case 0: /* Hrmm, something we don't know about? */ fatal("Unhandled long getopt option '%s'", longOptions[longindex].name); /* If it was an error, exit right here. */ case '?': exit(1); /* Was it a config file path ? */ case 'c': confreadStringCopy(configFile, optarg, WS_SIZE - 1); debug(DEBUG_ACTION,"New config file path is: %s", configFile); break; /* Was it a debug level set? */ case 'd': /* Save the value. */ debugLvl=atoi(optarg); if(debugLvl < 0 || debugLvl > DEBUG_MAX) { fatal("Invalid debug level"); } break; /* Was it a pid file switch? */ case 'f': confreadStringCopy(pidFile, optarg, WS_SIZE - 1); debug(DEBUG_ACTION,"New pid file path is: %s", pidFile); configOverride |= CO_PID_FILE; break; /* Was it a help request? */ case 'h': showHelp(); exit(0); /* Specify interface to broadcast on */ case 'i': confreadStringCopy(interface, optarg, WS_SIZE -1); xPL_setBroadcastInterface(interface); configOverride |= CO_INTERFACE; break; case 'u': /* Override debug path*/ confreadStringCopy(debugFile, optarg, WS_SIZE - 1); debug(DEBUG_ACTION,"New debug path is: %s", debugFile); configOverride |= CO_DEBUG_FILE; break; /* Was it a no-backgrounding request? */ case 'n': /* Mark that we shouldn't background. */ noBackground = TRUE; break; case 'p': /* Override com port*/ confreadStringCopy(comPort, optarg, WS_SIZE - 1); debug(DEBUG_ACTION,"New com port is: %s", comPort); configOverride |= CO_COM_PORT; break; /* Was it an instance ID ? */ case 's': confreadStringCopy(instanceID, optarg, WS_SIZE); debug(DEBUG_ACTION,"New instance ID is: %s", instanceID); configOverride |= CO_INSTANCE_ID; break; /* Was it a version request? */ case 'v': printf("Version: %s\n", VERSION); exit(0); /* It was something weird.. */ default: fatal("Unhandled getopt return value %d", optchar); } } /* If there were any extra arguments, we should complain. */ if(optind < argc) { fatal("Extra argument on commandline, '%s'", argv[optind]); } /* Load the config file */ if(!(configEntry =confreadScan(configFile, NULL))) exit(1); /* Parse the general section */ /* Com port */ if(!(configOverride & CO_COM_PORT)){ if((p = confreadValueBySectKey(configEntry, "general", "com-port"))){ confreadStringCopy(comPort, p, WS_SIZE); } } /* Debug file */ if(!(configOverride & CO_DEBUG_FILE)){ if((p = confreadValueBySectKey(configEntry, "general", "debug-file"))){ confreadStringCopy(debugFile, p, WS_SIZE); } } /* PID file */ if(!(configOverride & CO_PID_FILE)){ if((p = confreadValueBySectKey(configEntry, "general", "pid-file"))){ confreadStringCopy(pidFile, p, WS_SIZE); } } /* Instance ID */ if(!(configOverride & CO_INSTANCE_ID)){ if((p = confreadValueBySectKey(configEntry, "general", "instance-id"))){ confreadStringCopy(instanceID, p, WS_SIZE); } } /* Interface */ if(!(configOverride & CO_INTERFACE)){ if((p = confreadValueBySectKey(configEntry, "general", "interface"))){ confreadStringCopy(interface, p, WS_SIZE); } } /* Build Zone Map */ if(!(e = confreadGetFirstKeyBySection(configEntry, "zone-map"))) fatal("A valid zone-map section and at least one entry must be defined in the config file"); for(; e; e = confreadGetNextKey(e)){ String plist[3]; const String key = confreadGetKey(e); const String value = confreadGetValue(e); /* Allocate a zone struct */ if(!(zm = mallocz(sizeof(zoneMap_t)))) MALLOC_ERROR; /* Get the zone number */ if(!str2uns(key, &zm->zone_num, 1, 99)) syntax_error(e, configFile,"invalid zone number"); /* Get the parameters */ if(3 != splitString(value, plist, ',', 3)) syntax_error(e, configFile, "3 parameters required"); if(!(zm->zone_name = strdup(plist[0]))) MALLOC_ERROR; if(!(zm->zone_type = strdup(plist[1]))) MALLOC_ERROR; if(!(zm->alarm_type = strdup(plist[2]))) MALLOC_ERROR; /* Hash the zone name */ zm->zone_name_hash = confreadHash(zm->zone_name); /* Free the split string */ free(plist[0]); /* Insert the entry into the zone list */ if(!zoneMapHead) zoneMapHead = zoneMapTail = zm; else{ zm->prev = zoneMapTail; zoneMapTail->next = zm; zoneMapTail = zm; } zoneCount++; } /* EXP zone mapping */ for(e = confreadGetFirstKeyBySection(configEntry, "exp-map"); e; e = confreadGetNextKey(e)){ expMapPtr_t emp; const String keyString = confreadGetKey(e); const String zone = confreadGetValue(e); String plist[3]; unsigned expaddr, expchannel; /* Check the key and zone strings */ if(!(keyString) || (!zone)) syntax_error(e, configFile, "key or zone missing"); /* Split the address and channel */ plist[0] = NULL; if(2 != splitString(keyString, plist, ',', 2)) syntax_error(e, configFile, "left hand side needs 2 numbers separated by a comma"); /* Convert and check address */ if(!str2uns(plist[0], &expaddr, 1, 99)) syntax_error(e, configFile,"address is limited from 1 - 99"); /* Convert and check channel */ if(!str2uns(plist[1], &expchannel, 1, 99)) syntax_error(e, configFile,"channel is limited from 1 - 99"); /* debug(DEBUG_ACTION, "Address: %u, channel: %u, zone: %s", expaddr, expchannel, zone); */ /* Look up zone to ensure it is defined */ if(!(zm = zoneLookup(zone))) syntax_error(e, configFile, "Zone must be defined in zone-map section"); /* Get memory for entry */ if(!(emp = mallocz(sizeof(expMap_t)))) MALLOC_ERROR; /* Initialize entry */ emp->zone_entry = zm; emp->addr = expaddr; emp->channel = expchannel; if(!(emp->zone = strdup(zone))) MALLOC_ERROR; /* Insert into list */ if(!expMapHead){ expMapHead = expMapTail = emp; } else{ expMapTail->next = emp; emp->prev = expMapTail; expMapTail = emp; } /* Free parameter string */ if(plist[0]) free(plist[0]); } /* Turn on library debugging for level 5 */ if(debugLvl >= 5) xPL_setDebugging(TRUE); /* Make sure we are not already running (.pid file check). */ if(pid_read(pidFile) != -1) { fatal("%s is already running", progName); } /* Check to see the serial device exists before we fork */ if(!serio_check_node(comPort)) fatal("Serial device %s does not exist or its permissions are not allowing it to be used.", comPort); /* Fork into the background. */ if(!noBackground) { int retval; debug(DEBUG_STATUS, "Forking into background"); /* * If debugging is enabled, and we are daemonized, redirect the debug output to a log file if * the path to the logfile is defined */ if((debugLvl) && (debugFile[0])) notify_logpath(debugFile); /* Fork and exit the parent */ if((retval = fork())){ if(retval > 0) exit(0); /* Exit parent */ else fatal_with_reason(errno, "parent fork"); } /* * The child creates a new session leader * This divorces us from the controlling TTY */ if(setsid() == -1) fatal_with_reason(errno, "creating session leader with setsid"); /* * Fork and exit the session leader, this prohibits * reattachment of a controlling TTY. */ if((retval = fork())){ if(retval > 0) exit(0); /* exit session leader */ else fatal_with_reason(errno, "session leader fork"); } /* * Change to the root of all file systems to * prevent mount/unmount problems. */ if(chdir("/")) fatal_with_reason(errno, "chdir to /"); /* set the desired umask bits */ umask(022); /* Close STDIN, STDOUT, and STDERR */ close(0); close(1); close(2); } /* Start xPL up */ if (!xPL_initialize(xPL_getParsedConnectionType())) { fatal("Unable to start xPL lib"); } /* Initialize xplrcs service */ /* Create a service and set our application version */ xplService = xPL_createService("hwstar", "xplademco", instanceID); xPL_setServiceVersion(xplService, VERSION); /* * Create a status message object */ xplStatusMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_STATUS); /* * Create trigger message objects */ /* security.gateway */ if(!(xplEventTriggerMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_TRIGGER))) fatal("Could not initialize security.gateway trigger"); xPL_setSchema(xplEventTriggerMessage, "security", "gateway"); /* security.zone */ if(!(xplZoneTriggerMessage = xPL_createBroadcastMessage(xplService, xPL_MESSAGE_TRIGGER))) fatal("Could not initialize security.zone trigger"); xPL_setSchema(xplZoneTriggerMessage, "security", "zone"); /* Install signal traps for proper shutdown */ signal(SIGTERM, shutdownHandler); signal(SIGINT, shutdownHandler); /* Initialize the COM port */ if(!(serioStuff = serio_open(comPort, COM_BAUD_RATE))) fatal("Could not open com port: %s", comPort); /* Flush any partial commands */ serio_printf(serioStuff, "\r"); usleep(100000); serio_flush_input(serioStuff); /* Ask xPL to monitor our serial device */ if(xPL_addIODevice(serioHandler, 1234, serio_fd(serioStuff), TRUE, FALSE, FALSE) == FALSE) fatal("Could not register serial I/O fd with xPL"); /* Add 1 second tick service */ xPL_addTimeoutHandler(tickHandler, 1, NULL); /* And a listener for all xPL messages */ xPL_addMessageListener(xPLListener, NULL); /* Enable the service */ xPL_setServiceEnabled(xplService, TRUE); /* Update pid file */ if(pid_write(pidFile, getpid()) != 0) { debug(DEBUG_UNEXPECTED, "Could not write pid file '%s'.", pidFile); } /** Main Loop **/ for (;;) { /* Let XPL run forever */ xPL_processMessages(-1); } exit(1); }