123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /* tsiproxy request handling */
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <unistd.h>
- #include <string.h>
- #include <signal.h>
- #include <netdb.h>
- #include <pthread.h>
- #include <regex.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <sys/types.h>
-
- #include <fcntl.h>
- #include <errno.h>
-
- #include "libfuncs/libfuncs.h"
-
- #include "data.h"
- #include "conf.h"
- #include "commands.h"
- #include "request.h"
- #include "proxy_common.h"
-
- extern LIST *netconf;
-
- extern regex_t request_get;
- extern regex_t request_authmatch;
-
- extern CONFIG *config;
- extern STATS allstats;
-
- #define FREE_DATA { FREE(path); FREE(IP); FREE(agent); FREE(buf); }
- #define NEXT_CLIENT { FREE_DATA; pthread_exit(0); }
- #define SHUTDOWN_CLIENT { FREE_DATA; shutdown_fd(&clientsock); pthread_exit(0); }
- #define BUF_SIZE 1024
-
- void process_request(void *in_req) {
- request_info *req = (request_info *)in_req;
- regmatch_t res[8];
- uint32_t src_ip;
- char *path=NULL, *IP=NULL, *agent=NULL, *buf=NULL;
- unsigned long client_id = 0;
- int client_udp_port = 0;
- int smart_client = 0;
- int clientsock = req->clientsock;
- struct sockaddr_in client = req->client;
- time_t expire = -1;
- acl_t acl;
- FREE(req);
-
- buf = calloc(1, BUF_SIZE);
- if (!buf) {
- log_perror("Can't allocate buffer", errno);
- SHUTDOWN_CLIENT;
- }
-
- IP=strdup(inet_ntoa(client.sin_addr));
- src_ip = client.sin_addr.s_addr;
-
- if (fdgetline(clientsock, buf, BUF_SIZE-1)<=0) {
- SHUTDOWN_CLIENT;
- }
-
- if (regexec(&request_get,buf,2,res,0)==REG_NOMATCH) {
- send_501_not_implemented(clientsock);
- SHUTDOWN_CLIENT;
- }
-
- buf[res[1].rm_eo]=0;
- chomp(buf+res[1].rm_so);
- if (buf[res[1].rm_eo-1]=='/') buf[res[1].rm_eo-1]=0;
- path = strdup(buf+res[1].rm_so);
- int plen = strlen(path);
- {
- int k = 0;
- int qmarkpos = 0;
- int esc_7e = 2; // max replaces
- int esc_2b = 32; // max replaces
- int esc_2c = 8; // max replaces
- while (k < plen) {
- /* Fix escaped symbols only when it's safe */
- if (path[k]=='%' && k+2 <= plen) {
- int mv = 0;
- if (esc_7e >= 0 && path[k+1]=='7' && (path[k+2]=='E' || path[k+2]=='e')) { /* %7E -> ~ */
- path[k] = '~';
- esc_7e--;
- mv = 1;
- }
- if (esc_2b >= 0 && path[k+1]=='2' && (path[k+2]=='B' || path[k+2]=='b')) { /* %2B -> + */
- path[k] = '+';
- esc_2b--;
- mv = 1;
- }
- if (esc_2c >= 0 && path[k+1]=='2' && (path[k+2]=='C' || path[k+2]=='c')) { /* %2C -> , */
- path[k] = ',';
- esc_2c--;
- mv = 1;
- }
- if (mv) {
- memmove(&path[k+1], &path[k+3], plen-(k+2));
- plen -= 2;
- }
- }
- /* Bugfix for Windows Media Player. If path have // sequence
- (in base64 it is happening) WMP send just one / thus invalidating signature
- To fix this, URL generator replaces // with /_ so now we change _ back to / */
- if (path[k] == '_')
- path[k] = '/';
- /* Some shitty player replaces // with /~ */
- if (path[k] == '~')
- path[k] = '/';
- /* Leave only "safe" characters */
- if (path[k] < '*' || path[k] > 'z' || path[k]=='`')
- path[k] = '*';
- if (path[k] == '?')
- qmarkpos = k;
- k++;
- }
- if (qmarkpos && qmarkpos < plen) {
- path[qmarkpos] = 0;
- client_udp_port = atoi(path+qmarkpos+1);
- }
- }
- while (fdgetline(clientsock, buf, BUF_SIZE-1) > 0) {
- if (buf[0] == '\n' || buf[0] == '\r') // End of headers
- break;
- if (strstr(buf, "X-Smart-Client: yes")==buf) {
- smart_client = 1;
- }
- if (memcmp(buf,"User-Agent: ",12)==0 && strlen(buf) > 12) {
- unsigned int k = 0;
- agent=chomp(strdup(buf+12));
- while(k<strlen(agent)) {
- if (agent[k] < 32 || agent[k] > 122 || agent[k]==96) /* Do not allow ( < && > z && ` */
- agent[k]=' ';
- k++;
- }
- }
- }
-
- int pathlen = strlen(path);
- if (!pathlen) {
- send_302_redirect(clientsock, "https://georgi.unixsol.org/");
- SHUTDOWN_CLIENT;
- }
-
- int acl_found = acl_search(netconf, client.sin_addr.s_addr, &acl);
-
- if (!acl_found) {
- LOGf("DENY : Access denied | IP: %s Path: /%s Agent: %s\n", IP, path, agent);
- send_403_forbidden_msg(clientsock, "access-denied");
- SHUTDOWN_CLIENT;
- }
-
- if (strncmp(path,"ping",4)==0) {
- run_ping(clientsock, acl, src_ip, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"stats",5)==0) {
- show_stats(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"info",4)==0) {
- show_info(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"readinfo",8)==0) {
- read_info(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"netconf",7)==0) {
- run_netconf(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"chanconf",8)==0) {
- run_chanconf(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"getnetconf",10)==0) {
- run_getnetconf(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"getchanconf",10)==0) {
- run_getchanconf(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"livecheck",9)==0) {
- run_livecheck(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
- if (strncmp(path,"channels",8)==0) {
- run_channels(clientsock, acl, IP);
- SHUTDOWN_CLIENT;
- }
-
- if (!is_ext(path, ".asf") && !is_ext(path, ".mpg") && !is_ext(path, ".ts")) {
- if (!is_ext(path, ".ico") && // favicon.ico
- !is_ext(path, ".txt") && // robots.txt
- !is_ext(path, ".asx") && // Playlists
- !is_ext(path, ".m3u") && // Playlists
- !is_ext(path, ".smi") && // Subtitles
- !is_ext(path, ".ass") &&
- !is_ext(path, ".wse") &&
- !is_ext(path, ".idx") &&
- !is_ext(path, ".psb") &&
- !is_ext(path, ".srt") &&
- !is_ext(path, ".ssa") &&
- !is_ext(path, ".sub") &&
- !is_ext(path, ".ASF") && // some crap player desides to UPPERCASE the request
- !is_ext(path, ".wmv") && // No wmv files here
- !is_ext(path, "atus") && // apstatus
- !is_ext(path, ".exe") && // ShitZ
- !is_ext(path, ".php") &&
- !is_ext(path, ".pl") &&
- !is_ext(path, ".dll"))
- {
- LOGf("404 : File not found | IP: %s Path: /%s Agent: %s\n", IP, path, agent);
- }
- send_404_not_found(clientsock);
- SHUTDOWN_CLIENT;
- }
-
- if (config_redirect_enabled(config, clientsock, path)) {
- SHUTDOWN_CLIENT;
- }
-
- CLIENT *c = new_client(clientsock, expire, path, IP, agent, client_id, acl, client_udp_port, smart_client);
- process_client(clientsock, c);
-
- NEXT_CLIENT;
- }
|