Compare commits

..

4 Commits

6 changed files with 1243 additions and 648 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.vscode/

211
client.c
View File

@ -8,6 +8,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <termios.h>
#define BUF 1024 #define BUF 1024
void remN(char *s) { void remN(char *s) {
@ -30,7 +31,6 @@ bool startsWith(const char *pre, const char *str)
} }
int main (int argc, char **argv) { int main (int argc, char **argv) {
int create_socket; int create_socket;
char buffer[BUF]; char buffer[BUF];
struct sockaddr_in address; struct sockaddr_in address;
@ -40,65 +40,100 @@ int main (int argc, char **argv) {
printf("Usage: %s ServerAdresse Port\n", argv[0]); printf("Usage: %s ServerAdresse Port\n", argv[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if ((create_socket = socket (AF_INET, SOCK_STREAM, 0)) == -1) if ((create_socket = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{ {
perror("Socket error"); perror("Socket error");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
memset(&address,0,sizeof(address)); memset(&address,0,sizeof(address));
address.sin_family = AF_INET; address.sin_family = AF_INET;
address.sin_port = htons (atoi(argv[2])); address.sin_port = htons (atoi(argv[2]));
inet_aton (argv[1], &address.sin_addr); inet_aton (argv[1], &address.sin_addr);
if (connect ( create_socket, (struct sockaddr *) &address, sizeof (address)) == 0) if (connect ( create_socket, (struct sockaddr *) &address, sizeof (address)) == 0)
{ {
printf ("Connection with server (%s) established\n", inet_ntoa (address.sin_addr)); printf ("\x1b[32mConnection with server (%s) established\n\x1b[0m", inet_ntoa (address.sin_addr));
size=recv(create_socket,buffer,BUF-1, 0); size=recv(create_socket,buffer,BUF-1, 0);
if (size>0) if (size>0)
{ {
buffer[size]= '\0'; buffer[size]= '\0';
printf("%s",buffer); printf("\x1b[36m%s\x1b[0m",buffer);
} }
} }
else else
{ {
perror("Connect error - no server available"); perror("\x1b[31mConnect error - no server available\x1b[0m");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
bool login = false;
do { do {
//command vom user überprüfen //command vom user überprüfen
char command[6] = ""; char command[7] = "";
printf ("\nEnter Command: \n"); printf ("\n\x1b[35mEnter Command:\x1b[0m \n");
fgets (command, 6, stdin); fgets (command, 7, stdin);
if (startsWith("login", command) == true && login == false)
{
char username[10] = "";
char pw[50] = "";
char bufferString[BUF] = "";
strcpy(bufferString, "login;");
//User Dateneingabe und daten einlesen
printf("\x1b[35m<Username max. 8 Zeichen>\x1b[0m\n");
fgets (username, 10, stdin);
printf("\x1b[35m<Passwort max. 50 Zeichen>\x1b[0m\n");
//PW eingabe unsichtbar machen
struct termios term, term_orig;
tcgetattr(STDIN_FILENO, &term);
term_orig = term;
term.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
scanf("%s", pw);
// Eingabe wieder sichtbar schalten
tcsetattr(STDIN_FILENO, TCSANOW, &term_orig);
strcat(bufferString, username);
strcat(bufferString, ";");
strcat(bufferString, pw);
remN(bufferString);
send(create_socket, bufferString, strlen (bufferString), 0);
//Response vom Server (OK oder ERR) empfangen und ausgeben
char readBuffer[BUF] = "";
read(create_socket , readBuffer, 1023);
remN(readBuffer);
if (strcmp("OK", readBuffer) == 0)
{
printf("\n\x1b[32m%s\x1b[0m\n", readBuffer);
login = true;
}else if (strcmp("ERR", readBuffer) == 0 || strcmp("Client Gesperrt", readBuffer) == 0)
{
printf("\n\x1b[31m%s\x1b[0m\n", readBuffer);
}
}else if (login == false && startsWith("quit", command) == true)
{
strcpy(buffer, "quit\n");
}else if (login == false)
{
printf("\x1b[33mBitte zuerst <login> eingeben. Erst danach können sie auf das Program zugreifen!\x1b[0m\n");
}
if(login == true){
//je nach command wird was audgeführt //je nach command wird was audgeführt
if(startsWith("send", command) == true) { if(startsWith("send", command) == true) {
char sender[10] = "";
char sender[8] = ""; char empfaenger[10] = "";
char empfaenger[8] = ""; char betreff[82] = "";
char betreff[80] = "";
char nachricht[128] = ""; char nachricht[128] = "";
char bufferString[BUF] = ""; char bufferString[BUF] = "";
strcpy(bufferString, ""); strcpy(bufferString, "");
strcat(bufferString, "send"); strcat(bufferString, "send");
//User Dateneingabe und daten einlesen //User Dateneingabe und daten einlesen
printf("<Sender max. 8 Zeichen>\n"); printf("\x1b[35m<Sender max. 8 Zeichen>\x1b[0m\n");
fgets (sender, 8, stdin); fgets (sender, 10, stdin);
printf("\x1b[35m<Empfänger max. 8 Zeichen>\x1b[0m\n");
printf("<Empfänger max. 8 Zeichen>\n"); fgets (empfaenger, 10, stdin);
fgets (empfaenger, 8, stdin); printf("\x1b[35m<Betreff max. 80 Zeichen>\x1b[0m\n");
fgets (betreff, 82, stdin);
printf("<Betreff max. 80 Zeichen>\n"); printf("\x1b[35m<Nachricht, beliebige Anzahl an Zeilen>\x1b[0m\n");
fgets (betreff, 80, stdin); fgets (nachricht, 82, stdin);
printf("<Nachricht, beliebige Anzahl an Zeilen>\n");
fgets (nachricht, 80, stdin);
//Buffer formatieren //Buffer formatieren
strcat(bufferString, ";"); strcat(bufferString, ";");
strcat(bufferString, sender); strcat(bufferString, sender);
@ -109,82 +144,61 @@ int main (int argc, char **argv) {
strcat(bufferString, ";"); strcat(bufferString, ";");
strcat(bufferString, nachricht); strcat(bufferString, nachricht);
remN(bufferString); remN(bufferString);
//printf("Buffer: %s", bufferString);
send(create_socket, bufferString, strlen (bufferString), 0); send(create_socket, bufferString, strlen (bufferString), 0);
//Response vom Server (OK oder ERR) empfangen und ausgeben //Response vom Server (OK oder ERR) empfangen und ausgeben
char readBuffer[BUF] = ""; char readBuffer[BUF] = "";
int valread = read(create_socket , readBuffer, 1024); read(create_socket , readBuffer, 1024);
printf("\n%s\n", readBuffer); printf("\n%s\n", readBuffer);
}else if(startsWith("list", command) == true) {
}
else if(startsWith("list", command) == true) {
char bufferString[BUF] = "list"; char bufferString[BUF] = "list";
char username[8] = ""; char username[10] = "";
char p[20] = ""; char p[22] = "";
int counter = 0; int counter = 0;
printf("\x1b[35m<Username max. 8 Zeichen>\x1b[0m\n");
printf("<Username max. 8 Zeichen>\n"); fgets (username, 10, stdin);
fgets (username, 8, stdin); printf("\x1b[35m<Posteingang oder Postausgang>\x1b[0m\n");
printf("<Posteingang oder Postausgang>\n"); fgets (p, 22, stdin);
fgets (p, 20, stdin);
strcat(bufferString, ";"); strcat(bufferString, ";");
strcat(bufferString, username); strcat(bufferString, username);
strcat(bufferString, ";"); strcat(bufferString, ";");
strcat(bufferString, p); strcat(bufferString, p);
remN(bufferString); remN(bufferString);
printf("%s ", bufferString);
send(create_socket, bufferString, strlen (bufferString), 0); send(create_socket, bufferString, strlen (bufferString), 0);
char readBuffer[BUF] = ""; char readBuffer[BUF] = "";
int valread = read(create_socket , readBuffer, 1024); read(create_socket , readBuffer, 1024);
char delimiter[] = ";"; char delimiter[] = ";";
char *ptr; char *ptr;
ptr = strtok(readBuffer, delimiter); ptr = strtok(readBuffer, delimiter);
while(ptr != NULL) { while(ptr != NULL) {
if(strcmp(ptr, ".") == 0) { if(strcmp(ptr, ".") == 0) {
} }else if(strcmp(ptr, "..") == 0) {
else if(strcmp(ptr, "..") == 0) { }else if (counter == 0) {
printf("\x1b[35m<Anzahl der Nachrichten für den User: %s>\x1b[0m\n", ptr);
} }else {
else if (counter == 0) {
printf("<Anzahl der Nachrichten für den User: %s>\n", ptr);
}
else {
printf("Betreff: %s \n", ptr); printf("Betreff: %s \n", ptr);
//printf("%.*s", 17, ptr + 5);
} }
counter = counter + 1; counter = counter + 1;
// naechsten Abschnitt erstellen // naechsten Abschnitt erstellen
ptr = strtok(NULL, delimiter); ptr = strtok(NULL, delimiter);
} }
}else if(startsWith("read", command) == true) {
}
else if(startsWith("read", command) == true) {
char bufferString[BUF] = "read"; char bufferString[BUF] = "read";
char username[8] = ""; char username[10] = "";
char nid[80] = ""; char nid[82] = "";
char folder[20] = ""; char folder[22] = "";
printf("<Username max. 8 Zeichen>\n"); printf("\x1b[35m<Username max. 8 Zeichen>\x1b[0m\n");
fgets (username, 8, stdin); fgets (username, 10, stdin);
printf("<posteingang oder postausgang>\n"); printf("\x1b[35m<posteingang oder postausgang>\x1b[0m\n");
fgets (folder, 20, stdin); fgets (folder, 22, stdin);
printf("<Nachrichten-Nummer>\n"); printf("\x1b[35m<Nachrichten-Nummer>\x1b[0m\n");
fgets (nid, 80, stdin); fgets (nid, 82, stdin);
strcat(bufferString, ";"); strcat(bufferString, ";");
strcat(bufferString, username); strcat(bufferString, username);
@ -194,32 +208,22 @@ int main (int argc, char **argv) {
strcat(bufferString, nid); strcat(bufferString, nid);
remN(bufferString); remN(bufferString);
//printf("%s ", bufferString);
send(create_socket, bufferString, strlen (bufferString), 0); send(create_socket, bufferString, strlen (bufferString), 0);
//strcpy(buffer, "");
//buffer[size]= '\0';
char readBuffer[BUF] = ""; char readBuffer[BUF] = "";
int valread = read(create_socket , readBuffer, 1000); read(create_socket , readBuffer, 1000);
printf("\n%s\n", readBuffer ); printf("\n%s\n", readBuffer );
}else if(startsWith("del", command) == true) {
} char username[10] = "";
char nachrichtennummer[82] = "";
else if(startsWith("del", command) == true) {
//printf("\n del");
char username[8] = "";
char nachrichtennummer[80] = "";
char bufferString[BUF] = "del"; char bufferString[BUF] = "del";
char p[20] = ""; char p[22] = "";
printf("<Username max. 8 Zeichen>\n"); printf("\x1b[35m<Username max. 8 Zeichen>\x1b[0m\n");
fgets (username, 8, stdin); fgets (username, 10, stdin);
printf("<Posteingang oder Postausgang>\n"); printf("\x1b[35m<Posteingang oder Postausgang>\x1b[0m\n");
fgets (p, 20, stdin); fgets (p, 22, stdin);
printf("<Nachrichten-Nummer>\n"); printf("\x1b[35m<Nachrichten-Nummer>\x1b[0m\n");
fgets (nachrichtennummer, 80, stdin); fgets (nachrichtennummer, 82, stdin);
strcat(bufferString, ";"); strcat(bufferString, ";");
strcat(bufferString, username); strcat(bufferString, username);
@ -228,28 +232,17 @@ int main (int argc, char **argv) {
strcat(bufferString, ";"); strcat(bufferString, ";");
strcat(bufferString, nachrichtennummer); strcat(bufferString, nachrichtennummer);
remN(bufferString); remN(bufferString);
//printf("%s ", bufferString);
send(create_socket, bufferString, strlen (bufferString), 0); send(create_socket, bufferString, strlen (bufferString), 0);
char readBuffer[BUF] = ""; char readBuffer[BUF] = "";
int valread = read(create_socket , readBuffer, 1024); read(create_socket , readBuffer, 1024);
printf("\n%s\n", readBuffer ); printf("\n%s\n", readBuffer );
}else if(startsWith("quit", command) == true) {
}
else if(startsWith("quit", command) == true) {
strcpy(buffer, "quit\n"); strcpy(buffer, "quit\n");
} }else {
else {
printf("DAS IST KEIN COMMAND!!!!!"); printf("DAS IST KEIN COMMAND!!!!!");
} }
} }
while (strcmp (buffer, "quit\n") != 0); }while (strcmp (buffer, "quit\n") != 0);
close (create_socket); close (create_socket);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1,25 +1,26 @@
#Client und Server kompilieren #Client und Server kompilieren
all: myserver.c myclient.c all: server.c client.c
gcc myserver.c -o myserver gcc -Wall -o server server.c -lldap -llber -lpthread
gcc myclient.c -o myclient gcc -Wall -o client client.c -lldap -llber -lpthread
#Kompilierten Client und Server löschen #Kompilierten Client und Server löschen
clean: myclient myserver clean: client server
rm -f myclient myserver rm -f client server
#Nur den Client kompilieren: #Nur den Client kompilieren:
client: myclient.c client: client.c
gcc myclient.c -o myclient gcc -Wall -o client client.c -lldap -llber -lpthread
#Nur den Server kompilieren: #Nur den Server kompilieren:
server: myserver.c server: server.c
gcc myserver.c -o myserver gcc -Wall -o server server.c -lldap -llber -lpthread
#Kompilierten Server löschen #Kompilierten Server löschen
cleanS: myserver cleanS: server
rm -f myserver rm -f server
#Kompilierten Client löschen #Kompilierten Client löschen
cleanC: myclient cleanC: client
rm -f myclient rm -f client

47
readme.md Normal file
View File

@ -0,0 +1,47 @@
# Protokoll 🔧
```
Als erstes muss der User immer der Befehl eingegeben (send, read, list oder delete). Danach schreibt der Client
immer eine Zeile, was der User als nächstes eingeben soll. Die Buffer Strings der Befehle sind folgerndermaßen
aufgebaut:
SEND: send;sender;empänger;betreff;nachricht
LIST: list;username;postEinAusgang
READ: read;username;postEinAusgang;nid
DEL: del;username;postEinAusgang;nid
Der Buffer wird immer als Ganzes (wie oben beschrieben) vom Client an den Server übertragen (nicht Blockweise).
Der Client fügt die Usereingaben als String zusammen und trennt sie mit einem ";". Der Server splittet den Befehl
dann anhand des Delimiters ";" und geht jedes einzelne Attribut (z.B. username, nid) in einer Schleife durch und
führt den entsprechende Aktionen aus. Als erstes Attribut steht immer der Befehl, damit der Server sofort erkennt,
welche Aktion er ausführen soll. Die nid (Nachrichten ID) wird am Server erzeugt und setzt sich aus einem Timestamp
+ dem Betreff zusammen.
Bei send und delete sendet der Server entweder OK oder ERR zurück. Bei list, die Anzahl der Nachrichten und pro
Zeile den Betreff. Bei read wird die gesamte Nachricht (nid, Sent From/To, Betreff, Nachricht) zurückgesendet.
Am Server gibt es die Verzeichnisse Posteingang und Postausgang. Darin sind Verzeichniss mit den jeweiligen
Usernamen und darin befinden sich .txt Dateien mit den Nachrichten.
Eine Nachricht wird zb. folgerndermaßen am Server gespeichert:
ID: 2020-10-2918:05:32hallo
Sent to: if20b206
Betreff: hallo
Message: wie gehts
```
# Installation
```
sudo apt-get install ldap-utils
sudo apt-get install libldap
sudo apt-get update -y
sudo apt-get install -y libldap-dev
```
# Erstellt von
* Lukas Nowy
* Georg Reisinger

View File

@ -1,4 +0,0 @@
SEND: send;sender;empänger;betreff;nachricht
LIST: list:username;postEinAusgang
READ: read;username;postEinAusgang;nid
DEL: del;username;postEinAusgang;nid

701
server.c
View File

@ -13,19 +13,265 @@
#include <stdbool.h> #include <stdbool.h>
#include <dirent.h> #include <dirent.h>
#include <time.h> #include <time.h>
#include <pthread.h>
#include <ldap.h>
#include <termios.h>
#define MAXCHAR 1000 #define MAXCHAR 1000
#define BUF 1024 #define BUF 1024
char *verzeichnis;
bool startsWith(const char *pre, const char *str) // Entfernt das \n und macht \0 daraus
void remN(char *s) {
char *p2 = s;
while(*s != '\0') {
if(*s != '\t' && *s != '\n') {
*p2++ = *s++;
} else {
++s;
}
}
*p2 = '\0';
}
//Checkt ob ein dir bereits existiert
bool dirExists(const char path[300]){
struct stat st = {0};
char cwd[300];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
//printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
}
strcat(cwd, path);
if (stat(cwd, &st) == 0) {
printf("\x1b[32mDir: %s exists!\x1b[0m\n", cwd);
return true;
}else
{ {
printf("\x1b[31mDir: %s gibt es NICHT!\x1b[0m\n", cwd);
return false;
}
}
//Erstellt ein Dir wenn nicht bereits vorhanden
void createDir(const char dir[]){
if(dirExists(dir) == false){
char cwd[300];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
//printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
}
strcat(cwd, dir);
if(mkdir(cwd, 0700) == -1)
{
printf("\x1b[31mFailed to create %s\x1b[0m\n", cwd);
perror("mkdir");
exit(EXIT_FAILURE);
}
else{
printf("\x1b[33mCreated directory: %s\x1b[0m\n", cwd);
}
}
}
// Die Denyfiles werden gelöscht -1 ist error
int stopDenyUser(char username[10]){
char cwd[300];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
//printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
}
strcat(cwd, "/");
strcat(cwd, verzeichnis);
strcat(cwd, "/deny/");
strcat(cwd, username);
DIR *d = opendir(cwd);
size_t path_len = strlen(cwd);
int r = -1;
if (d) {
struct dirent *p;
r = 0;
while (!r && (p=readdir(d))) {
int r2 = -1;
char *buf;
size_t len;
/* Skip the names "." and ".." as we don't want to recurse on them. */
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
continue;
len = path_len + strlen(p->d_name) + 2;
buf = malloc(len);
if (buf) {
struct stat statbuf;
snprintf(buf, len, "%s/%s", cwd, p->d_name);
if (!stat(buf, &statbuf)) {
if (S_ISDIR(statbuf.st_mode))
r2 = stopDenyUser(buf);
else
r2 = unlink(buf);
}
free(buf);
}
r = r2;
}
closedir(d);
}
if (!r)
r = rmdir(cwd);
return r;
}
// Zählt wv denys ein user bereits hat
int countDenyUser(char username[10]){
char dir[50];
strcpy(dir, "/");
strcat(dir, verzeichnis);
strcat(dir, "/deny/");
strcat(dir, username);
if (dirExists(dir) == false)
{
printf("\x1b[31mDIR Exists NICHT!\x1b[0m\n");
return 0;
}else
{
int file_count = 0;
DIR * dirp;
struct dirent * entry;
char cwd[1000];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
//printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
}
strcat(cwd, "/");
strcat(cwd, verzeichnis);
strcat(cwd, "/deny/");
strcat(cwd, username);
dirp = opendir(cwd); /* There should be error handling after this */
while ((entry = readdir(dirp)) != NULL) {
if (entry->d_type == DT_REG) { /* If the entry is a regular file */
file_count++;
}
}
closedir(dirp);
return file_count;
}
}
// Wenn der User 3 Deny Files hat, ist er gesperrt und es kommt true zurück
bool userDenied(char username[10]){
if (countDenyUser(username) == 3)
{
printf("\x1b[31mUser: %s ist gesperrt!\x1b[0m\n", username);
return true;
}else
{
printf("\x1b[32mUser: %s ist NICHT gesperrt!\x1b[0m\n", username);
return false;
}
}
// Erstellt ein Deny User eintrag
void createDenyUser(char username[10]){
char filename[1000];
strcpy(filename, "/");
strcat(filename, verzeichnis);
strcat(filename, "/deny/");
strcat(filename, username);
createDir(filename);
FILE *fp;
// Datum besorgen
char timeStr[22];
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(timeStr, sizeof(timeStr)-1, "%H:%M:%S", t);
char cwd[300];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
//printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
}
// Filename erstellen
strcpy(filename, cwd);
strcat(filename, "/");
strcat(filename, verzeichnis);
strcat(filename, "/deny/");
strcat(filename, username);
strcat(filename,"/");
strcat(filename,timeStr);
strcat(filename, ".txt");
// File erstellen
fp = fopen(filename, "w");
if(fp == NULL){
perror("fopen");
}
fprintf(fp, "DENY");
fclose(fp);
}
// True wenn der user wieder zugelassen werden darf
bool checkDeniedUser(char username[10]){
time_t now;
time(&now);
struct tm*local = localtime(&now);
int readHour = 0, readMinutes = 0, readSekundes = 0;
char cwd[1000];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
//printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
}
strcat(cwd, "/");
strcat(cwd, verzeichnis);
strcat(cwd, "/deny/");
strcat(cwd, username);
DIR *d;
struct dirent *dir;
d = opendir(cwd);
if (d)
{
while ((dir = readdir(d)) != NULL)
{
if(strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0){
//printf("%s\n", dir->d_name);
sscanf(dir->d_name, "%2d:%2d:%2d", &readHour, &readMinutes, &readSekundes);
struct tm breakdown = {0};
breakdown.tm_sec = readSekundes;
breakdown.tm_hour = readHour;
breakdown.tm_min = readMinutes;
breakdown.tm_year = local->tm_year;
breakdown.tm_mon = local->tm_mon;
breakdown.tm_mday = local->tm_mday;
time_t result;
if ((result = mktime(&breakdown)) == (time_t)-1) {
fprintf(stderr, "Could not convert time input to time_t\n");
perror("checkDeniedUser Read time from file");
}
double diff_t;
diff_t = difftime(now, result);
printf("\x1b[34mZeitdifferenz: %f\x1b[0m\n", diff_t);
if (diff_t >= 300 || diff_t <= -300) //300 = 5min
{
return true;
}
}
}
closedir(d);
}
return false;
}
bool startsWith(const char *pre, const char *str){
size_t lenpre = strlen(pre), size_t lenpre = strlen(pre),
lenstr = strlen(str); lenstr = strlen(str);
return lenstr < lenpre ? false : memcmp(pre, str, lenpre) == 0; return lenstr < lenpre ? false : memcmp(pre, str, lenpre) == 0;
} }
void mstore_data(const char *filepath, const char *data) void mstore_data(const char *filepath, const char *data){
{
FILE *fp = fopen(filepath, "ab"); FILE *fp = fopen(filepath, "ab");
if (fp != NULL) if (fp != NULL)
{ {
@ -39,66 +285,324 @@ int countFiles(char path[]) {
DIR * dirp; DIR * dirp;
struct dirent * entry; struct dirent * entry;
dirp = opendir(path); /* There should be error handling after this */ dirp = opendir(path);
while ((entry = readdir(dirp)) != NULL) { while ((entry = readdir(dirp)) != NULL) {
if (entry->d_type == DT_REG) { /* If the entry is a regular file */ if (entry->d_type == DT_REG) {
file_count++; file_count++;
} }
} }
closedir(dirp); closedir(dirp);
return file_count; return file_count;
} }
int login_user(char username[10], char pw[50]){
////////////////////////////////////////////////////////////////////////////
// LDAP config
// anonymous bind with user and pw empty
const char *ldapUri = "ldap://ldap.technikum-wien.at:389";
const int ldapVersion = LDAP_VERSION3;
int main (int argc, char **argv) { // read username (bash: export ldapuser=<yourUsername>)
int create_socket, new_socket; char ldapBindUser[256];
socklen_t addrlen; char rawLdapUser[128];
char buffer[BUF]; strcpy(rawLdapUser, username);
int size; sprintf(ldapBindUser, "uid=%s,ou=people,dc=technikum-wien,dc=at", rawLdapUser);
struct sockaddr_in address, cliaddress;
if( argc < 3 ){ // read password (bash: export ldappw=<yourPW>)
printf("Usage: %s S Port Verzeichniss\n", argv[0]); char ldapBindPassword[256];
exit(EXIT_FAILURE); strcpy(ldapBindPassword, pw);
}
create_socket = socket (AF_INET, SOCK_STREAM, 0); // search settings
const char *ldapSearchBaseDomainComponent = "dc=technikum-wien,dc=at";
const char *ldapSearchFilter = "(uid=if20b20*)";
ber_int_t ldapSearchScope = LDAP_SCOPE_SUBTREE;
const char *ldapSearchResultAttributes[] = {"uid", "cn", NULL};
memset(&address,0,sizeof(address)); // general
address.sin_family = AF_INET; int rc = 0; // return code
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons (atoi(argv[1]));
if (bind ( create_socket, (struct sockaddr *) &address, sizeof (address)) != 0) { ////////////////////////////////////////////////////////////////////////////
perror("bind error"); // setup LDAP connection
return EXIT_FAILURE; // https://linux.die.net/man/3/ldap_initialize
} LDAP *ldapHandle;
listen (create_socket, 5); rc = ldap_initialize(&ldapHandle, ldapUri);
if (rc != LDAP_SUCCESS)
addrlen = sizeof (struct sockaddr_in);
//Verzeichniss erstellen
mkdir(argv[2], 0711);
while (1) {
printf("Waiting for connections...\n");
new_socket = accept ( create_socket, (struct sockaddr *) &cliaddress, &addrlen );
if (new_socket > 0)
{ {
printf ("Client connected from %s:%d...\n", inet_ntoa (cliaddress.sin_addr),ntohs(cliaddress.sin_port)); fprintf(stderr, "ldap_init failed\n");
strcpy(buffer,"Welcome to myserver, Please enter your command:\n"); return 0;
}
printf("\x1b[32mconnected to LDAP server %s\x1b[0m\n", ldapUri);
////////////////////////////////////////////////////////////////////////////
// set verison options
// https://linux.die.net/man/3/ldap_set_option
rc = ldap_set_option(
ldapHandle,
LDAP_OPT_PROTOCOL_VERSION, // OPTION
&ldapVersion); // IN-Value
if (rc != LDAP_OPT_SUCCESS)
{
// https://www.openldap.org/software/man.cgi?query=ldap_err2string&sektion=3&apropos=0&manpath=OpenLDAP+2.4-Release
fprintf(stderr, "ldap_set_option(PROTOCOL_VERSION): %s\n", ldap_err2string(rc));
ldap_unbind_ext_s(ldapHandle, NULL, NULL);
return 0;
}
////////////////////////////////////////////////////////////////////////////
// start connection secure (initialize TLS)
// https://linux.die.net/man/3/ldap_start_tls_s
// int ldap_start_tls_s(LDAP *ld,
// LDAPControl **serverctrls,
// LDAPControl **clientctrls);
// https://linux.die.net/man/3/ldap
// https://docs.oracle.com/cd/E19957-01/817-6707/controls.html
// The LDAPv3, as documented in RFC 2251 - Lightweight Directory Access
// Protocol (v3) (http://www.faqs.org/rfcs/rfc2251.html), allows clients
// and servers to use controls as a mechanism for extending an LDAP
// operation. A control is a way to specify additional information as
// part of a request and a response. For example, a client can send a
// control to a server as part of a search request to indicate that the
// server should sort the search results before sending the results back
// to the client.
rc = ldap_start_tls_s(
ldapHandle,
NULL,
NULL);
if (rc != LDAP_SUCCESS)
{
fprintf(stderr, "ldap_start_tls_s(): %s\n", ldap_err2string(rc));
ldap_unbind_ext_s(ldapHandle, NULL, NULL);
return 0;
}
////////////////////////////////////////////////////////////////////////////
// bind credentials
// https://linux.die.net/man/3/lber-types
// SASL (Simple Authentication and Security Layer)
// https://linux.die.net/man/3/ldap_sasl_bind_s
// int ldap_sasl_bind_s(
// LDAP *ld,
// const char *dn,
// const char *mechanism,
// struct berval *cred,
// LDAPControl *sctrls[],
// LDAPControl *cctrls[],
// struct berval **servercredp);
BerValue bindCredentials;
bindCredentials.bv_val = (char *)ldapBindPassword;
bindCredentials.bv_len = strlen(ldapBindPassword);
BerValue *servercredp; // server's credentials
rc = ldap_sasl_bind_s(
ldapHandle,
ldapBindUser,
LDAP_SASL_SIMPLE,
&bindCredentials,
NULL,
NULL,
&servercredp);
if (rc != LDAP_SUCCESS)
{
fprintf(stderr, "LDAP bind error: %s\n", ldap_err2string(rc));
ldap_unbind_ext_s(ldapHandle, NULL, NULL);
return 0;
}
////////////////////////////////////////////////////////////////////////////
// perform ldap search
// https://linux.die.net/man/3/ldap_search_ext_s
// _s : synchronous
// int ldap_search_ext_s(
// LDAP *ld,
// char *base,
// int scope,
// char *filter,
// char *attrs[],
// int attrsonly,
// LDAPControl **serverctrls,
// LDAPControl **clientctrls,
// struct timeval *timeout,
// int sizelimit,
// LDAPMessage **res );
LDAPMessage *searchResult;
rc = ldap_search_ext_s(
ldapHandle,
ldapSearchBaseDomainComponent,
ldapSearchScope,
ldapSearchFilter,
(char **)ldapSearchResultAttributes,
0,
NULL,
NULL,
NULL,
500,
&searchResult);
if (rc != LDAP_SUCCESS)
{
fprintf(stderr, "LDAP search error: %s\n", ldap_err2string(rc));
ldap_unbind_ext_s(ldapHandle, NULL, NULL);
return 0;
}
// https://linux.die.net/man/3/ldap_count_entries
printf("\x1b[34mTotal results: %d\x1b[0m\n", ldap_count_entries(ldapHandle, searchResult));
////////////////////////////////////////////////////////////////////////////
// get result of search
// https://linux.die.net/man/3/ldap_first_entry
// https://linux.die.net/man/3/ldap_next_entry
LDAPMessage *searchResultEntry;
for (searchResultEntry = ldap_first_entry(ldapHandle, searchResult);
searchResultEntry != NULL;
searchResultEntry = ldap_next_entry(ldapHandle, searchResultEntry))
{
/////////////////////////////////////////////////////////////////////////
// Base Information of the search result entry
// https://linux.die.net/man/3/ldap_get_dn
printf("\x1b[35mDN: %s\x1b[0m\n", ldap_get_dn(ldapHandle, searchResultEntry));
/////////////////////////////////////////////////////////////////////////
// Attributes
// https://linux.die.net/man/3/ldap_first_attribute
// https://linux.die.net/man/3/ldap_next_attribute
//
// berptr: berptr, a pointer to a BerElement it has allocated to keep
// track of its current position. This pointer should be passed
// to subsequent calls to ldap_next_attribute() and is used to
// effectively step through the entry's attributes.
BerElement *ber;
char *searchResultEntryAttribute;
for (searchResultEntryAttribute = ldap_first_attribute(ldapHandle, searchResultEntry, &ber);
searchResultEntryAttribute != NULL;
searchResultEntryAttribute = ldap_next_attribute(ldapHandle, searchResultEntry, ber))
{
BerValue **vals;
if ((vals = ldap_get_values_len(ldapHandle, searchResultEntry, searchResultEntryAttribute)) != NULL)
{
for (int i = 0; i < ldap_count_values_len(vals); i++)
{
printf("\t\x1b[35m%s: %s\x1b[0m\n", searchResultEntryAttribute, vals[i]->bv_val);
if(strcmp(searchResultEntryAttribute,"uid") == 0){
if(strcmp(vals[i]->bv_val,rawLdapUser) == 0){
printf("\n\n\x1b[32mGEFUNDEN!!!!!!!!!!!!!!!!!\x1b[0m\n\n");
// Free Memory
ldap_value_free_len(vals);
ldap_memfree(searchResultEntryAttribute);
if (ber != NULL){
ber_free(ber, 0);
}
printf("\n");
ldap_msgfree(searchResult);
ldap_unbind_ext_s(ldapHandle, NULL, NULL);
return 1;
}
}
}
ldap_value_free_len(vals);
}
// free memory
ldap_memfree(searchResultEntryAttribute);
}
// free memory
if (ber != NULL)
{
ber_free(ber, 0);
}
printf("\n");
}
// free memory
ldap_msgfree(searchResult);
////////////////////////////////////////////////////////////////////////////
// https://linux.die.net/man/3/ldap_unbind_ext_s
// int ldap_unbind_ext_s(
// LDAP *ld,
// LDAPControl *sctrls[],
// LDAPControl *cctrls[]);
ldap_unbind_ext_s(ldapHandle, NULL, NULL);
return 0;
}
void *threadFun(void *arg){
int new_socket = *((int *)arg);
char buffer[BUF];
pthread_detach(pthread_self());
if(new_socket > 0){
strcpy(buffer, "Welcome to Lukas & Georgs Server, Please type <login> to login:\n");
send(new_socket, buffer, strlen(buffer),0); send(new_socket, buffer, strlen(buffer),0);
} }
//ab hier bool login = false;
do { do {
size = recv (new_socket, buffer, BUF-1, 0); int size = recv (new_socket, buffer, BUF-1, 0);
if( size > 0) if( size > 0)
{ {
buffer[size] = '\0'; buffer[size] = '\0';
if (login == false)
{
// Do login
if (strncmp("login", buffer, 5) == 0)
{
char delimiter[] = ";";
char *ptr;
//den buffer mit dem seperator splitten
ptr = strtok(buffer, delimiter);
int counter = 0;
char username[10];
char pw[50];
while(ptr != NULL) {
if (counter == 1) {
strcpy(username, ptr);
}else if(counter == 2)
{
strcpy(pw, ptr);
}
counter = counter + 1;
// naechsten Abschnitt erstellen
ptr = strtok(NULL, delimiter);
}
if(login_user(username, pw) == 1){
printf("\x1b[32mUser: %s hat den Login geschafft!!\x1b[0m\n", username);
if(checkDeniedUser(username) == true){
stopDenyUser(username);
}
if(userDenied(username) == true){
//ERR an den client zurücksenden
char err[] = "Client Gesperrt";
send(new_socket , err , strlen(err) , 0 );
}else{
//OK an den client zurücksenden
char suc[] = "OK";
login = true;
send(new_socket , suc , strlen(suc) , 0 );
stopDenyUser(username);
}
}else
{
printf("\x1b[31mUser: %s hat den Login NICHT geschafft!!\x1b[0m\n", username);
if(userDenied(username) == false){
createDenyUser(username);
//ERR an den client zurücksenden
char err[] = "ERR";
send(new_socket , err , strlen(err) , 0 );
}else{
//ERR an den client zurücksenden
char err[] = "Client Gesperrt";
send(new_socket , err , strlen(err) , 0 );
if(checkDeniedUser(username) == true){
stopDenyUser(username);
}
}
}
}
}else{// Is logedin
// Überprüfen welchen command der client eingegeben hat, // Überprüfen welchen command der client eingegeben hat,
// wenn command nicht zutreffend error zurücksenden // wenn command nicht zutreffend error zurücksenden
if(startsWith("send", buffer) == true) { if(startsWith("send", buffer) == true) {
@ -109,18 +613,14 @@ int main (int argc, char **argv) {
ptr = strtok(buffer, delimiter); ptr = strtok(buffer, delimiter);
int counter = 0; int counter = 0;
char filename1[] = ""; char sender[10] = "";
char filename2[] = ""; char empfaenger[10] = "";
char sender[8] = ""; char betreff[82] = "";
char content[] = "";
char empfaenger[8] = "";
char betreff[80] = "";
char nid[100] = "";
//timestamp als ersten teil der id erstellen //timestamp als ersten teil der id erstellen
char ts[20]; char ts[22];
time_t now = time(NULL); time_t now = time(NULL);
strftime(ts, 20, "%Y-%m-%d%H:%M:%S", localtime(&now)); strftime(ts, 22, "%Y-%m-%d%H:%M:%S", localtime(&now));
//den gesplitteten buffer schritt für schritt durchgehen //den gesplitteten buffer schritt für schritt durchgehen
@ -163,7 +663,7 @@ int main (int argc, char **argv) {
strcat(ts, betreff); strcat(ts, betreff);
//Pfad erstellen für den sender und file erstellen //Pfad erstellen für den sender und file erstellen
char fb[100] = "touch ./data/postausgang/"; char fb[300] = "touch ./data/postausgang/";
strcat(fb, "/"); strcat(fb, "/");
strcat(fb, sender); strcat(fb, sender);
strcat(fb, "/"); strcat(fb, "/");
@ -187,7 +687,7 @@ int main (int argc, char **argv) {
//printf("4 %s \n", ptr); //printf("4 %s \n", ptr);
//file content für den empfänger erstellen //file content für den empfänger erstellen
char fp[100] = "./data/posteingang/"; char fp[300] = "./data/posteingang/";
char content1[1000] = ""; char content1[1000] = "";
strcpy(content1, "ID: "); strcpy(content1, "ID: ");
strcat(content1, ts); strcat(content1, ts);
@ -251,10 +751,10 @@ int main (int argc, char **argv) {
int counter = 0; int counter = 0;
char username[8] = ""; char username[10] = "";
char nid[80] = ""; char nid[82] = "";
char p[20] = ""; char p[22] = "";
char path[100] = ""; char path[300] = "";
while(ptr != NULL) { while(ptr != NULL) {
@ -306,10 +806,10 @@ int main (int argc, char **argv) {
ptr = strtok(buffer, delimiter); ptr = strtok(buffer, delimiter);
int counter = 0; int counter = 0;
char username[8] = ""; char username[10] = "";
char nid[80] = ""; char nid[82] = "";
char betreff[80] = ""; char betreff[82] = "";
char folder[20] = ""; char folder[22] = "";
while(ptr != NULL) { while(ptr != NULL) {
@ -345,12 +845,10 @@ int main (int argc, char **argv) {
ptr_file = fopen(filename,"r"); ptr_file = fopen(filename,"r");
if (!ptr_file) if (!ptr_file)
return 1; perror("File Open error!");
while (fgets(buf,1000, ptr_file)!=NULL) { while (fgets(buf,1000, ptr_file)!=NULL) {
strcat(res, buf); strcat(res, buf);
} }
@ -379,9 +877,9 @@ int main (int argc, char **argv) {
ptr = strtok(buffer, delimiter); ptr = strtok(buffer, delimiter);
int counter = 0; int counter = 0;
char username[8] = ""; char username[10] = "";
char p[20] = ""; char p[22] = "";
char path[100] = ""; char path[300] = "";
while(ptr != NULL) { while(ptr != NULL) {
@ -448,14 +946,13 @@ int main (int argc, char **argv) {
} }
} }else {
else {
printf("error"); printf("error");
char err[] = "ERR"; char err[] = "ERR";
send(new_socket , err , strlen(err) , 0 ); send(new_socket , err , strlen(err) , 0 );
} }
}
//printf ("\n content: \n %s", buffer); //printf ("\n content: \n %s", buffer);
@ -463,7 +960,7 @@ int main (int argc, char **argv) {
} }
else if (size == 0) else if (size == 0)
{ {
printf("Client closed remote socket\n"); printf("\x1b[33mClient closed remote socket\x1b[0m\n");
break; break;
} }
else else
@ -471,11 +968,71 @@ int main (int argc, char **argv) {
perror("recv error"); perror("recv error");
char err[] = "ERR"; char err[] = "ERR";
send(new_socket , err , strlen(err) , 0 ); send(new_socket , err , strlen(err) , 0 );
return EXIT_FAILURE;
} }
} while (strncmp (buffer, "quit", 4) != 0); } while (strncmp (buffer, "quit", 4) != 0);
close (new_socket); close (new_socket);
pthread_exit(NULL);
}
int main (int argc, char **argv) {
int create_socket, new_socket;
socklen_t addrlen;
struct sockaddr_in address, cliaddress;
if( argc < 3 ){
printf("Usage: %s S Port Verzeichniss\n", argv[0]);
exit(EXIT_FAILURE);
}
create_socket = socket (AF_INET, SOCK_STREAM, 0);
memset(&address,0,sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons (atoi(argv[1]));
if (bind ( create_socket, (struct sockaddr *) &address, sizeof (address)) != 0) {
perror("bind error");
return EXIT_FAILURE;
}
listen (create_socket, 5);
addrlen = sizeof (struct sockaddr_in);
//Verzeichnisse erstellen
verzeichnis = argv[2];
char tmpVerzeichnis[300];
strcpy(tmpVerzeichnis, "/");
strcat(tmpVerzeichnis, verzeichnis);
createDir(tmpVerzeichnis);
char denyDir[300];
strcpy(denyDir, tmpVerzeichnis);
strcat(denyDir, "/deny");
createDir(denyDir);
char postausgang[300];
char posteingang[300];
strcpy(postausgang, tmpVerzeichnis);
strcat(postausgang, "/postausgang");
strcpy(posteingang, tmpVerzeichnis);
strcat(posteingang, "/posteingang");
createDir(postausgang);
createDir(posteingang);
pthread_t tid;
while (1) {
printf("\x1b[34mWaiting for connections...\x1b[0m\n");
new_socket = accept ( create_socket, (struct sockaddr *) &cliaddress, &addrlen );
if (new_socket > 0)
{
printf ("\x1b[32mClient connected from %s:%d...\x1b[0m\n", inet_ntoa (cliaddress.sin_addr),ntohs(cliaddress.sin_port));
}
if (pthread_create(&tid, NULL, threadFun, &new_socket) != 0)
{
perror("Failed to create thread");
exit(EXIT_FAILURE);
}
} }
close (create_socket); close (create_socket);
return EXIT_SUCCESS; return EXIT_SUCCESS;