1 #define _GNU_SOURCE
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include <netinet/in.h>
9 #include <sys/socket.h>
10 #include <sys/wait.h>
11 #include <arpa/inet.h>
12 #include <unistd.h>
13 #include <signal.h>
14
15
16 #define LISTENPORT 24019
17 #define REALPWD "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
18 #define OLDPWD "XXXXXXXXXXXXXXXX"
19 #define DROPUID 1998
20 #define DROPGID 1998
21
22 struct query
23 {
24 unsigned char oldpass[20+1];
25 unsigned char pass[100+1];
26 unsigned int len;
27 } qry;
28
29 struct response
30 {
31 unsigned int result;
32 unsigned char pass[100+1];
33 } rsp;
34
35 int main(int argc, char *argv[])
36 {
37 int listenfd, connfd;
38 struct sockaddr_in localaddr;
39 struct sockaddr_in remoteaddr;
40 int sin_size;
41 int port=LISTENPORT;
42
43 setresgid(DROPGID, DROPGID, DROPGID);
44 setresuid(DROPUID, DROPUID, DROPUID);
45 signal(SIGPIPE, SIG_IGN);
46 daemon(0,0);
47
48 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
49 {
50 perror("socket");
51 exit(EXIT_FAILURE);
52 }
53
54 localaddr.sin_family = AF_INET;
55 localaddr.sin_port = htons(port);
56 localaddr.sin_addr.s_addr = INADDR_ANY;
57 bzero(&(localaddr.sin_zero), 8);
58
59 if (bind(listenfd, (struct sockaddr *)&localaddr, sizeof(struct sockaddr)) == -1)
60 {
61 perror("bind");
62 exit(EXIT_FAILURE);
63 }
64
65 if (listen(listenfd, 20) == -1)
66 {
67 perror("listen");
68 exit(EXIT_FAILURE);
69 }
70
71 for (;;)
72 {
73 sin_size = sizeof(struct sockaddr_in);
74 if ((connfd = accept(listenfd, (struct sockaddr *)&remoteaddr, &sin_size)) == -1)
75 {
76 perror("accept");
77 continue;
78 }
79
80 // printf("connection from %s\n", inet_ntoa(remoteaddr.sin_addr));
81
82 if (!fork()) //child
83 {
84 close(listenfd);
85
86 for (;;)
87 {
88 memset(&qry, 0, sizeof(struct query));
89 memset(&rsp, 0, sizeof(struct response));
90
91 if (recv(connfd, &qry, sizeof(struct query), 0)!=sizeof(struct query))
92 {
93 perror("recv");
94 close(connfd);
95 exit(EXIT_FAILURE);
96 }
97
98 if (strncmp(qry.oldpass, OLDPWD, strlen(OLDPWD)))
99 {
100 close(connfd);
101 exit(EXIT_FAILURE);
102 }
103
104 // validate
105 if (!strncmp(qry.pass, REALPWD, qry.len))
106 rsp.result=1;
107
108 if (rsp.result && (qry.len==strlen(REALPWD)))
109 strcpy(rsp.pass, REALPWD);
110
111 // printf("-> result=%s\n", rsp.result?"CORRECT":"WRONG");
112 if (send(connfd, &rsp, sizeof(struct response), 0)!=sizeof(struct response))
113 {
114 perror("send");
115 close(connfd);
116 exit(EXIT_FAILURE);
117 }
118 }
119 }
120
121 while(waitpid(-1,NULL,WNOHANG) > 0);
122
123 close(connfd);
124 }
125
126 }