-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathencrypt-daemon.c
332 lines (291 loc) · 11.1 KB
/
encrypt-daemon.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
/*
* Description: This program pairs with the encrypt-client program and functions as the server
* in the client / server communication model. This program takes a plaintext file and key
* from the client and encrypts the file using the provided key. The file is then returned
* to the client.
* **SOURCE: Much of the code is based from Beej's guide to Socket Programming at https://beej.us/guide/bgnet/html/multi/clientserver.html**
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <dirent.h>
/*Function Prototypes*/
void error(const char* message);
int createSocket(int portNum);
void readCommand(int establishedConnectionFD, int* dataPort, char* dataCommand, char* dataFile, char* buffer);
void sendDirectory(char* buffer, int dataSocketFD);
void sendReqFile(char* buffer, char* dataFile, int dataSocketFD);
void recMessage(char* buffer, int establishedConndectionFD, char* message, char* key);
void encryptMessage(char* key, char* message, char* encMessage);
void decryptMessage(char* key, char* message, char* decMessage);
void sendMessage(char* message, int establishedConnectionFD);
/*Main Function*/
int main(int argc, const char * argv[]) {
int listenSocketFD, listenDataSocketFD, establishedConnectionFD, dataSocketFD, portNumber, spawnPID;
int dataPort = 3333;
socklen_t sizeOfClientInfo, sizeOfClientInfo2;
char buffer[200000];
memset(buffer, '\0', 200000);
char dataCommand[1024];
memset(dataCommand, '\0', 1024);
char dataFile[1024];
memset(dataFile, '\0', 1024);
struct sockaddr_in clientAddress, clientAddress2;
char key[100000];
memset(key, '\0', 100000);
char message[100000];
memset(message, '\0', 100000);
char encMessage[100000];
memset(encMessage, '\0', 100000);
//Check if port number was given as an argument
if (argc < 2) {
fprintf(stderr,"Usage: %s port\n", argv[0]);
exit(1);
} else {
portNumber = atoi(argv[1]); //Get port number from command argument
}
listenSocketFD = createSocket(portNumber); //Create listening socket
//Keep server in infinite accept loop
while (1) {
//Accept connection (block while waiting for one to connect)
sizeOfClientInfo = sizeof(clientAddress); //Gets client address size
establishedConnectionFD = accept(listenSocketFD, (struct sockaddr*)&clientAddress, &sizeOfClientInfo); //Accepts connection
if (establishedConnectionFD < 0) {
error("Hull breach: accept()");
}
spawnPID = fork(); //Spawn new process for data handling
switch(spawnPID) {
case -1: //Error
error("Hull breach: fork()");
exit(1);
case 0: //Child handling data request
readCommand(establishedConnectionFD, &dataPort, dataCommand, dataFile, buffer);
listenDataSocketFD = createSocket(dataPort);
dataSocketFD = accept(listenDataSocketFD, (struct sockaddr*)&clientAddress2, &sizeOfClientInfo2);
//Execute specified command or return error if uknown
if ((strstr(dataCommand, "enc")) != NULL) { //Encrypt file
recMessage(buffer, dataSocketFD, message, key); //Get message/key
encryptMessage(key, message, encMessage); //Encrypt Message
sendMessage(encMessage, dataSocketFD); //Send encryption
} else if ((strstr(dataCommand, "dec")) != NULL) { //Wrong server
printf("otp_dec connecting to wrong server");
} else { //Error
printf("Data Command is: %s\n", dataCommand);
fflush(stdout);
error("Error reading command\n");
}
close(establishedConnectionFD);
close(listenDataSocketFD);
close(dataSocketFD);
exit(0);
break;
default:
//break;
close(establishedConnectionFD);
}
//close(establishedConnectionFD);
//wait(NULL);
}
close(listenSocketFD); //Close the listening socket
return 0;
}
/*
* Function: error
* Usage: error(message)
* -------------------------
* This function prints takes a string parameter which contains a message and outputs
* it as an error. It then exits the program with a status code of 1.
* SOURCE: Code based off CS344-400 lecture material 4.3
*/
void error(const char* message) {
perror(message);
exit(1);
}
/*
* Function: createSocket
* Usage: createSocket(12345)
* -------------------------
* This function creates a listening socket on the server and returns this socket
* back to the calling function. It takes one parameter which is the desired port
* number.
*/
int createSocket(int portNum) {
int listenSocketFD;
struct sockaddr_in serverAddress;
//Fill in address struct for the server
memset((char*)&serverAddress, '\0', sizeof(serverAddress)); //Initialize address struct
serverAddress.sin_family = AF_INET; //Set type to TCP
serverAddress.sin_port = htons(portNum); //Convert portNum to network byte order
serverAddress.sin_addr.s_addr = INADDR_ANY; //Accept from any IP address
//Setup the socket
listenSocketFD = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocketFD < 0) {
error("Hull Breach: socket()");
}
//Bind the socket
if (bind(listenSocketFD, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
printf("%s ", portNum); fflush(stdout);
error("Hull breach: bind()");
}
listen(listenSocketFD, 5); //Socket turned on and listens for up to 5 connections
return listenSocketFD;
}
/*
* Function: readCommand
* Usage: readCommand(socket, dataPort, command, buffer)
* -------------------------
* This function reads in a command line from a client. The format of the request
* must be passed in the following format "portNumber , command." This function
* makes use of the tokenizer to parse the command and determine the port number
* to send data back on as well as what data needs to be sent.
*/
void readCommand(int establishedConnectionFD, int* dataPort, char* dataCommand, char* dataFile, char* buffer) {
int charRead;
memset(buffer, '\0', 200000);
char* token;
//Read in command from client
charRead = recv(establishedConnectionFD, buffer, 199999, 0);
if (charRead < 0) {
error("Error: read()");
}
//Extract port number
token = strtok(buffer, ",");
*dataPort = atoi(token);
//Extract command
token = strtok(NULL, ",");
strcpy(dataCommand, token);
//Extract file name if the file transfer command given
if (strcmp(dataCommand, "-g") == 0) {
token = strtok(NULL, ",");
strcpy(dataFile, token);
}
}
/*
* Function: recMessage
* Usage: recMessage(buffer, scoket, message)
* -------------------------
* This function reads in data from a connected socket and stores it into the
* character string passed as a parameter. If no data is read, it will return an error
* message and exit.
*/
void recMessage(char* buffer, int establishedConndectionFD, char* message, char* key) {
int charRead;
memset(buffer, '\0', 200000);
char* token;
//Read in message from client
charRead = recv(establishedConndectionFD, buffer, 199999, 0);
if (charRead < 0) {
error("Error: read()");
}
//Extract message
token = strtok(buffer, ",");
strcpy(message, token);
//Extract key
token = strtok(NULL, ",");
strcpy(key, token);
}
/*
* Function: encryptMessage
* Usage: encryptMessage(key, message, encryptedMessage)
* -------------------------
* This function encrypts a message using a designated key. It first converts the key and
* message into integer values before adding them together and taking the modulo. The
* integers are then converted back to characters to represent the encrypted message.
*/
void encryptMessage(char* key, char* message, char* encMessage) {
int numMessage[99999] = {0};
int numMessageCount = 0;
int numKey[99999] = {0};
int numKeyCount = 0;
int encrypted[99999] = {0};
char letters[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i = 0, j = 0;
//Convert key into integers
for (i = 0; i < strlen(key); i++) {
while (key[i] != letters[j]) {
j++;
}
numKey[i] = j;
numKeyCount++;
j = 0;
}
//Convert original message into integers
for (i = 0; i < strlen(message); i++) {
while (message[i] != letters[j]) {
j++;
}
numMessage[i] = j;
numMessageCount++;
j = 0;
}
//Combine key and message into encrypted message
for (i = 0; i < numMessageCount; i++) {
encrypted[i] = ( numMessage[i] + numKey[i] ) % 27;
}
//Convert encrypted message from integer form back to characters
for (i = 0; i < numMessageCount; i++) {
encMessage[i] = letters[encrypted[i]];
}
}
/*
* Function: decryptMessage
* Usage: decryptMessage(key, message, encryptedMessage)
* -------------------------
* This function decrypts a message using a designated key. It first converts the key and
* message into integer values before adding them together and taking the modulo. The
* integers are then converted back to characters to represent the encrypted message.
*/
void decryptMessage(char* key, char* message, char* decMessage) {
int numMessage[99999] = {0};
int numMessageCount = 0;
int numKey[99999] = {0};
int numKeyCount = 0;
int decrypted[99999] = {0};
char letters[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i = 0, j = 0;
//Convert key into integers
for (i = 0; i < strlen(key); i++) {
while (key[i] != letters[j]) {
j++;
}
numKey[i] = j;
numKeyCount++;
j = 0;
}
//Convert original message into integers
for (i = 0; i < strlen(message); i++) {
while (message[i] != letters[j]) {
j++;
}
numMessage[i] = j;
numMessageCount++;
j = 0;
}
//Combine key and message into encrypted message
for (i = 0; i < numMessageCount; i++) {
decrypted[i] = ( numMessage[i] - numKey[i] ) ;
if (decrypted[i] < 0) {
decrypted[i] += 27;
}
}
//Convert encrypted message from integer form back to characters
for (i = 0; i < numMessageCount; i++) {
decMessage[i] = letters[decrypted[i]];
}
}
void sendMessage(char* message, int establishedConnectionFD) {
int charSend;
charSend = send(establishedConnectionFD, message, strlen(message), 0);
if(charSend < 0) {
error("Hull breach: error in sending encrypted message");
}
}