Guest User

Untitled

a guest
May 26th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.42 KB | None | 0 0
  1. #include <mysql.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #include <string.h>
  8. #include <netdb.h>
  9. #include <sys/types.h>
  10. #include <netinet/in.h>
  11. #include <sys/socket.h>
  12. #include <arpa/inet.h>
  13. #include <ctype.h>
  14.  
  15. /* exit error codes */
  16. #define SUCCESS 0
  17. #define UNKNOWN_ERROR 1
  18. #define MYSQL_ERROR 2
  19. #define HTTP_ERROR 3
  20. #define MEM_ERROR 4
  21.  
  22. /* MySQL credentials */
  23. #define MYSQL_USER "root"
  24. #define MYSQL_PASS "fl33021"
  25. #define MYSQL_HOST "localhost"
  26. #define MYSQL_DATABASE "havesomeunix"
  27. #define SQL_CHARS_FORBIDDEN "'\""
  28. /* HTTP information */
  29. #define PAGE_SIZE_LIMIT 2048        // max size for web pages are crawler will download, in bytes.
  30.  
  31. int url_check(MYSQL *, char *);
  32. int add_urls(MYSQL *, char *);
  33. int grep(char *, char *);
  34. char *get_page(char *, long int); /* TODO: write this function */
  35. char *sql_escape(char *);
  36. char *html_tag_remove(char *);
  37. char *next_url(char **);
  38. char **get_urls(char *);
  39. void *get_in_addr(struct sockaddr *);
  40.  
  41. int main(void) {
  42.     MYSQL *connection;
  43.     MYSQL_RES *results;
  44.     MYSQL_ROW row;
  45.     char *query;
  46.     int query_buffer;
  47.     long int update_time;
  48.    
  49.     connection = mysql_init(0);
  50.    
  51.     if (!mysql_real_connect(connection, MYSQL_HOST,
  52.             MYSQL_USER, MYSQL_PASS, MYSQL_DATABASE, 0, 0, 0)) {
  53.         return MYSQL_ERROR;
  54.     }
  55.  
  56.     while (1) {
  57.         if (mysql_query(connection, "SELECT url FROM urls WHERE last_checked=(SELECT MIN(last_checked) FROM urls)")) { /* that query is very inefficient and needs to be optimized */
  58.             return MYSQL_ERROR;
  59.         }
  60.  
  61.         results = mysql_store_result(connection);
  62.         row = mysql_fetch_row(results);
  63.        
  64.         url_check(connection, row[0]);
  65.  
  66.         update_time = (long int)time(0);
  67.         query_buffer = update_time + (int)strlen(row[0]);
  68.        
  69.         if (!(query = malloc(sizeof(char) * (200 + query_buffer))) {
  70.             return MEM_ERROR;
  71.         }
  72.  
  73.         sprintf(query, "UPDATE urls SET last_checked=%l WHERE url='%s'", update_time, row[0]);
  74.         mysql_query(connection, query);
  75.         free(query);
  76.         mysql_free_result(results);
  77.     }
  78.    
  79.     mysql_close(connection);
  80.  
  81.     return SUCCESS;
  82. }
  83.  
  84. char *get_page(char *url) {
  85.     int sockfd;
  86.     int addr_len;
  87.     char *auth_negotiation;
  88.     char *auth_acknowledge;
  89.     char *socks5_conn_req;
  90.     char *socks5_allowance;
  91.     char *IP4_info;
  92.     char *DNS_info;
  93.     char *IP6_info;
  94.     char *HTTP_request;
  95.     char *HTTP_response;
  96.     char *HTTP_web_page;
  97.    
  98.     addr_len = (int)strlen(url);
  99.     auth_negotiation = malloc(sizeof(int) * 4);
  100.     auth_acknowledge = malloc(sizeof(int) * 3);
  101.     socks5_conn_req = malloc(sizeof(int) * (7 + addr_len));
  102.     socks5_allowance = malloc(sizeof(int) * 4);
  103.     IP4_info = malloc(sizeof(int) * 4);
  104.     DNS_info = malloc(sizeof(int));
  105.     IP6_info = malloc(sizeof(int) * 16);
  106.     HTTP_request = malloc(sizeof(int) * (26 + addr_len));
  107.     HTTP_response =
  108.     strcpy(auth_negotiation "\x05\x01\x00");
  109.     sprintf(socks5_conn_req, "\x05\x01\x00\x03%x%s\x00\x50", addr_len, url);
  110.     sprintf(HTTP_request, "GET / HTTP/1.1\r\nHost: %s\r\n\r\n", url);
  111.    
  112.     sockfd = socket(AF_INET, SOCK_STREAM, 0);
  113.  
  114.     connect(sockfd, url, addr_len);
  115.  
  116.     // Auth negototiation
  117.     send(sockfd, auth_negotiation, (int)strlen(auth_negotiation), 0);
  118.     recv(sockfd, auth_acknowledge, 3, 0);
  119.  
  120.     // Tell the proxy what we want to connect to
  121.     send(sockfd, socks5_conn_req, 7 + addr_len, 0);
  122.     recv(sockfd, socks5_allowance, 4, 0);
  123.  
  124.     // local socket address information that we don't care about
  125.     recv(sockfd, IP4_info, 4, 0);
  126.     recv(sockfd, DNS_info, 1, 0);
  127.     recv(sockfd, IP6_info, 16, 0);
  128.  
  129.     // HTTP request
  130.     send(sockfd, HTTP_request, 26 + addr_len, 0);
  131.     recv(sockfd, HTTP_respons2048
  132. }
  133.  
  134. char *sql_escape(char *query) {
  135.     char *new_query;
  136.     char *forbidden_chars;
  137.     int buffer;
  138.     int is_forbidden;
  139.  
  140.     buffer = (int)strlen(query) * 2;
  141.     new_query = malloc(sizeof(char) * buffer);
  142.     forbidden_chars = malloc(sizeof(char) * (int)strlen(SQL_CHARS_FORBIDDEN));
  143.  
  144.     while (*query++) {
  145.         is_forbidden = 0;
  146.  
  147.         while (*forbidden_chars++) {
  148.             if (*query = *forbidden_chars) {
  149.                 is_forbidden = 1;
  150.                 break;
  151.             }
  152.  
  153.             if (is_forbidden) {
  154.                 *new_query++ = '\\';
  155.             }
  156.             *new_query++ = *query;
  157.         }
  158.     }
  159.  
  160.     *new_query = '\0';
  161.  
  162.     return new_query;
  163. }
  164.  
  165. char *html_tag_remove(char *page) {
  166.     char *fpage;
  167.     int in_tag;
  168.     int buffer;
  169.  
  170.     buffer = (int)strlen(page);
  171.     fpage = malloc(sizeof(char) * buffer);
  172.  
  173.     while (*page) {
  174.         if (*page == '<') {
  175.             in_tag = 1;
  176.         }
  177.  
  178.         if (in_tag) {
  179.             *fpage = *page;
  180.         }
  181.  
  182.         if (*page == '>') {
  183.             in_tag = 0;
  184.         }
  185.        
  186.         fpage++;
  187.         page++;
  188.     }
  189.    
  190.     *fpage = '\0';
  191.  
  192.     return fpage;
  193. }
  194.  
  195. int insert_urls(MYSQL *connection, char **urls) {
  196.     char *query;
  197.     int query_len;
  198.  
  199.     while (*urls) {
  200.         query_len = (int)strlen(*urls);
  201.         query = malloc(sizeof(char) * (200 + query_len));
  202.         sprintf(query, "INSERT urls (url, last_checked, linkers, page_content) VALUES ('%s', 0, '', ''", *urls);
  203.         mysql_query(connection, query);
  204.         free(query);
  205.        
  206.         ++urls;
  207.     }
  208.  
  209.     return SUCCESS;
  210. }
  211.  
  212. int url_check(MYSQL *connection, char *url) {
  213.     char *raw_page;
  214.     char *web_page;
  215.     char *query;
  216.  
  217.     if (!(web_page = sql_escape((raw_page = get_page(url, PAGE_LIMIT))))) {
  218.         return HTTP_ERROR;
  219.     }
  220.    
  221.     if (!(query = malloc(sizeof(char) * (int)strlen(web_page)))) {
  222.         return MEM_ERROR;
  223.     }
  224.    
  225.     sprintf(query, "UPDATE urls SET page_content='%s' WHERE url='%s'", html_tag_remove(web_page), url);
  226.     mysql_query(connection, query);
  227.     add_urls(connection, raw_page);
  228.    
  229.     free(raw_page);
  230.     free(query);
  231.     free(web_page);
  232.            
  233.     return SUCCESS
  234. }
  235.  
  236. int add_urls(MYSQL *connection, char *web_page) {
  237.     char **urls;
  238.     int i;
  239.    
  240.     if (urls = get_urls(web_page)) {
  241.         return HTTP_ERROR;
  242.     }
  243.    
  244.     if (insert_urls(connection, urls)) {
  245.         return MYSQL_ERROR;
  246.     }
  247.    
  248.     return SUCCESS;
  249. }
  250.  
  251. int is_url(char url_char, int period) {
  252.     char *bad_chars = "'\"<> ;,$:\\@#{}()|\t\n\r[]";
  253.     int i;
  254.  
  255.     if (period) {
  256.         if (url_char == '.') {
  257.             return 0;
  258.         }
  259.     }
  260.  
  261.     for (i = 0; *(bad_chars + i); i++) {
  262.         if (url_char == *(bad_chars + i)) {
  263.             return 0;
  264.         }
  265.     }
  266.  
  267.     return 1;
  268. }
  269.  
  270. char *next_url(char **orig_document_stream) {
  271.     char *document_stream;
  272.     char *NULL_domain;
  273.     char *top_level_domain = ".onion";
  274.     char *raw_tld;
  275.     int domain_buffer;
  276.     int tld_count;
  277.     int i;
  278.     int period_found;
  279.     signed int url_pos;
  280.  
  281.     NULL_domain = malloc(sizeof(char));
  282.     strcpy(NULL_domain, "1");
  283.     document_stream = *orig_document_stream;
  284.     domain_buffer = 50;
  285.     url_pos = grep(document_stream, top_level_domain) - 1;
  286.  
  287.     if (url_pos == -1) {
  288.         return (char *)-1;
  289.     }
  290.  
  291.     raw_tld = malloc(sizeof(char) * domain_buffer);
  292.  
  293.     while (isalnum(*(document_stream + url_pos)) && url_pos > 0) {
  294.         url_pos--;
  295.     }
  296.  
  297.     if (!isalnum(*(document_stream + url_pos))) {
  298.         url_pos++;
  299.     }
  300.  
  301.     period_found = 0;
  302.     tld_count = 0;
  303.  
  304.     for (i = 0; is_url(*(document_stream + url_pos + i), period_found); i++) {
  305.         if (i * 2 > domain_buffer) {
  306.             domain_buffer *= 2;
  307.             raw_tld = realloc(raw_tld, sizeof(char) * domain_buffer);
  308.         }
  309.  
  310.         if (*(document_stream + url_pos + i) == '.') {
  311.             period_found = 1;
  312.         }
  313.  
  314.         if (period_found) {
  315.             tld_count++;
  316.         }
  317.  
  318.         if (tld_count > strlen(top_level_domain)) {
  319.             break;
  320.         }
  321.  
  322.         *(raw_tld + i) = *(document_stream + url_pos + i);
  323.     }
  324.  
  325.     *orig_document_stream = (document_stream + url_pos + (int)strlen(raw_tld));
  326.  
  327.     if (grep(document_stream, top_level_domain) == -1) {
  328.         free(raw_tld);
  329.         return NULL_domain;
  330.     }
  331.  
  332.     if (!strcmp(raw_tld, top_level_domain)) {
  333.         document_stream = document_stream + strlen(top_level_domain);
  334.         return next_url(&document_stream);
  335.     }
  336.  
  337.     return raw_tld;
  338. }
  339.  
  340.  
  341. int grep(char *full_string, char *substring) {
  342.     int i;
  343.     int x;
  344.     int match;
  345.  
  346.     match = 1;
  347.  
  348.     for (i = 0; *(full_string + i); i++) {
  349.         for (x = 0; *(substring + x); x++) {
  350.             if (*(full_string + i + x) != *(substring + x)) {
  351.                 match = 0;
  352.                 break;
  353.             }
  354.         }
  355.         if (match) {
  356.             return i;
  357.         }
  358.  
  359.         match = 1;
  360.     }
  361.  
  362.     return -1;
  363. }
  364.  
  365. char **get_urls(char *web_page) {
  366.     char *url;
  367.     char **urls;
  368.     char **orig_urls;
  369.     int buffer;
  370.     int i;
  371.  
  372.     buffer = 50;
  373.     i = 0;
  374.     urls = malloc(sizeof(char *) * buffer);
  375.     orig_urls = urls;
  376.  
  377.     while (strlen(url = next_url(&web_page)) != 1) {
  378.         *urls = malloc(sizeof(char) * ((int)strlen(url) + 1));
  379.         strcpy(*urls, url);
  380.         free(url);
  381.        
  382.         if (((i++) * 2) > buffer) {
  383.             buffer *= 2;
  384.             urls = realloc(urls, sizeof(char *) * buffer);
  385.         }
  386.  
  387.         ++urls;
  388.     }
  389.  
  390.     *urls = 0;
  391.     free(url);
  392.  
  393.     return orig_urls;
  394. }
Add Comment
Please, Sign In to add comment