diff --git a/proxy.c b/proxy.c index c6eadbe..571ee53 100644 --- a/proxy.c +++ b/proxy.c @@ -4,19 +4,12 @@ #include #include #include +#include +#include #include #include #include "structs.h" -#define PROXY_PORT 2020 -#define PROXY_CONN 20 -#define PROXY_MAX_MSGLEN 10*1024 -#define TITLE_DELIM " " - -#define REGEX_MATCHN 4 -#define REGEX_TITLE "^([A-Z]+)[ ]+([a-zA-Z0-9\\:\\/\\_\\-\\.\\,]+)[ ]+([a-zA-Z0-9\\_\\-\\.\\,\\/]+)[ ]*[$\n\r]" -#define REGEX_HEADER "^(.*)[$\\n\\r]" - struct http_msg *child_msg; regex_t preg; regmatch_t pmatch[REGEX_MATCHN]; @@ -34,7 +27,43 @@ _return: } int parse_header(char *msgbuff) { + int ret; + + ret = regcomp(&preg, REGEX_HEADER, REG_EXTENDED); + if (ret != 0) + goto _err; + + ret = regexec(&preg, msgbuff, REGEX_MATCHN, pmatch, 0); + if (ret != 0) + goto _err; + + char *key = extractsub(msgbuff, pmatch[1]); + if (key == NULL) + goto _err; + + char *value = extractsub(msgbuff, pmatch[2]); + if (value == NULL) + goto _err; + + struct header new_header = { + .key = key, + .value = value + }; + + int last_index = child_msg->header_num; + + child_msg->header_num++; + child_msg->headers = (void *) realloc(child_msg->headers, + child_msg->header_num*sizeof(struct header)); + + child_msg->headers[last_index] = new_header; + + regfree(&preg); return 0; + +_err: + regfree(&preg); + return -1; } int parse_title(char *msgbuff) { @@ -60,20 +89,15 @@ int parse_title(char *msgbuff) { if (child_msg->ver == NULL) goto _err; - goto _ok; + regfree(&preg); + return 0; _err: regfree(&preg); return -1; -_ok: - regfree(&preg); - return 0; - } -int par_line = 0; - int parse_line(char *line, int line_count) { int ret = 0; @@ -86,13 +110,24 @@ int parse_line(char *line, int line_count) { return ret; } +int test(char *line, int num) { + fprintf(stdout, "line %s and num %d\n", line, num); + return 0; +} + +int par_line = 0; + void handle_request(int sockfd) { int ret; int id = getpid(); - char msgbuff[PROXY_MAX_MSGLEN]; - memset(msgbuff, 0, sizeof(msgbuff)); + + char *msgbuff = (char *) calloc(1, PROXY_MAX_MSGLEN); + if (msgbuff == NULL) { + fprintf(stderr, "Not enough dynamic memory\n"); + goto end_sock; + } - ret = recv(sockfd, msgbuff, sizeof(msgbuff), 0); + ret = recv(sockfd, msgbuff, PROXY_MAX_MSGLEN, 0); if (ret < 0) { fprintf(stderr, "[CHILD %d] Failed to receive data from client\n", id); goto end_sock; @@ -103,84 +138,170 @@ void handle_request(int sockfd) { // prepare structs child_msg = (struct http_msg *) calloc(1, sizeof(struct http_msg)); if (child_msg == NULL) { - fprintf(stderr, "[CHILD %d] Failed to allocate memory for client structs\n", id); + fprintf(stderr, "[CHILD %d] Failed to allocate memory for client" + "structs\n", id); goto end_sock; } - for (char *ln = strtok(msgbuff, "\n"); ln != NULL; ln = strtok(NULL, "\n"), par_line++) { - parse_line(ln, par_line); + char *ln = strdup(msgbuff); + if (!ln) { + fprintf(stdout, "Not enough dynamic memory\n"); + goto end_sock; } - - // start parsing - /*ret = parse_title(msgbuff); - if (ret < 0) { - fprintf(stderr, "[CHILD %d] Failed to parse the title of the request\n", id); - goto end_structs; - }*/ + ln = strtok(ln, "\n"); + + while (ln) { + parse_line(ln, par_line); + par_line++; + ln = strtok(NULL, "\n"); + } + + fprintf(stdout, "I am done here.... zzzz \n"); + + for (;;); //end_structs: - free(child_msg); + //free(child_msg); end_sock: close(sockfd); } -int main(int argc, char *argv[]) { - int server_socket; - int ret; +void dohelp() { + printf( + "+====================+\n" + "| HTTP/1.0 PROXY |\n" + "+=====@0xdeadbeer====+\n" + "usage:\n" + " ./proxy [mode]\n" + "mode:\n" + " * server -> start listening as proxy\n" + " * client -> send test requests to server\n" + ); +} - ret = server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); +int doserver(void) { + int ret, server_socket; + + ret = server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ret < 0) { - fprintf(stderr, "Failed to create a socket to listen on\n"); - return EXIT_FAILURE; + fprintf(stderr, "Failed to create a socket to listen on\n"); + return -1; } struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(PROXY_PORT); - ret = bind(server_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); + ret = bind(server_socket, (struct sockaddr *) &serv_addr, + sizeof(serv_addr)); if (ret < 0) { fprintf(stderr, "Failed to bind to port %d\n", PROXY_PORT); - return EXIT_FAILURE; + return -1; } ret = listen(server_socket, PROXY_CONN); if (ret < 0) { - fprintf(stderr, "Failed to listen on port %d\n", PROXY_PORT); - return EXIT_FAILURE; + fprintf(stderr, "Failed to listen on port %d\n", PROXY_PORT); + return -1; } fprintf(stdout, "Listening on port %d\n", PROXY_PORT); for (;;) { struct sockaddr_in client_addr; - socklen_t client_addrlen = sizeof(client_addr); + socklen_t client_addrlen = sizeof(client_addr); int client_socket; - ret = client_socket = accept(server_socket, (struct sockaddr *) &client_addr, &client_addrlen); + ret = client_socket = accept(server_socket, (struct sockaddr *) + &client_addr, &client_addrlen); if (ret < 0) { - fprintf(stderr, "Failed to establish socket connection with client\n"); - return EXIT_FAILURE; + fprintf(stderr, "Failed to establish socket connection with" + "client\n"); + return -1; } ret = fork(); switch (ret) { case -1: - fprintf(stderr, "[CLIENT SOCKET %d] Failed to fork child process to handle the request\n", client_socket); - return EXIT_FAILURE; + fprintf(stderr, "[CLIENT SOCKET %d] Failed to fork child process to" + "handle the request\n", client_socket); + return -1; break; case 0: handle_request(client_socket); break; default: - fprintf(stdout, "[PROGRAM] Successfully forked a new child process with PID %d\n", ret); + fprintf(stdout, "[PROGRAM] Successfully forked a new child process" + "with PID %d\n", ret); break; } } - return EXIT_SUCCESS; + return 0; +} + +int doclient(void) { + int ret = 0; + int client_socket; + struct sockaddr_in serv_addr; + + ret = client_socket = socket(AF_INET, SOCK_STREAM, 0); + if(ret < 0) + { + fprintf(stderr, "Failed creating socket\n"); + return -1; + } + + memset(&serv_addr, '0', sizeof(serv_addr)); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(PROXY_PORT); + + ret = inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); + if(ret <= 0) + { + fprintf(stderr, "Inet_pton error\n"); + return -1; + } + + ret = connect(client_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); + if(ret < 0) + { + fprintf(stderr, "Failed connecting to remote server\n"); + return -1; + } + + int bytes = 0; + do { + bytes += send(client_socket, CLIENT_MESSAGE, sizeof(CLIENT_MESSAGE), 0); + } while (bytes != sizeof(CLIENT_MESSAGE)); + + fprintf(stdout, "Sent %d bytes to server\n", bytes); + + return 0; +} + +int main(int argc, char *argv[]) { + int ret; + if (argc != 2) { + dohelp(); + return 0; + } + + const char *mode = argv[1]; + ret = strcmp(mode, SERVER_MODE); + if (ret == 0) + return doserver(); + + ret = strcmp(mode, CLIENT_MODE); + if (ret == 0) + return doclient(); + + fprintf(stderr, "Unknown proxy mode\n"); } diff --git a/structs.h b/structs.h index a6f740d..4b036a2 100644 --- a/structs.h +++ b/structs.h @@ -1,6 +1,23 @@ #ifndef STRUCTS_H #define STRUCTS_H +#define SERVER_MODE "server" +#define CLIENT_MODE "client" + +#define PROXY_PORT 2020 +#define PROXY_CONN 20 +#define PROXY_MAX_MSGLEN 10*1024 + +#define REGEX_MATCHN 4 +#define REGEX_TITLE "^([A-Z]+)[ ]+([a-zA-Z0-9\\:\\/\\_\\-\\.\\,]+)"\ + "[ ]+([a-zA-Z0-9\\_\\-\\.\\,\\/]+)[ ]*$|\n|\r" +#define REGEX_HEADER "^([a-zA-Z0-9\\-\\_]*):[ \t]+(.*)$|\n|\r" + +#define CLIENT_MESSAGE "GET http://google.com/auth HTTP/1.0\n"\ + "\n"\ + "Host: google.com\n"\ + "Authorization: Bearer ffja2439gjawgjgojserg\n" + struct header { char *key; char *value; @@ -10,6 +27,7 @@ struct http_msg { char *method; char *uri; char *ver; + int header_num; struct header *headers; void *body; };