/** Process an incoming main loop control request @returns non-zero on success, 0 on failure (errno set) **/ int http_control_request(HTTPCNX *http, char *action) { char buffer[1024]; if ( strcmp(action,"resume")==0 ) { exec_mls_resume(TS_NEVER); return 1; } else if ( sscanf(action,"pauseat=%[-0-9%:A-Za-z]",buffer)==1 ) { TIMESTAMP ts; http_decode(buffer); ts = convert_to_timestamp(buffer); if ( ts!=TS_INVALID ) { exec_mls_resume(ts); return 1; } else { output_error("control command '%s' has an invalid timestamp", buffer); return 0; } } else if ( strcmp(action,"shutdown")==0 ) { output_message("server shutdown by client"); exit(XC_SUCCESS); } return 0; }
/* * Decompose a path into the principal, collection, and resource parts. * We manage this as follows: * /principal/collection/resource * For now, the collection can't have directories of its own. * Return zero on failure (no leading slash or memory failure), non-zero * on success. * All pointers will be set. */ int http_paths(const char *in, char **pp, char **cp, char **rp) { const char *p; *pp = *cp = *rp = NULL; /* Strip leading absolute path. */ if ('/' != in[0]) return(0); in++; if (NULL != (p = strchr(in, '/'))) { *pp = malloc(p - in + 1); memcpy(*pp, in, p - in); (*pp)[p - in] = '\0'; in = p + 1; if (NULL != (p = strrchr(in, '/'))) { *cp = malloc(p - in + 1); memcpy(*cp, in, p - in); (*cp)[p - in] = '\0'; in = p + 1; http_decode(in, rp); } else { *cp = strdup(""); http_decode(in, rp); } } else { *pp = strdup(in); *cp = strdup(""); *rp = strdup(""); } if (NULL == *pp || NULL == *cp || NULL == *rp) { kerr(NULL); free(*pp); free(*cp); free(*rp); return(0); } return(1); }
/** * Unescapes the characters of a string to make it a normal string. The * returned string should be freed with #g_free() when no longer needed. * * @param escaped The string. * * @return The unescaped string or NULL on error. **/ gchar *steam_http_uri_unescape(const gchar *escaped) { gchar *ret; gchar *str; g_return_val_if_fail(escaped != NULL, NULL); str = g_strdup(escaped); http_decode(str); ret = g_strdup(str); g_free(str); return ret; }
/** Process an incoming XML data request @returns non-zero on success, 0 on failure (errno set) **/ int http_xml_request(HTTP *http,char *uri) { char arg1[1024]="", arg2[1024]=""; int nargs = sscanf(uri,"%1023[^/=\r\n]/%1023[^\r\n=]",arg1,arg2); char *value = strchr(uri,'='); char buffer[1024]=""; OBJECT *obj=NULL; char *id; /* value */ if (value) *value++; /* decode %.. */ http_decode(arg1); http_decode(arg2); if (value) http_decode(value); /* process request */ switch (nargs) { /* get global variable */ case 1: /* find the variable */ if (global_getvar(arg1,buffer,sizeof(buffer))==NULL) { output_error("global variable '%s' not found", arg1); return 0; } /* assignment, if any */ if (value) global_setvar(arg1,value); /* post the response */ http_format(http,"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); http_format(http,"<globalvar>\n\t<name>%s</name>\n\t<value>%s</value>\n</globalvar>\n", arg1, http_unquote(buffer)); http_type(http,"text/xml"); return 1; /* get object property */ case 2: /* find the object */ id = strchr(arg1,':'); if ( id==NULL ) obj = object_find_name(arg1); else obj = object_find_by_id(atoi(id+1)); if ( obj==NULL ) { output_error("object '%s' not found", arg1); return 0; } /* post the current value */ if ( !object_get_value_by_name(obj,arg2,buffer,sizeof(buffer)) ) { output_error("object '%s' property '%s' not found", arg1, arg2); return 0; } /* assignment, if any */ if ( value && !object_set_value_by_name(obj,arg2,value) ) { output_error("cannot set object '%s' property '%s' to '%s'", arg1, arg2, value); return 0; } /* post the response */ http_format(http,"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<property>\n"); http_format(http,"\t<object>%s</object>\n", arg1); http_format(http,"\t<name>%s</name>\n", arg2); http_format(http,"\t<value>%s</value>\n", http_unquote(buffer)); /* TODO add property type info */ http_format(http,"</property>\n"); http_type(http,"text/xml"); return 1; default: return 0; } return 0; }
/* * Parse the QUERY_STRING for key-value pairs * and store the values into the query structure. */ static void http_parse(struct req *req, const char *qs) { char *key, *val; size_t keysz, valsz; req->q.manpath = NULL; req->q.arch = NULL; req->q.sec = NULL; req->q.query = NULL; req->q.equal = 1; key = val = NULL; while (*qs != '\0') { /* Parse one key. */ keysz = strcspn(qs, "=;&"); key = mandoc_strndup(qs, keysz); qs += keysz; if (*qs != '=') goto next; /* Parse one value. */ valsz = strcspn(++qs, ";&"); val = mandoc_strndup(qs, valsz); qs += valsz; /* Decode and catch encoding errors. */ if ( ! (http_decode(key) && http_decode(val))) goto next; /* Handle key-value pairs. */ if ( ! strcmp(key, "query")) set_query_attr(&req->q.query, &val); else if ( ! strcmp(key, "apropos")) req->q.equal = !strcmp(val, "0"); else if ( ! strcmp(key, "manpath")) { #ifdef COMPAT_OLDURI if ( ! strncmp(val, "OpenBSD ", 8)) { val[7] = '-'; if ('C' == val[8]) val[8] = 'c'; } #endif set_query_attr(&req->q.manpath, &val); } else if ( ! (strcmp(key, "sec") #ifdef COMPAT_OLDURI && strcmp(key, "sektion") #endif )) { if ( ! strcmp(val, "0")) *val = '\0'; set_query_attr(&req->q.sec, &val); } else if ( ! strcmp(key, "arch")) { if ( ! strcmp(val, "default")) *val = '\0'; set_query_attr(&req->q.arch, &val); } /* * The key must be freed in any case. * The val may have been handed over to the query * structure, in which case it is now NULL. */ next: free(key); key = NULL; free(val); val = NULL; if (*qs != '\0') qs++; } }
/* Create a new axel_t structure */ axel_t *axel_new( conf_t *conf, int count, void *url ) { search_t *res; axel_t *axel; url_t *u; char *s; int i; axel = malloc( sizeof( axel_t ) ); memset( axel, 0, sizeof( axel_t ) ); *axel->conf = *conf; axel->conn = malloc( sizeof( conn_t ) * axel->conf->num_connections ); memset( axel->conn, 0, sizeof( conn_t ) * axel->conf->num_connections ); if( axel->conf->max_speed > 0 ) { if( (float) axel->conf->max_speed / axel->conf->buffer_size < 0.5 ) { if( axel->conf->verbose >= 2 ) axel_message( axel, _("Buffer resized for this speed.") ); axel->conf->buffer_size = axel->conf->max_speed; } axel->delay_time = (int) ( (float) 1000000 / axel->conf->max_speed * axel->conf->buffer_size * axel->conf->num_connections ); } if( buffer == NULL ) buffer = malloc( max( MAX_STRING, axel->conf->buffer_size ) ); if( count == 0 ) { axel->url = malloc( sizeof( url_t ) ); axel->url->next = axel->url; strncpy( axel->url->text, (char *) url, MAX_STRING ); } else { res = (search_t *) url; u = axel->url = malloc( sizeof( url_t ) ); for( i = 0; i < count; i ++ ) { strncpy( u->text, res[i].url, MAX_STRING ); if( i < count - 1 ) { u->next = malloc( sizeof( url_t ) ); u = u->next; } else { u->next = axel->url; } } } axel->conn[0].conf = axel->conf; if( !conn_set( &axel->conn[0], axel->url->text ) ) { axel_message( axel, _("Could not parse URL.\n") ); axel->ready = -1; return( axel ); } axel->conn[0].local_if = axel->conf->interfaces->text; axel->conf->interfaces = axel->conf->interfaces->next; strncpy( axel->filename, axel->conn[0].file, MAX_STRING ); http_decode( axel->filename ); if( *axel->filename == 0 ) /* Index page == no fn */ strncpy( axel->filename, axel->conf->default_filename, MAX_STRING ); if( ( s = strchr( axel->filename, '?' ) ) != NULL && axel->conf->strip_cgi_parameters ) *s = 0; /* Get rid of CGI parameters */ if( !conn_init( &axel->conn[0] ) ) { axel_message( axel, axel->conn[0].message ); axel->ready = -1; return( axel ); } /* This does more than just checking the file size, it all depends on the protocol used. */ if( !conn_info( &axel->conn[0] ) ) { axel_message( axel, axel->conn[0].message ); axel->ready = -1; return( axel ); } s = conn_url( axel->conn ); strncpy( axel->url->text, s, MAX_STRING ); if( ( axel->size = axel->conn[0].size ) != INT_MAX ) { if( axel->conf->verbose > 0 ) axel_message( axel, _("File size: %lld bytes"), axel->size ); } /* Wildcards in URL --> Get complete filename */ if( strchr( axel->filename, '*' ) || strchr( axel->filename, '?' ) ) strncpy( axel->filename, axel->conn[0].file, MAX_STRING ); return( axel ); }
static int msn_ns_command( struct msn_handler_data *handler, char **cmd, int num_parts ) { struct im_connection *ic = handler->data; struct msn_data *md = ic->proto_data; if( num_parts == 0 ) { /* Hrrm... Empty command...? Ignore? */ return( 1 ); } if( strcmp( cmd[0], "VER" ) == 0 ) { if( cmd[2] && strncmp( cmd[2], MSNP_VER, 5 ) != 0 ) { imcb_error( ic, "Unsupported protocol" ); imc_logout( ic, FALSE ); return( 0 ); } return( msn_ns_write( ic, handler->fd, "CVR %d 0x0409 mac 10.2.0 ppc macmsgs 3.5.1 macmsgs %s\r\n", ++md->trId, ic->acc->user ) ); } else if( strcmp( cmd[0], "CVR" ) == 0 ) { /* We don't give a damn about the information we just received */ return msn_ns_write( ic, handler->fd, "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user ); } else if( strcmp( cmd[0], "XFR" ) == 0 ) { char *server; int port; if( num_parts >= 6 && strcmp( cmd[2], "NS" ) == 0 ) { b_event_remove( handler->inpa ); handler->inpa = -1; server = strchr( cmd[3], ':' ); if( !server ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } *server = 0; port = atoi( server + 1 ); server = cmd[3]; imcb_log( ic, "Transferring to other server" ); return msn_ns_connect( ic, handler, server, port ); } else if( num_parts >= 6 && strcmp( cmd[2], "SB" ) == 0 ) { struct msn_switchboard *sb; server = strchr( cmd[3], ':' ); if( !server ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } *server = 0; port = atoi( server + 1 ); server = cmd[3]; if( strcmp( cmd[4], "CKI" ) != 0 ) { imcb_error( ic, "Unknown authentication method for switchboard" ); imc_logout( ic, TRUE ); return( 0 ); } debug( "Connecting to a new switchboard with key %s", cmd[5] ); if( ( sb = msn_sb_create( ic, server, port, cmd[5], MSN_SB_NEW ) ) == NULL ) { /* Although this isn't strictly fatal for the NS connection, it's definitely something serious (we ran out of file descriptors?). */ imcb_error( ic, "Could not create new switchboard" ); imc_logout( ic, TRUE ); return( 0 ); } if( md->msgq ) { struct msn_message *m = md->msgq->data; GSList *l; sb->who = g_strdup( m->who ); /* Move all the messages to the first user in the message queue to the switchboard message queue. */ l = md->msgq; while( l ) { m = l->data; l = l->next; if( strcmp( m->who, sb->who ) == 0 ) { sb->msgq = g_slist_append( sb->msgq, m ); md->msgq = g_slist_remove( md->msgq, m ); } } } } else { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } } else if( strcmp( cmd[0], "USR" ) == 0 ) { if( num_parts >= 6 && strcmp( cmd[2], "SSO" ) == 0 && strcmp( cmd[3], "S" ) == 0 ) { g_free( md->pp_policy ); md->pp_policy = g_strdup( cmd[4] ); msn_soap_passport_sso_request( ic, cmd[5] ); } else if( strcmp( cmd[2], "OK" ) == 0 ) { /* If the number after the handle is 0, the e-mail address is unverified, which means we can't change the display name. */ if( cmd[4][0] == '0' ) md->flags |= MSN_EMAIL_UNVERIFIED; imcb_log( ic, "Authenticated, getting buddy list" ); msn_soap_memlist_request( ic ); } else { imcb_error( ic, "Unknown authentication type" ); imc_logout( ic, FALSE ); return( 0 ); } } else if( strcmp( cmd[0], "MSG" ) == 0 ) { if( num_parts < 4 ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } handler->msglen = atoi( cmd[3] ); if( handler->msglen <= 0 ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } } else if( strcmp( cmd[0], "BLP" ) == 0 ) { msn_ns_send_adl_start( ic ); return msn_ns_finish_login( ic ); } else if( strcmp( cmd[0], "ADL" ) == 0 ) { if( num_parts >= 3 && strcmp( cmd[2], "OK" ) == 0 ) { msn_ns_send_adl( ic ); return msn_ns_finish_login( ic ); } else if( num_parts >= 3 ) { handler->msglen = atoi( cmd[2] ); } } else if( strcmp( cmd[0], "PRP" ) == 0 ) { imcb_connected( ic ); } else if( strcmp( cmd[0], "CHL" ) == 0 ) { char *resp; int st; if( num_parts < 3 ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } resp = msn_p11_challenge( cmd[2] ); st = msn_ns_write( ic, -1, "QRY %d %s %zd\r\n%s", ++md->trId, MSNP11_PROD_ID, strlen( resp ), resp ); g_free( resp ); return st; } else if( strcmp( cmd[0], "ILN" ) == 0 || strcmp( cmd[0], "NLN" ) == 0 ) { const struct msn_away_state *st; const char *handle; int cap = 0; if( num_parts < 6 ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } /* ILN and NLN are more or less the same, except ILN has a trId at the start, and NLN has a capability field at the end. Does ILN still exist BTW? */ if( cmd[0][1] == 'I' ) cmd ++; else cap = atoi( cmd[4] ); handle = msn_normalize_handle( cmd[2] ); if( strcmp( handle, ic->acc->user ) == 0 ) return 1; /* That's me! */ http_decode( cmd[3] ); imcb_rename_buddy( ic, handle, cmd[3] ); st = msn_away_state_by_code( cmd[1] ); if( !st ) { /* FIXME: Warn/Bomb about unknown away state? */ st = msn_away_state_list + 1; } imcb_buddy_status( ic, handle, OPT_LOGGED_IN | ( st != msn_away_state_list ? OPT_AWAY : 0 ) | ( cap & 1 ? OPT_MOBILE : 0 ), st->name, NULL ); msn_sb_stop_keepalives( msn_sb_by_handle( ic, handle ) ); } else if( strcmp( cmd[0], "FLN" ) == 0 ) { const char *handle; if( cmd[1] == NULL ) return 1; handle = msn_normalize_handle( cmd[1] ); imcb_buddy_status( ic, handle, 0, NULL, NULL ); msn_sb_start_keepalives( msn_sb_by_handle( ic, handle ), TRUE ); } else if( strcmp( cmd[0], "RNG" ) == 0 ) { struct msn_switchboard *sb; char *server; int session, port; if( num_parts < 7 ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } session = atoi( cmd[1] ); server = strchr( cmd[2], ':' ); if( !server ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } *server = 0; port = atoi( server + 1 ); server = cmd[2]; if( strcmp( cmd[3], "CKI" ) != 0 ) { imcb_error( ic, "Unknown authentication method for switchboard" ); imc_logout( ic, TRUE ); return( 0 ); } debug( "Got a call from %s (session %d). Key = %s", cmd[5], session, cmd[4] ); if( ( sb = msn_sb_create( ic, server, port, cmd[4], session ) ) == NULL ) { /* Although this isn't strictly fatal for the NS connection, it's definitely something serious (we ran out of file descriptors?). */ imcb_error( ic, "Could not create new switchboard" ); imc_logout( ic, TRUE ); return( 0 ); } else { sb->who = g_strdup( msn_normalize_handle( cmd[5] ) ); } } else if( strcmp( cmd[0], "OUT" ) == 0 ) { int allow_reconnect = TRUE; if( cmd[1] && strcmp( cmd[1], "OTH" ) == 0 ) { imcb_error( ic, "Someone else logged in with your account" ); allow_reconnect = FALSE; } else if( cmd[1] && strcmp( cmd[1], "SSD" ) == 0 ) { imcb_error( ic, "Terminating session because of server shutdown" ); } else { imcb_error( ic, "Session terminated by remote server (%s)", cmd[1] ? cmd[1] : "reason unknown)" ); } imc_logout( ic, allow_reconnect ); return( 0 ); } else if( strcmp( cmd[0], "IPG" ) == 0 ) { imcb_error( ic, "Received IPG command, we don't handle them yet." ); handler->msglen = atoi( cmd[1] ); if( handler->msglen <= 0 ) { imcb_error( ic, "Syntax error" ); imc_logout( ic, TRUE ); return( 0 ); } } #if 0 else if( strcmp( cmd[0], "ADG" ) == 0 ) { char *group = g_strdup( cmd[3] ); int groupnum, i; GSList *l, *next; http_decode( group ); if( sscanf( cmd[4], "%d", &groupnum ) == 1 ) { if( groupnum >= md->groupcount ) { md->grouplist = g_renew( char *, md->grouplist, groupnum + 1 ); for( i = md->groupcount; i <= groupnum; i ++ ) md->grouplist[i] = NULL; md->groupcount = groupnum + 1; } g_free( md->grouplist[groupnum] ); md->grouplist[groupnum] = group; }
/* * Parse out key-value pairs from an HTTP request variable. * This can be either a cookie or a POST/GET string, although man.cgi * uses only GET for simplicity. */ static void http_parse(struct req *req, char *p) { char *key, *val, *manroot; int i, legacy; memset(&req->q, 0, sizeof(struct query)); legacy = -1; manroot = NULL; while ('\0' != *p) { key = p; val = NULL; p += (int)strcspn(p, ";&"); if ('\0' != *p) *p++ = '\0'; if (NULL != (val = strchr(key, '='))) *val++ = '\0'; if ('\0' == *key || NULL == val || '\0' == *val) continue; /* Just abort handling. */ if ( ! http_decode(key)) break; if (NULL != val && ! http_decode(val)) break; if (0 == strcmp(key, "expr")) req->q.expr = val; else if (0 == strcmp(key, "query")) req->q.expr = val; else if (0 == strcmp(key, "sec")) req->q.sec = val; else if (0 == strcmp(key, "sektion")) req->q.sec = val; else if (0 == strcmp(key, "arch")) req->q.arch = val; else if (0 == strcmp(key, "manpath")) manroot = val; else if (0 == strcmp(key, "apropos")) legacy = 0 == strcmp(val, "0"); } /* Test for old man.cgi compatibility mode. */ req->q.legacy = legacy > 0; /* * Section "0" means no section when in legacy mode. * For some man.cgi scripts, "default" arch is none. */ if (req->q.legacy && NULL != req->q.sec) if (0 == strcmp(req->q.sec, "0")) req->q.sec = NULL; if (req->q.legacy && NULL != req->q.arch) if (0 == strcmp(req->q.arch, "default")) req->q.arch = NULL; /* Default to first manroot. */ if (NULL != manroot) { for (i = 0; i < (int)req->psz; i++) if (0 == strcmp(req->p[i].name, manroot)) break; req->q.manroot = i < (int)req->psz ? i : -1; } }
int Lua::handle_script_request(struct mg_connection *conn, const struct mg_request_info *request_info, char *script_path) { char buf[64], key[64], val[64]; luaL_openlibs(L); /* Load base libraries */ lua_register_classes(L, true); /* Load custom classes */ lua_pushlightuserdata(L, (char*)conn); lua_setglobal(L, CONST_HTTP_CONN); /* Put the GET params into the environment */ lua_newtable(L); if(request_info->query_string != NULL) { char *query_string = strdup(request_info->query_string); if(query_string) { char *tok, *where; tok = strtok_r(query_string, "&", &where); while(tok != NULL) { /* key=val */ char *equal = strchr(tok, '='); if(equal) { char *decoded_buf; equal[0] = '\0'; if((decoded_buf = http_decode(&equal[1])) != NULL) { //ntop->getTrace()->traceEvent(TRACE_WARNING, "'%s'='%s'", tok, decoded_buf); lua_push_str_table_entry(L, tok, decoded_buf); free(decoded_buf); } } tok = strtok_r(NULL, "&", &where); } free(query_string); } } lua_setglobal(L, "_GET"); /* Like in php */ /* Put the _SESSION params into the environment */ lua_newtable(L); mg_get_cookie(conn, "user", buf, sizeof(buf)); lua_push_str_table_entry(L, "user", buf); mg_get_cookie(conn, "session", buf, sizeof(buf)); lua_push_str_table_entry(L, "session", buf); snprintf(key, sizeof(key), "sessions.%s.ifname", buf); if(ntop->getRedis()->get(key, val, sizeof(val)) < 0) { set_default_if_name_in_session: snprintf(val, sizeof(val), "%s", ntop->getInterfaceId(0)->get_name()); lua_push_str_table_entry(L, "ifname", val); ntop->getRedis()->set(key, val, 3600 /* 1h */); } else { if(ntop->getInterface(val) != NULL) { /* The specified interface still exists */ lua_push_str_table_entry(L, "ifname", val); ntop->getRedis()->expire(key, 3600); /* Extend session */ } else { goto set_default_if_name_in_session; } } lua_setglobal(L, "_SESSION"); /* Like in php */ if(luaL_dofile(L, script_path) != 0) { const char *err = lua_tostring(L, -1); ntop->getTrace()->traceEvent(TRACE_WARNING, "Script failure [%s][%s]", script_path, err); return(send_error(conn, 500 /* Internal server error */, "Internal server error", PAGE_ERROR, script_path, err)); } return(CONST_LUA_OK); }