/* * Reads an HTTP request from stream (fd), and writes an HTTP response * containing: * * 1) If user requested an existing file, respond with the file * 2) If user requested a directory and index.html exists in the directory, * send the index.html file. * 3) If user requested a directory and index.html doesn't exist, send a list * of files in the directory with links to each. * 4) Send a 404 Not Found response. */ void handle_files_request(int fd) { struct http_request*request=http_request_parse(fd); char*fullpath,*fullfullpath; struct stat st; if(0==strcmp("GET",request->method)){ fullpath=conc(server_files_directory,request->path); if(0==stat(fullpath,&st)){ // file/dir exists if(S_ISREG(st.st_mode)){ // is file http_send_file(fd,fullpath); }else if(S_ISDIR(st.st_mode)){ // is dir fullfullpath=conc(fullpath,"/index.html"); if(0==stat(fullfullpath,&st)){ // has an index.html http_send_file(fd,fullfullpath); }else{ // hasnt. list files DIR*d=opendir(fullpath); struct dirent*di; http_start_response(fd,200); http_send_header(fd,"Content-type","text/html"); http_end_headers(fd); while(NULL!=(di=readdir(d))) http_send_anchor(fd,di->d_name); } free(fullfullpath); } }else{ // doesnt exist. error 404 http_start_response(fd,404); http_send_header(fd,"Content-type","text/html"); http_end_headers(fd); http_send_string(fd,"<center><p>ERROR 404</p></center>"); } free(fullpath); } }
int cwmp_agent_upload_file(upload_arg_t * ularg) { int faultcode = 0; FUNCTION_TRACE(); char * fromfile; if(strcpy(ularg->filetype, "1 Vendor Configuration File") == 0) { //根据实际情况, 修改这里的配置文件路径 fromfile = "/tmp/mysystem.cfg"; } else if(strcpy(ularg->filetype, "2 Vendor Log File") == 0) { //根据实际情况, 修改这里的配置文件路径 fromfile = "/tmp/mysystem.log"; } else { fromfile = "/tmp/mysystem.cfg"; } faultcode = http_send_file(fromfile, ularg->url); if(faultcode != CWMP_OK) { faultcode = 9001; } return faultcode; }
void http_thread_work(void *arg) { struct http_job *job = arg; struct stat st; if (stat(job->filepath, &st) == -1){ http_not_found(job->fd); return; } if (S_ISDIR(st.st_mode)){ http_show_dir(job->fd, job->filepath); } if (S_ISREG(st.st_mode)){ http_send_file(job->fd, job->filepath); } if (strcasecmp(walkerconf[THREADNUMBER].value, "0")!=0) close(job->fd); free(job); return ; }
DWORD WINAPI http_do_request(void *lPtr) { socket_conn* conn = (socket_conn*)lPtr; if(conn == 0) return 0; printf("[%08x]new connection\n", GetCurrentThreadId()); while(1) { int keepalive = 0; dynamic_object * req = dynamic_create(); if(http_read_request(conn, req) == 0) { dynamic_delete(req); break; } char* path = dynamic_get_string(dynamic_map_find(req, "PATH")); char* method = dynamic_get_string(dynamic_map_find(req, "METHOD")); char* connection = dynamic_get_string(dynamic_map_find(req, HTTP_HEADER_CONNECTION)); if(connection && strcmp(connection, "keep-alive")==0) keepalive = 1; printf("[%08x]%s %s\n", GetCurrentThreadId(), method, path); if(strcmp(path, "/hello") == 0) { char* html = "<html><body>Hello World!</body></html>"; int htmllen = strlen(html); dynamic_object * res = dynamic_create(); dynamic_string_printf(dynamic_map_insert(res, HTTP_HEADER_CONTENT_LENGTH), "%d", htmllen); dynamic_set_string(dynamic_map_insert(res, HTTP_HEADER_CONTENT_TYPE), "text/html"); http_send_response(conn, 200, res); write_socket(conn, html, htmllen, -1); dynamic_delete(res); }else { http_send_file(conn, req); } dynamic_delete(req); if(keepalive == 0) break; } close_socket(conn); printf("[%08x]close connection\n", GetCurrentThreadId()); return 0; }
void serve(int sockfd) { char buf[BUF_LEN]; read(sockfd, buf, BUF_LEN); if(!strncmp(buf, "GET", 3)) { char *file = buf+5; char *space = strchr(file, ' '); *space = '\0'; http_send_file(file, sockfd); } else { printf("unsupported request\n"); return; } }
/* Called by: */ int http_decode(struct hi_thr* hit, struct hi_io* io) { struct hi_pdu* req = io->cur_pdu; char* url; char* url_lim = 0; char* p = req->m; int n = req->ap - p; if (n < HTTP_MIN_PDU_SIZE) { /* too little, need more */ req->need = HTTP_MIN_PDU_SIZE - n; return 0; } if (memcmp(p, "GET /", sizeof("GET /")-1)) { ERR("Not a GET HTTP PDU. fd(%x). Got(%.*s)", io->fd, HTTP_MIN_PDU_SIZE, req->m); return HI_CONN_CLOSE; } for (p += 5; p < req->ap - (sizeof(" HTTP/1.0")-2); ++p) if (!memcmp(p, " HTTP/1.0\n", sizeof(" HTTP/1.0")-1)) { /* Found end of URL */ url = req->m + 4; url_lim = p; break; } if (!url_lim) { req->need = 1; return 0; } /* *** Proper processing of content-length and setting need to length of PDU is still needed. */ D("need=%d len=%d buf(%.*s)", req->need, (int)(req->ap-req->m), (int)(req->ap-req->m), req->m); hi_add_to_reqs(hit, io, req, HTTP_MIN_PDU_SIZE); /* 01234567890 * GET / HTTP/1.0 */ switch (req->m[6]) { case 'a': http_send_data(hit, io, req, url_lim-url, url); break; case 'b': http_send_file(hit, io, req, url_lim-url, url); break; /* *** */ default: http_send_err(hit, io, req, 500, "Error"); break; } return HI_CONN_CLOSE; /* HTTP/1.0 without keep-alive: close connection after every req-resp */ }
void APISelect(void *data) { OPS("### @ API : Accept Success - Thread[%d]", pthread_self()); // struct data qqclient* qq = ((void**)data)[0]; qq->api_select_count ++ ; apiclient* apis = ((void**)data)[1]; int client = apis->sock; pthread_mutex_unlock(&apis->mxsock); // Request char *buffer; NEW(buffer, REQUEST_BUFFER); // Select 模型读取请求 fd_set fdRead; struct timeval fdRTV = {1, 0}; FD_ZERO(&fdRead); FD_SET(client, &fdRead); switch ( select(client, &fdRead, NULL, NULL, &fdRTV) ) { default: if ( FD_ISSET(client, &fdRead) ) { recv(client, buffer, REQUEST_BUFFER, 0); } } if ( strlen(buffer) < 9 ) { OPS("### @ API : Request Unavailable."); DEL(buffer); return; } // Request Test DBG("##### Request Begin #####\n%s\n##### Request End #####\n", buffer); char *http; NEW(http, 16); mid_value(buffer, "GET ", " HTTP/1.1", http, 16); if ( strstr(http, "/v?") >0 ) { // 验证码读取 char *uid, *file; NEW(uid, 18); NEW(file, 32); if ( strstr(http, "&") > 0 ) { mid_value(http, "/v?", "&", uid, 18); } else { mid_value(http, "/v?", NULL, uid, 18); } sprintf(file, "./verify/%s.png", uid); http_send_file(client, file); DEL(uid); DEL(file); DEL(http); DEL(buffer); return; } else if ( strstr(http, "/send?") > 0 ) { // 发送自定义信息 char *msg; NEW(msg, REQUEST_BUFFER); mid_value(buffer, "GET /send?", " HTTP/1.1", msg, REQUEST_BUFFER); api_callback_build("http.send", msg); DEL(msg); http_send(client, "Message Sends OK."); DEL(http); DEL(buffer); return; } else if ( strlen(http) > 0 ) { http_send(client, "QQRobot API Server."); DEL(http); DEL(buffer); return; } DEL(http); char *api; NEW(api, API_BUFFER); mid_value(buffer, "API ", " MOYO/1.1", api, API_BUFFER); if (strlen(api) == 0) { http_send(client, "API IS EMPTY"); DEL(api); DEL(buffer); return; } // API Commands char *response; NEW(response, RESPONSE_BUFFER); // Check SecKey char *seckey; NEW(seckey, 255); mid_value(buffer, "<seckey>", "</seckey>", seckey, 255); if ( strcmp(apis->APISeckey, seckey)!=0 ) { strcat(response, "ACCESS DENIED"); OPS("### @ API : Denied of : %s", api); DEL(seckey); goto API_RESPONSE; } DEL(seckey); // API Runs OPS("### @ API : Command of : %s ...Runs ...", api); // ##### API of login ##### if ( stricmp(api, "login.create")==0 ) { char *uid, *password; NEW(uid, 10); NEW(password, 32); mid_value(buffer, "<uid>", "</uid>", uid, 10); mid_value(buffer, "<password>", "</password>", password, 32); strcat(response, myqq_login(atoi(uid), password)); //printf("Done of %s.\n", api); DEL(uid); DEL(password); } else if ( stricmp(api, "login.destroy")==0 ) { strcat(response, myqq_logout()); //printf("Done of %s.\n", api); } else if ( stricmp(api, "login.verify")==0 ) { char *vcode; NEW(vcode, 4); mid_value(buffer, "<verify>", "</verify>", vcode, 4); if ( qq->process == P_VERIFYING ) { qqclient_verify(qq, vcode); OPS("### @ API : [Input] Verify Code : %s", vcode); strcat(response, myqq_resume_login()); } else { strcat(response, "DONT NEED"); } //printf("Done of %s.\n", api); DEL(vcode); } else if ( stricmp(api, "login.check")==0 ) { strcat(response, myqq_check_login(qq)); //printf("Done of %s.\n", api); } // ##### API of buddy ##### else if ( stricmp(api, "buddy.name")==0 ) { char *uid; NEW(uid, 10); mid_value(buffer, "<uid>", "</uid>", uid, 10); strcat(response, myqq_get_buddy_name(qq, atoi(uid))); //printf("Done of %s.\n", api); DEL(uid); } else if ( stricmp(api, "buddy.send")==0 ) { char *uid, *message; NEW(uid, 10); NEW(message, SEND_MESSAGE_SIZE); mid_value(buffer, "<uid>", "</uid>", uid, 10); mid_value(buffer, "<message>", "</message>", message, SEND_MESSAGE_SIZE); if ( myqq_send_im_to_buddy(qq, atoi(uid), message, 0) ) { strcat(response, "SEND FAILED"); } else { strcat(response, "SEND SUCCESS"); } //printf("Done of %s.\n", api); DEL(uid); DEL(message); } else if ( stricmp(api, "buddy.info")==0 ) { char *uid; NEW(uid, 10); mid_value(buffer, "<uid>", "</uid>", uid, 10); char *info; NEW(info, KB(4)); myqq_get_buddy_info(qq, atoi(uid), info, KB(4)); strcat(response, info); //printf("Done of %s.\n", api); DEL(uid); DEL(info); } else if ( stricmp(api, "buddy.list")==0 ) { char *online; NEW(online, 3); mid_value(buffer, "<online>", "</online>", online, 3); char *info; NEW(info, BUDDY_BUF_SIZE); if ( stricmp(online, "yes")==0 ) { myqq_get_buddy_list(qq, info, BUDDY_BUF_SIZE, 1); } else { myqq_get_buddy_list(qq, info, BUDDY_BUF_SIZE, 0); } strcat(response, info); //printf("Done of %s.\n", api); DEL(online); DEL(info); } // ##### API of qun ##### else if ( stricmp(api, "qun.name")==0 ) { char *gid; NEW(gid, 10); mid_value(buffer, "<gid>", "</gid>", gid, 10); strcat(response, myqq_get_qun_name(qq, atoi(gid))); //printf("Done of %s.\n", api); DEL(gid); } else if ( stricmp(api, "qun.send")==0 ) { char *gid, *message; NEW(gid, 10); NEW(message, SEND_MESSAGE_SIZE); mid_value(buffer, "<gid>", "</gid>", gid, 10); mid_value(buffer, "<message>", "</message>", message, SEND_MESSAGE_SIZE); if ( myqq_send_im_to_qun(qq, atoi(gid), message, 0) ) { strcat(response, "SEND FAILED"); } else { strcat(response, "SEND SUCCESS"); } //printf("Done of %s.\n", api); DEL(gid); DEL(message); } else if ( stricmp(api, "qun.buddy.name")==0 ) { char *gid, *uid; NEW(gid, 10); NEW(uid, 10); mid_value(buffer, "<gid>", "</gid>", gid, 10); mid_value(buffer, "<uid>", "</uid>", uid, 10); strcat(response, myqq_get_qun_member_name(qq, atoi(gid), atoi(uid))); //printf("Done of %s.\n", api); DEL(gid); DEL(uid); } else if ( stricmp(api, "qun.info")==0 ) { char *gid; NEW(gid, 10); mid_value(buffer, "<gid>", "</gid>", gid, 10); char *info; NEW(info, KB(4)); myqq_get_qun_info(qq, atoi(gid), info, KB(4)); strcat(response, info); //printf("Done of %s.\n", api); DEL(gid); DEL(info); } else if ( stricmp(api, "qun.list")==0 ) { char *info; NEW(info, QUN_BUF_SIZE); myqq_get_qun_list(qq, info, QUN_BUF_SIZE); strcat(response, info); //printf("Done of %s.\n", api); DEL(info); } else if ( stricmp(api, "qun.buddy.list")==0 ) { char *gid, *online; NEW(gid, 10); NEW(online, 3); mid_value(buffer, "<gid>", "</gid>", gid, 10); mid_value(buffer, "<online>", "</online>", online, 3); char *info; NEW(info, BUDDY_BUF_SIZE); if ( stricmp(online, "yes")==0 ) { myqq_get_qun_member_list(qq, atoi(gid), info, BUDDY_BUF_SIZE, 1); } else { myqq_get_qun_member_list(qq, atoi(gid), info, BUDDY_BUF_SIZE, 0); } strcat(response, info); //printf("Done of %s.\n", api); DEL(gid); DEL(online); DEL(info); } // ##### API of me ##### else if ( stricmp(api, "me.sleep")==0 ) { char *power; NEW(power, 3); mid_value(buffer, "<power>", "</power>", power, 3); if ( strcmp(power, "on")==0 ) { apis->APISleep = 1; } else { apis->APISleep = 0; } strcat(response, "SWITCH SUCCESS"); //printf("Done of %s.\n", api); DEL(power); } else if ( stricmp(api, "me.list.update")==0 ) { qun_update_all(qq); buddy_update_list(qq); group_update_list(qq); if ( qqclient_wait(qq, 10)<0 ) { strcat(response, "UPDATE FAILED"); } else { strcat(response, "UPDATE SUCCESS"); } //printf("Done of %s.\n", api); } else if ( stricmp(api, "me.autoreply")==0 ) { char *power; NEW(power, 3); mid_value(buffer, "<power>", "</power>", power, 3); if ( strcmp(power, "on")==0 ) { myqq_auto_reply(1); } else { myqq_auto_reply(0); } strcat(response, "SWITCH SUCCESS"); //printf("Done of %s.\n", api); DEL(power); } else if ( stricmp(api, "me.status.update")==0 ) { char *status; NEW(status, 6); mid_value(buffer, "<status>", "</status>", status, 6); if( strcmp( status, "away") == 0 ) qqclient_change_status( qq, QQ_AWAY ); else if( strcmp( status, "online") == 0 ) qqclient_change_status( qq, QQ_ONLINE ); else if( strcmp( status, "hidden") == 0 ) qqclient_change_status( qq, QQ_HIDDEN ); else if( strcmp( status, "killme") == 0 ) qqclient_change_status( qq, QQ_KILLME ); else if( strcmp( status, "busy") == 0 ) qqclient_change_status( qq, QQ_BUSY ); strcat(response, "UPDATE SUCCESS"); //printf("Done of %s.\n", api); DEL(status); } else if ( stricmp(api, "me.buddy.add")==0 ) { char *uid, *message; NEW(uid, 10); NEW(message, 50); mid_value(buffer, "<uid>", "</uid>", uid, 10); mid_value(buffer, "<message>", "</message>", message, 50); qqclient_add(qq, atoi(uid), message); strcat(response, "ADD SUCCESS"); //printf("Done of %s.\n", api); DEL(uid); DEL(message); } else if ( stricmp(api, "me.buddy.del")==0 ) { char *uid; NEW(uid, 10); mid_value(buffer, "<uid>", "</uid>", uid, 10); qqclient_del(qq, atoi(uid)); strcat(response, "DELETE SUCCESS"); //printf("Done of %s.\n", api); DEL(uid); } else { strcat(response, "UNKNOWN API COMMAND"); OPS("### @ API : Command Unknown : %s", api); } API_RESPONSE: // Send send(client, response, strlen(response), 0); // print OPS("### @ API : Command of : %s ...Done.", api); // Response Test DBG("##### Response Begin #####\n%s\n##### Response End #####\n", response); // Close shutdown(client, SD_BOTH); closesocket(client); // Clear DEL(response); //DEL(client); pthread_detach(pthread_self()); }
/** 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; }