1 #include <crypt.h>
2 #include <netdb.h>
3 #include <netinet/in.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/socket.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10
11 /* Do nothing with first message */
handleData0(char * data,int len)12 void handleData0(char *data, int len) {
13 printf("Auth success\n");
14 }
15
16 /* Second message is stack based buffer overflow */
handleData1(char * data,int len)17 void handleData1(char *data, int len) {
18 char buff[8];
19 bzero(buff, 8);
20 memcpy(buff, data, len);
21 printf("Handledata1: %s\n", buff);
22 }
23
24 /* Third message is heap overflow */
handleData2(char * data,int len)25 void handleData2(char *data, int len) {
26 char *buff = malloc(8);
27 bzero(buff, 8);
28 memcpy(buff, data, len);
29 printf("Handledata2: %s\n", buff);
30 free(buff);
31 }
32
handleData3(char * data,int len)33 void handleData3(char *data, int len) {
34 printf("Meh: %i\n", len);
35 }
36
handleData4(char * data,int len)37 void handleData4(char *data, int len) {
38 printf("Blah: %i\n", len);
39 }
40
doprocessing(int sock)41 void doprocessing(int sock) {
42 char data[1024];
43 int n = 0;
44 int len = 0;
45
46 while (1) {
47 bzero(data, sizeof(data));
48 len = read(sock, data, 1024);
49
50 if (len == 0 || len <= 1) {
51 return;
52 }
53
54 printf("Received data with len: %i on state: %i\n", len, n);
55 switch (data[0]) {
56 case 'A':
57 handleData0(data, len);
58 write(sock, "ok", 2);
59 break;
60 case 'B':
61 handleData1(data, len);
62 write(sock, "ok", 2);
63 break;
64 case 'C':
65 handleData2(data, len);
66 write(sock, "ok", 2);
67 break;
68 case 'D':
69 handleData3(data, len);
70 write(sock, "ok", 2);
71 break;
72 case 'E':
73 handleData4(data, len);
74 write(sock, "ok", 2);
75 break;
76 default:
77 return;
78 }
79
80 n++;
81 }
82 }
83
main(int argc,char * argv[])84 int main(int argc, char *argv[]) {
85 int sockfd, newsockfd, portno, clilen;
86 char buffer[256];
87 struct sockaddr_in serv_addr, cli_addr;
88 int n, pid;
89
90 if (argc == 2) {
91 portno = atoi(argv[1]);
92 } else {
93 portno = 5001;
94 }
95
96 sockfd = socket(AF_INET, SOCK_STREAM, 0);
97 if (sockfd < 0) {
98 perror("ERROR opening socket");
99 exit(1);
100 }
101
102 int reuse = 1;
103 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const char *)&reuse, sizeof(reuse)) < 0)
104 perror("setsockopt(SO_REUSEPORT) failed");
105
106 bzero((char *)&serv_addr, sizeof(serv_addr));
107 serv_addr.sin_family = AF_INET;
108 serv_addr.sin_addr.s_addr = INADDR_ANY;
109 serv_addr.sin_port = htons(portno);
110
111 printf("Listening on port: %i\n", portno);
112
113 /* Now bind the host address using bind() call.*/
114 if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
115 perror("ERROR on binding");
116 exit(1);
117 }
118
119 listen(sockfd, 5);
120 clilen = sizeof(cli_addr);
121
122 while (1) {
123 newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
124 if (newsockfd < 0) {
125 perror("ERROR on accept");
126 exit(1);
127 }
128 printf("New client connected\n");
129 doprocessing(newsockfd);
130 printf("Closing...\n");
131 shutdown(newsockfd, 2);
132 close(newsockfd);
133 }
134 }
135