- Authentication Daemon
-
There is an authentication daemon waiting on brebera port 24012. You connect to it, supply your password and get authenticated. The semtex 12 password will give you user access, the admin password will give you administrator access...
After authentication you connect to the remote file system reader on port 24013. Depending on your access level you can list files and show them. The semtex 13 password has been located in one of the files on this remote file system. Brebera is fast, can you be faster?
- Thanks to bk for this level!
- Code listing (level12.authd.c)
-
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/ipc.h>
5 #include <sys/shm.h>
6 #include <sys/types.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <sys/socket.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <time.h>
14 #include <signal.h>
15 #include <wait.h>
16
17
18 #include "server.h"
19 #include "sem.h"
20
21 #define PATH "/path"
22 #define SHM_SIZE 4096
23 #define SHM_KEY 0xbadc0ded
24 #define AUTH_PORT 24012
25 #define BUFSIZE 512
26
27 int new_connection(unsigned int addr, int pass, struct sharea* auth_array);
28 int daemonize();
29
30 int main(int argc, char **argv)
31 {
32 if(argc > 1) {
33 if((argv[1][0] == 'D')) {
34 if((daemonize()) == -1)
35 exit(EXIT_FAILURE);
36 }
37 }
38
39 int fd, sockfd, connfd;
40 unsigned int sin_size;
41 struct sockaddr_in my_addr, remote_addr;
42 struct sigaction reap_zombies;
43
44 key_t key = SHM_KEY;
45 int shmid;
46 struct sharea *auth_array;
47
48 char sendbuf[BUFSIZE], recvbuf[BUFSIZE], super_pass[BUFSIZE];
49
50 fd = open(PATH, O_RDONLY);
51 if(fd < 0) {
52 perror("open");
53 exit(EXIT_FAILURE);
54 }
55
56 if((read(fd, super_pass, BUFSIZE)) < 0) {
57 perror("pass");
58 exit(EXIT_FAILURE);
59 }
60 close(fd);
61
62 /*Set up the shared memory authorization array */
63
64 if((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) == -1) {
65 perror("Shared");
66 exit(1);
67 }
68
69 if((auth_array = shmat(shmid, NULL, 0)) == (void *)-1) {
70 perror("Share attach");
71 exit(1);
72 }
73
74 memset(auth_array, 0, sizeof(*auth_array));
75
76 memset(&reap_zombies, 0, sizeof(reap_zombies));
77 reap_zombies.sa_flags = SA_NOCLDWAIT;
78
79 if((sigaction(SIGCHLD, &reap_zombies, 0)) == -1) {
80 perror("Sighandler");
81 exit(1);
82 }
83
84 /* Lets set up the listening socket */
85
86 if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
87 perror("Socket");
88 exit(1);
89 }
90 my_addr.sin_family = AF_INET;
91 my_addr.sin_port = htons(AUTH_PORT);
92 my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
93 memset(&(my_addr.sin_zero), '\0', 8);
94
95 if((bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))) == -1) {
96 perror("Bind");
97 exit(1);
98 }
99
100
101 listen(sockfd, 5); /* Error checks... nah! */
102
103 while(1) {
104
105 pid_t pid;
106
107 sin_size = sizeof(struct sockaddr_in);
108 if((connfd = accept(sockfd, (struct sockaddr*)&remote_addr, &sin_size)) == -1) {
109 perror("Accept");
110 exit(1);
111 }
112
113 pid = fork();
114 if(pid < 0) {
115 perror("fork");
116 exit(EXIT_FAILURE);
117 }
118 if(pid > 0) {
119 close(connfd);
120 continue;
121 }
122
123 strcpy(sendbuf, "Authd login - Send Pass");
124 send(connfd, sendbuf, strlen(sendbuf), 0);
125 recv(connfd, recvbuf, BUFSIZE - 1, 0);
126 recvbuf[BUFSIZE - 1] = '\0';
127
128 if(!new_connection(remote_addr.sin_addr.s_addr, strcmp(recvbuf, super_pass), auth_array)) {
129 strcpy(sendbuf, "Failed - try again later");
130 send(connfd, sendbuf, strlen(sendbuf), 0);
131 }
132 close(connfd);
133 exit(EXIT_SUCCESS);
134 }
135 }
136
137 int new_connection(unsigned int addr, int super, struct sharea *auth_array)
138 {
139 int i, found = 0;
140
141 /* Insert new entry with correct perms */
142
143 down(&auth_array->sem);
144 for(i = 0; i < 32; i++) {
145 if(auth_array->list[i].token == 0) {
146 found++;
147 auth_array->list[i].token = addr;
148 auth_array->list[i].timestamp = time(NULL);
149 if(super)
150 auth_array->list[i].perms = 1; /* 1 = ordinary user */
151 break;
152 }
153
154 }
155 up(&auth_array->sem);
156
157 /* Expire old connections */
158 down(&auth_array->sem);
159 for(i = 0; i < 32; i++) {
160 if((auth_array->list[i].timestamp + 300) < time(NULL))
161 memset(&auth_array->list[i], 0, sizeof(struct auth));
162 }
163 up(&auth_array->sem);
164
165 return found;
166 }
- Code listing (level12.daemon.c)
-
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <fcntl.h>
6 #include <errno.h>
7 #define _GNU_SOURCE
8 #include <unistd.h>
9
10
11 #define TARGET_UID 1998
12
13 int daemonize()
14 {
15 int ret = -1;
16
17 if((daemon(0, 0)) == -1)
18 return ret;
19
20 if((setresgid(TARGET_UID, TARGET_UID, TARGET_UID)) == -1)
21 return ret;
22 if((setresuid(TARGET_UID, TARGET_UID, TARGET_UID)) == -1)
23 return ret;
24
25 ret = 0;
26
27 return ret;
28
29 }
- Code listing (level12.reader.c)
-
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/ipc.h>
5 #include <sys/shm.h>
6 #include <sys/types.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <sys/socket.h>
10 #include <dirent.h>
11 #include <unistd.h>
12 #include <signal.h>
13 #include <wait.h>
14
15
16 #include "server.h"
17 #include "sem.h"
18
19 #define PATH "/path"
20 #define SHM_SIZE 4096
21 #define SHM_KEY 0xbadc0ded
22 #define AUTH_PORT 24013
23 #define BUFSIZE 512
24
25 int daemonize();
26
27 void list_dir(int fd)
28 {
29 DIR *dirp;
30 struct dirent *dp;
31
32 if((dirp = opendir(PATH)) == NULL)
33 return;
34 while((dp = readdir(dirp)) != NULL) {
35 send(fd, dp->d_name, strlen(dp->d_name), 0);
36 }
37 return;
38 }
39
40 void filedump(const char *name, int fd)
41 {
42 FILE *filp;
43 char buf[2048];
44 int ret;
45
46 chdir(PATH);
47 if((filp = fopen(name, "rb")) == NULL) {
48 strcpy(buf, "File not found.");
49 send(fd, buf, strlen(buf), 0);
50 return;
51 }
52 do {
53 ret = fread(buf, 1, 2048, filp);
54 if(ret > 0)
55 send(fd, buf, ret, 0);
56 send(fd, "\n", 1, 0);
57 } while(ret >= 2048);
58 }
59
60 int main(int argc, char **argv)
61 {
62
63 if(argc > 1) {
64 if(argv[1][0] == 'D') {
65 if(daemonize())
66 exit(EXIT_SUCCESS);
67 }
68 }
69
70 int sockfd, connfd;
71 unsigned int sin_size;
72 struct sockaddr_in my_addr, remote_addr;
73
74 key_t key = SHM_KEY;
75 int shmid;
76 struct sharea *auth_array;
77 struct sigaction reap_zombies;
78
79 char sendbuf[BUFSIZE], recvbuf[BUFSIZE], filename[BUFSIZE];
80
81 /*Set up the shared memory authorization array */
82
83 if((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) == -1) {
84 perror("Shared");
85 exit(1);
86 }
87
88 if((auth_array = shmat(shmid, NULL, 0)) == (void *)-1) {
89 perror("Share attach");
90 exit(1);
91 }
92
93 /* Lets set up the listening socket */
94
95 memset(&reap_zombies, 0, sizeof(reap_zombies));
96 reap_zombies.sa_flags = SA_NOCLDWAIT;
97
98 if((sigaction(SIGCHLD, &reap_zombies, 0)) == -1) {
99 perror("Sighandler");
100 exit(1);
101 }
102
103 if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
104 perror("Socket");
105 exit(1);
106 }
107 my_addr.sin_family = AF_INET;
108 my_addr.sin_port = htons(AUTH_PORT);
109 my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
110 memset(&(my_addr.sin_zero), '\0', 8);
111
112 if((bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))) == -1) {
113 perror("Bind");
114 exit(1);
115 }
116
117 listen(sockfd, 5); /* Error checks... nah! */
118
119 while(1) {
120
121 int i, len, pid, found = 0;
122
123 sin_size = sizeof(struct sockaddr_in);
124 if((connfd = accept(sockfd, (struct sockaddr*)&remote_addr, &sin_size)) == -1) {
125 perror("Accept");
126 exit(1);
127 }
128
129 if((pid = fork()) < 0) {
130 perror("fork");
131 exit(EXIT_FAILURE);
132 }
133 if(pid) {
134 close(connfd);
135 continue;
136 }
137
138 strcpy(sendbuf, "File Transfer: Enter 'l' for list or type a filename:");
139 send(connfd, sendbuf, strlen(sendbuf), 0);
140 len = recv(connfd, recvbuf, BUFSIZE - 1, 0);
141
142 if(len <= 0)
143 break;
144
145 strncpy(filename, recvbuf, len < BUFSIZE ? len : BUFSIZE);
146 filename[BUFSIZE - 1] = '\0';
147
148 down(&auth_array->sem); /* Take semaphore for reading auth list */
149 for(i = 0; i < 32; i++) {
150 if(auth_array->list[i].token == remote_addr.sin_addr.s_addr) {
151 found++;
152 break;
153 }
154 }
155 up(&auth_array->sem); /* Release semaphore to wait on user replies next... avoid deadlock */
156
157 if(!found) {
158 strcpy(sendbuf, "Not recognized, use authd first.");
159 send(connfd, sendbuf, strlen(sendbuf), 0);
160 close(connfd);
161 continue;
162 }
163
164 if(filename[0] == 'l') {
165 list_dir(connfd);
166 }
167 else {
168 strcpy(sendbuf, "Display file? (y/n)");
169 /*check perm and display file*/
170
171 send(connfd, sendbuf, strlen(sendbuf), 0);
172 recv(connfd, recvbuf, BUFSIZE - 1, 0);
173 recvbuf[BUFSIZE - 1] = '\0';
174
175 if(recvbuf[0] == 'y') {
176 down(&auth_array->sem);
177 if(auth_array->list[i].perms == 0) {/* 0 is superuser, 1 is user */
178 filedump(filename, connfd);
179 }
180 else {
181 strcpy(sendbuf, "Not Authorized");
182 send(connfd, sendbuf, strlen(sendbuf), 0);
183 }
184 up(&auth_array->sem);
185 }
186
187 }
188 close(connfd);
189 exit(EXIT_SUCCESS);
190 }
191 return 0;
192 }
- Code listing (level12.sem.c)
-
1 #include <unistd.h>
2
3
4 /* Get the semaphore and busy wait if held already */
5
6 void down(int *sem)
7 {
8 retry:
9 while(*sem)
10 sleep(5);
11 (*sem)++;
12 if(*sem > 1) {
13 (*sem)--;
14 goto retry;
15 }
16 return;
17 }
18
19 /* Try and get the semaphore, but return 0 if held */
20
21 int try_down(int *sem)
22 {
23 if(*sem)
24 return 0;
25 (*sem)++;
26 if(*sem > 1) {
27 (*sem)--;
28 return 0;
29 }
30 return *sem;
31 }
32
33 /* Release the semaphore */
34
35 void up(int *sem)
36 {
37 *sem = 0;
38 }
- Code listing (level12.sem.h)
-
1 int down(int *sem);
2 int try_down(int *sem);
3 void up(int *sem);
- Code listing (level12.server.h)
-
1 struct auth {
2 unsigned int token;
3 unsigned int perms;
4 unsigned int timestamp;
5 };
6
7
8 struct sharea {
9 int sem;
10 unsigned int bitmap;
11 struct auth list[32];
12 };