void Desktop::OnCommand(const string_t &cmd) { if( cmd.empty() ) { return; } string_t exec; if( g_client && !g_client->IsLocal() ) { if( cmd[0] == '/' ) { exec = cmd.substr(1); // cut off the first symbol and execute cmd } else { dynamic_cast<TankClient*>(g_client)->SendTextMessage(cmd); return; } } else { exec = cmd; } if( luaL_loadstring(g_env.L, exec.c_str()) ) { lua_pop(g_env.L, 1); string_t tmp = "print("; tmp += exec; tmp += ")"; if( luaL_loadstring(g_env.L, tmp.c_str()) ) { lua_pop(g_env.L, 1); } else { script_exec(g_env.L, tmp.c_str()); return; } } script_exec(g_env.L, exec.c_str()); }
void ui_execute_console_command(char* cmd) { int ret = script_exec(cmd); if (ret != 0) { printf("TODO: handle ret != 0 from script command (ret = %d)\n", ret); } }
void do_init(void) { script_exec("/init.rc"); }
int sys_ping(const arms_ping_arg_t *arg, struct arms_ping_report *rep) { FILE *fp; struct addrinfo hints, *res, *res0; int af, n, pkts, success, timeout; const char *argv[4 + 3]; /* 3 for safety... */ char buf[300], *tmpfile; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_NUMERICHOST; n = getaddrinfo(arg->dst, NULL, &hints, &res0); if (n) { logit(LOG_WARNING, "cannot resolve %s: %s", arg->dst, gai_strerror(n)); return ARMS_ESYSTEM; } af = AF_UNSPEC; for (res = res0; res; res = res->ai_next) if (res->ai_family == AF_INET || res->ai_family == AF_INET6) { af = res->ai_family; break; } freeaddrinfo(res0); if (af == AF_UNSPEC) { logit(LOG_WARNING, "no IPv4/IPv6 address: %s", arg->dst); return ARMS_ESYSTEM; } fclose(armsdir_create_tmpfile(&tmpfile)); snprintf(buf, sizeof(buf), "%s -nq -c %d -s %d %s > %s", (af == AF_INET ? "ping" : "ping6"), arg->count, arg->size, arg->dst, tmpfile); logit(LOG_DEBUG, "ping command exec: %s", buf); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = buf; argv[3] = NULL; timeout = dconf_get_int("timeout"); n = script_exec(argv, timeout); if (n == -1) { logit(LOG_WARNING, "ping command failed"); unlink(tmpfile); return ARMS_ESYSTEM; } fp = fopen(tmpfile, "r"); if (fp == NULL) { logit(LOG_ERR, "ping command succeeded but cannot open %s: %s", tmpfile, strerror(errno)); unlink(tmpfile); return ARMS_ESYSTEM; } n = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { n = sscanf(buf, "%d packets transmitted, %d received", &pkts, &success); if (n == 2) { rep->success = success; rep->failure = pkts - success; break; } } fclose(fp); unlink(tmpfile); if (n == 2) return 0; else return ARMS_ESYSTEM; }
int sys_traceroute(const arms_traceroute_arg_t *arg, struct arms_traceroute_info *tr, int trcount) { FILE *fp; struct addrinfo hints, *res, *res0; int af, hop, n, timeout; const char *argv[4 + 3]; /* 3 for safety... */ char buf[300], host[64], *tmpfile; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_NUMERICHOST; n = getaddrinfo(arg->addr, NULL, &hints, &res0); if (n) { logit(LOG_WARNING, "cannot resolve %s: %s", arg->addr, gai_strerror(n)); return ARMS_ESYSTEM; } af = AF_UNSPEC; for (res = res0; res; res = res->ai_next) if (res->ai_family == AF_INET || res->ai_family == AF_INET6) { af = res->ai_family; break; } freeaddrinfo(res0); if (af == AF_UNSPEC) { logit(LOG_WARNING, "no IPv4/IPv6 address: %s", arg->addr); return ARMS_ESYSTEM; } fclose(armsdir_create_tmpfile(&tmpfile)); snprintf(buf, sizeof(buf), "traceroute %s -n -m %d -q %d %s > %s", (af == AF_INET ? "-4" : "-6"), arg->maxhop, arg->count, arg->addr, tmpfile); logit(LOG_DEBUG, "traceroute command exec: %s", buf); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = buf; argv[3] = NULL; timeout = dconf_get_int("timeout"); n = script_exec(argv, timeout); if (n == -1) { logit(LOG_WARNING, "traceroute command failed"); unlink(tmpfile); return ARMS_ESYSTEM; } fp = fopen(tmpfile, "r"); if (fp == NULL) { logit(LOG_ERR, "traceroute command succeeded but cannot open " "%s: %s", tmpfile, strerror(errno)); unlink(tmpfile); return ARMS_ESYSTEM; } n = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { n = sscanf(buf, " %d %63s", &hop, (char *)&host); if (n == 2) { if (trcount <= 0) break; tr->hop = hop; snprintf(tr->addr, sizeof(tr->addr), "%s", host); tr++; trcount--; } } fclose(fp); unlink(tmpfile); if (n == 2) return 0; else return ARMS_ESYSTEM; }
/** Main execution routine @param argc Number of args (0) @param argv Args (always empty) */ int main (int argc, char *argv[]) { /* --------------------------------------------------------------------- * Alert! setuid program with root privileges * ---------------------------------------------------------------------*/ /* syslog */ openlog ("odcgi", LOG_PID, LOG_USER); script_env_t env; /* Agent address */ //! @todo: what if eth0 don't exists? snprintf (env.agent_address, MAX_ENV_SIZE, "%s", getip ("eth0")); //! @todo: lots of static variables. Maybe some can be reused to save memory char http_gui[8]; //char http_style[10]; char http_logout[8]; char http_user[256]; char http_pass[256]; char http_session[1024]; char http_noheader[8]; char http_newuser[256]; char http_newpass1[256]; char http_newpass2[256]; char http_deluser[256]; char http_moduser[256]; char http_modpass1[256]; char http_modpass2[256]; char http_modoldpass[256]; char http_getfile[256]; char http_resource[50]; char http_play_mjpg[100]; char http_temp[100]; /* Configuration vars */ FILE *fh; read_config_file (fh, OD_APP_I18N_CONF, lang, "en"); //read_config_file(fh,OD_APP_STYLE_CONF,style,"default"); //read_config_file(fh,OD_APP_SKIN_CONF,skin,"silver"); /* Get HTTP variables */ cgi_t *cgi = cgi_alloc (); cgi_get_param_by_name (cgi, "GUI", http_gui, sizeof (http_gui)); cgi_get_param_by_name (cgi, "LOGOUT", http_logout, sizeof (http_logout)); cgi_get_param_by_name (cgi, "USER", http_user, sizeof (http_user)); cgi_get_param_by_name (cgi, "PASS", http_pass, sizeof (http_pass)); cgi_get_param_by_name (cgi, "HTSESSID", http_session, sizeof (http_session)); cgi_get_param_by_name (cgi, "NOHEADER", http_noheader, sizeof (http_noheader)); cgi_get_param_by_name (cgi, "NEWUSER", http_newuser, sizeof (http_newuser)); cgi_get_param_by_name (cgi, "NEWPASS1", http_newpass1, sizeof (http_newpass1)); cgi_get_param_by_name (cgi, "NEWPASS2", http_newpass2, sizeof (http_newpass2)); cgi_get_param_by_name (cgi, "DELUSER", http_deluser, sizeof (http_deluser)); cgi_get_param_by_name (cgi, "MODUSER", http_moduser, sizeof (http_moduser)); cgi_get_param_by_name (cgi, "MODPASS1", http_modpass1, sizeof (http_modpass1)); cgi_get_param_by_name (cgi, "MODPASS2", http_modpass2, sizeof (http_modpass2)); cgi_get_param_by_name (cgi, "MODOLDPASS", http_modoldpass, sizeof (http_modoldpass)); cgi_get_param_by_name (cgi, "FILE", http_getfile, sizeof (http_getfile)); cgi_get_param_by_name (cgi, "resource", http_resource, sizeof (http_resource)); cgi_get_param_by_name (cgi, "play_mjpg", http_play_mjpg, sizeof (http_play_mjpg)); // if (cgi_get_param_by_name(cgi,"style", http_style, sizeof(http_style))==1) // { // //cgi_get_cookie("HTSTYLE", http_style, sizeof(http_style)); // strncpy(style, http_style, sizeof(http_style)); // cgi_http_header_set_cookie("HTSTYLE", style); // } // Si se ha solicitado una hoja de estilo, la entregamos if (cgi_get_param_by_name (cgi, "css", http_temp, sizeof (http_temp)) == 1) { syslog (LOG_NOTICE, "printing style: %s\n", http_temp); odcgi_print_file (http_temp); cgi_free (cgi); return 0; } /* // Si se ha solicitado el javascript específico, lo entregamos if (cgi_get_param_by_name(cgi, "js", http_temp, sizeof(http_temp))==1) { syslog(LOG_NOTICE, "printing script: %s\n", http_temp); odcgi_print_file(http_temp); return 0; } */ if (strlen (http_session) == 0) { cgi_get_cookie ("HTSESSID", http_session, sizeof (http_session)); syslog (LOG_NOTICE, "session from cookie: %s\n", http_session); } /* get gui type */ if (strcmp (http_gui, "XML") == 0) gui = xml; if (strcmp (http_gui, "none") == 0) gui = none; /* login process */ if (odcgi_login (&env, http_user, http_pass, http_session, sizeof (http_session)) == -1) { syslog (LOG_NOTICE, "login failed: %s-%s\n", http_user, http_pass); cgi_free (cgi); return -1; } // syslog(LOG_NOTICE, "env.user: %s\n", env.user); // syslog(LOG_NOTICE, "http_user: %s\n", http_user); /* check logout */ if (odcgi_logout (&env, http_logout)) { cgi_free (cgi); return -1; } /* --------------------------------------------------------------------- * Login OK: odcgi is setuid root * --------------------------------------------------------------------- */ //syslog(LOG_NOTICE, "[odcgi] userid: %d\n", getuid()); /* root has not access */ if (odcgi_check_root (http_user)) { cgi_free (cgi); return -1; } /* --------------------------------------------------------------------- * Login OK: * + admin has root privileges * + normal user has Linux privileges * --------------------------------------------------------------------- */ syslog (LOG_NOTICE, "[odcgi] user: %s, uid: %d, guid: %d\n", env.user, getuid (), getgid ()); /* NO USER MANAGEMENT FUNCTIONS IN // adds a new user if (odcgi_add_user (http_newuser, http_newpass1, http_newpass2) == -1) { cgi_free (cgi); return -1; } // delete user if (odcgi_del_user (http_deluser) == -1) { cgi_free (cgi); return -1; } // modify user password if (odcgi_mod_user (http_moduser, http_modoldpass, http_modpass1, http_modpass2) == -1) { cgi_free (cgi); return -1; } */ /* set session */ /* Privilege separation: drop root privileges */ // syslog(LOG_NOTICE, "set session %s\n", http_session); // syslog(LOG_NOTICE, "[odcgi] session_set_ids user: %s\n", env.user); session_set_ids (env.user); syslog (LOG_NOTICE, "[odcgi] dropped privileges user: %s, uid: %d, guid: %d\n", env.user, getuid (), getgid ()); /* File reference with user permissions applied */ if (strlen (http_getfile) > 5) { char buffer[1024] = "/media/"; strcat (buffer, http_getfile); if (http_send_file (buffer)) { cgi_free (cgi); return 0; } else { //! @todo Mostrar error } } /* play mjpg file */ if (strlen (http_play_mjpg) > 3) { syslog (LOG_NOTICE, "play: %s\n", http_play_mjpg); mjpg_play (http_play_mjpg); cgi_free (cgi); return 0; } switch (gui) { case xml: cgi_http_header_begin ("text/xml"); break; case html: cgi_http_header_begin ("text/html"); break; default: cgi_http_header_begin ("text/plain"); } /* Resource reference */ //TODO Verificar permisos de usuario if (strlen (http_resource) > 3) { syslog (LOG_NOTICE, "Serving resource %s\n", http_resource); if (mjpg_streaming_rsc (http_resource)) { cgi_free (cgi); return 0; } else { //printf("<div id='connfail'><p class='error'>%s</p></div>\n", // T(ODCGI_ERROR__CONNECTION_FAILURE)); cgi_free (cgi); return 0; } } syslog (LOG_NOTICE, "1.session: %s\n", http_session); cgi_http_header_set_cookie ("HTSESSID", http_session); // cgi_get_cookie("HTSTYLE", style, sizeof(style)); // cgi_http_header_set_cookie("HTSTYLE", style); cgi_http_header_end (); /* --------------------------------------------------------------------- * User privileges * ---------------------------------------------------------------------*/ size_t len = cgi->decoded_url->size; char path_info[256 + len]; path_info[0] = 0; sstrncpy (path_info, cgi_get_path_info (cgi), sizeof (path_info)); syslog (LOG_NOTICE, "path_info %s - %d\n", path_info, strlen (path_info)); // If any POST/GET vars matches with submit_X.sh, X.sh is the target // then replace 'path_info'. char options[256 + len]; int index = 0; char varname[256]; char varvalue[256 + len]; int has_option = 0; char scriptname[256] = ""; char path[256 + len]; path[0] = 0; while (cgi_get_param_by_index (cgi, index, varname, sizeof (varname), varvalue, sizeof (varvalue))) { // Replace "+" for " " for (int i=0;i<sizeof(varvalue);i++) { if (varvalue[i]=='+') varvalue[i]=' '; } syslog (LOG_DEBUG, "CGIParam %d %s=%s\n", index, varname, varvalue); if (strcmp (varname, "GUI") == 0) { // Ignore } else if (strcmp (varname, "odcgioptionsel") == 0) { sstrncat (options, varvalue, sizeof (options)); sstrncat (options, " ", sizeof (options)); has_option = 1; } else if (strncmp (varname, "submit_", 7) == 0) { syslog (LOG_NOTICE, "Submit redirection found at %s\n", varname); sstrncpy (scriptname, varname + 7, sizeof (scriptname)); //sstrncpy(path_info, scriptname, sizeof(path_info)); snprintf (path, sizeof (path), "/usr/local/opendomo/%s", scriptname); syslog (LOG_DEBUG, "debugging %s - %s [%s]\n", scriptname, path, options); break; } index++; } /* Check PATH variable */ if (strlen (path_info) == 0) strcpy (path_info, "/"); /* filters */ if (!match (path_info, "^/[a-záéíóúàèäëïöüñçA-ZÁÉÍÓÚÀÈÄËÏÖÜÑÇ0-9_/]*\\.{0,1}[a-záéíóúàèäëïöüñçA-ZÁÉÍÓÚÀÈÄËÏÖÜÑÇ0-9_/+ =?:]*$")) { odcgi_print_header ("error", env.user); syslog (LOG_ERR, "%s\n", ODCGI_ERROR__INVALID_PATH); odcgi_msg_error (ODCGI_ERROR__INVALID_PATH, "Invalid character found in the command."); printf ("\n<!-- PATH_INFO: %s-->\n", path_info); odcgi_print_footer ("", 0, cgi); cgi_free (cgi); return -1; } int err = 0; char *param_regex = "[$;'\\\"]"; if (strstr (cgi_get_query_string (cgi), "..")) err = 1; else if (strstr (cgi_get_decoded_url (cgi), "..")) err = 2; else if (strlen (cgi_get_query_string (cgi)) > 0 && match (cgi_get_query_string (cgi), param_regex)) err = 3; else if (strlen (cgi_get_decoded_url (cgi)) > 0 && match (cgi_get_decoded_url (cgi), param_regex)) err = 4; if (err!=0) { odcgi_print_header ("error", env.user); syslog (LOG_ERR, "%s\n", ODCGI_ERROR__INVALID_PATH); odcgi_msg_error (ODCGI_ERROR__INVALID_PATH, "Invalid character found in the parameters."); printf ("\n<!-- PATH ERROR: %d (not allowed) \n\t%s \n\t %s -->\n", err, cgi_get_query_string (cgi), cgi_get_decoded_url (cgi)); odcgi_print_footer ("", 0, cgi); cgi_free (cgi); return -1; } // If PATH is not modified, use the default path in CONF_DIR. if (path[0] == 0) { snprintf (path, sizeof (path), "%s/%s", OD_CFG_ROOT_DIR, path_info); } /* root directory */ if (chdir (OD_CFG_ROOT_DIR) != 0) { odcgi_print_header ("error", env.user); syslog (LOG_ERR, "%s\n", ODCGI_ERROR__ROOT_PATH_ACCESS); odcgi_msg_error (ODCGI_ERROR__ROOT_PATH_ACCESS, "Cannot access the configuration directory. " "Missing privileges or misconfiguration"); odcgi_print_footer ("", 0, cgi); cgi_free (cgi); return -1; } char name[256 + len]; char value[256 + len]; char prename[256 + len]; char *shname; string_t *cmd = string_alloc (""); file_t fs; strcpy (scriptname, basename (path)); /* HTML-head begin */ odcgi_print_header (scriptname, env.user); printf ("<!-- path: %s, path_info: %s-->\n", path, path_info); /* Check NOHEADER */ if ((gui == html) && (atoi (http_noheader) != 1)) { string_assign_str (cmd, "/usr/bin/categories.sh "); string_append (cmd, path_info); script_exec (cmd->str, "header", &env); if (strlen (path_info) < 2) { printf (" <div class='applicationTitle'><h1>OpenDomo</h1></div>\n"); } else { printf (" <div class='root'><a href='" OD_URI "/'> </a></div>\n"); } } sstrncpy (prename, path, sizeof (prename)); shname = strtok (prename, " "); file_set_filename (&fs, shname); strcpy (scriptname, basename (path)); /* if dir: list contents */ if (file_is_dir (&fs)) { string_assign_str (cmd, "/usr/bin/list.sh "); string_append (cmd, path_info); string_append (cmd, " contents"); script_exec (cmd->str, "main", &env); } else { /* if file: execute */ // The path might be a redirection (no actual link in ..opendomo/root/) if (!file_is_file (&fs)) { snprintf (path, sizeof (path), "/usr/local/opendomo/%s", basename (scriptname)); printf ("\n<!-- debug paths: %s / %s [%s] -->\n", path, path_info, scriptname); file_set_filename (&fs, path); if (!file_is_file (&fs)) // If it's still not a valid path, abort { odcgi_msg_error (ODCGI_ERROR__SCRIPT_NOT_FOUND, "The script was not found. " "Maybe the function you are requiring " "is not installed in this system"); printf ("<!-- BASENAME: %s -->\n", basename (scriptname)); odcgi_print_footer ("", 0, cgi); cgi_free (cgi); return 1; } } //printf("<!-- debug path: %s -->\n", path); //char *p = strrchr(path, '/'); if (has_option /*&& p */ ) { string_assign_str (cmd, path); string_append (cmd, " "); string_append (cmd, options); } else { string_assign_str (cmd, path); string_append (cmd, " "); } printf ("\n<!-- decoded_url: %s \n\tquery_string: %s-->\n", cgi->decoded_url->str, cgi->query_string->str); int i = 0; while (cgi_get_param_by_index (cgi, i++, name, sizeof (name), value, sizeof (value))) { if (strcmp (name, ODCGI_SESSION_NAME) == 0) { // Ignoring session name var ... } else if (strncmp (name, "GUI", 3) == 0) { // Ignoring GUI param } else if (strncmp (name, "submit_", 7) == 0) { // Ignoring possible submit redirection ... } else { //for (i = 0; i < sizeof(value); i++){ // if (value[i]=='+') value[i]=' '; //} // Avoid overwritting a defined environment var if (getenv (name) == NULL) setenv (name, value, 1); string_append (cmd, " \""); string_append (cmd, value); string_append (cmd, "\" "); } } string_replace (cmd, "+", " "); string_replace (cmd, "'", "'"); printf ("<!-- cmd (file): %s -->\n", cmd->str); //fflush(stdout); // Force flush, otherwise an error will preceed stdout // Check the returned value of script_exec() int ret = script_exec (cmd->str, "main", &env); if (ret != 0) { /* else: empty div */ printf ("<div id='main'><p class='error'>%s</p></div>", ODCGI_ERROR__SCRIPT_NOT_FOUND); } } /* Print scripts */ //odcgi_print_script(path); DEPRECATED /* HTML end */ if (atoi (http_noheader) != 1) { odcgi_print_footer ("", BUTTON_LOGOUT + BUTTON_DEBUG, cgi); } string_free (cmd); cgi_free (cgi); closelog (); return 0; }