bakalarska_praca/kniznica/komunikacia.c
2020-04-16 11:25:05 +02:00

326 lines
8.8 KiB
C

//////////////////////////////////////////////////
// Bakalarska praca //
// Meno studenta: Tomas Lukac //
// Veduci BP: prof. Ing. Milos Drutarovsky CSc. //
// Skola: KEMT FEI TUKE //
// Datum poslednej upravy: 15.4.2020 //
//////////////////////////////////////////////////
#include "komunikacia.h"
#include "kryptografia.h"
int poslat_subor(WOLFSSL* ssl, WOLFSSL_CTX* ctx, const char* cesta, nastavenia_aplikacie *nastavenia)
{
int uspech;
//odoslanie nazvu (resp. cesty) suboru
uspech = 0;
while(uspech < VELKOST_CESTY)
{
uspech = wolfSSL_write(ssl, cesta, VELKOST_CESTY);
if(uspech <= 0)
{
fprintf(stderr, "Nastala chyba pri posielani dat o subore.\n");
return -1;
}
}
//otvorenie suboru na citanie
FILE* subor = fopen(cesta, "rb");
if(subor == NULL)
{
fprintf(stderr, "Nebolo mozne najst pozadovany subor.\n");
ukoncit_spojenie(ssl, ctx);
return -1;
}
else
{
printf("Posielam subor.\n");
//nastavi ukazovatel na koniec suboru
//a zisti velkost suboru
fseek(subor, 0, SEEK_END);
int velkost = (int)ftell(subor);
char velkost_suboru[VELKOST_SUBOR];
sprintf(velkost_suboru, "%ld", velkost);
printf("Velkost suboru: %s bajtov\n", velkost_suboru);
uspech = 0;
while(uspech < VELKOST_SUBOR)
{
uspech = wolfSSL_write(ssl, velkost_suboru, VELKOST_SUBOR);
if(uspech <= 0)
{
fprintf(stderr, "Nastala chyba pri posielani dat o velkosti suboru.\n");
return -1;
}
}
//nastavi ukazovatel na zaciatok suboru
//a nacita data zo suboru do pola
unsigned char* pole = calloc(velkost, sizeof(unsigned char));
fseek(subor, 0, SEEK_SET);
fread((unsigned char*)pole, 1, velkost, subor);
//posielanie jednotlivych bajtov
uspech = 0;
while(uspech < velkost)
{
uspech = wolfSSL_write(ssl, (unsigned char*)pole, velkost);
if(uspech <= 0)
{
fprintf(stderr, "Nastala chyba pri posielani suboru.\n");
return -1;
}
}
printf("Subor bol uspesne odoslany.\n");
//generovanie a poslanie kontrolneho suctu serveru pre kontrolu
byte* kontrolny_sucet;
int velkost_kontrolneho_suctu;
kontrolny_sucet = generovat_kontrolny_sucet_suboru(nastavenia, cesta, &velkost_kontrolneho_suctu);
uspech = 0;
while(uspech < velkost_kontrolneho_suctu)
{
uspech = wolfSSL_write(ssl, kontrolny_sucet, velkost_kontrolneho_suctu);
if(uspech <= 0)
{
fprintf(stderr, "Nastala chyba pri posielani kontrolneho suctu.\n");
return -1;
}
}
free(kontrolny_sucet);
fclose(subor);
free(pole);
return 0;
}
}
int prijat_subor(WOLFSSL* ssl, WOLFSSL_CTX* ctx, nastavenia_aplikacie* nastavenia)
{
int uspech;
//prijem dat o subore
char* cesta = calloc(VELKOST_CESTY, sizeof(char));
char* velkost_suboru = calloc(VELKOST_SUBOR, sizeof(char));
uspech = 0;
while(uspech < VELKOST_CESTY)
{
uspech = wolfSSL_read(ssl, cesta, VELKOST_CESTY);
if(uspech <= 0)
{
fprintf(stderr, "Nastala chyba pri prijati dat o subore\n");
return -1;
}
}
printf("Prebieha prijimanie suboru %s\n", cesta);
//ziskanie informacie od klienta o velkosti odoslaneho suboru
uspech = 0;
while(uspech < VELKOST_SUBOR)
{
uspech = wolfSSL_read(ssl, velkost_suboru, VELKOST_SUBOR);
if(uspech <= 0)
{
fprintf(stderr, "Nastala chyba pri prijati velkosti suboru\n");
return -1;
}
}
int velkost = (int)atol(velkost_suboru);
if(velkost < 1)
{
printf("Nastala chyba pri prijati suboru\n");
return -1;
}
else
{
printf("Velkost suboru: %s bajtov\n", velkost_suboru);
}
//prijem jednotlivych bajtov
unsigned char* pole = calloc(velkost, sizeof(unsigned char));
uspech = 0;
while(uspech < velkost)
{
uspech = wolfSSL_read(ssl, (unsigned char*)pole, velkost);
if(uspech <= 0)
{
fprintf(stderr, "Nastala chyba pri prijatii suboru.\n");
return -1;
}
}
printf("Subor bol uspesne prijaty.\n");
//vypocet vlastneho kontrolneho suctu
byte* kontrolny_sucet;
int velkost_kontrolneho_suctu;
FILE *subor = fopen(cesta, "wb+");
int n = fwrite((unsigned char*)pole, 1, velkost, subor);
fclose(subor);
kontrolny_sucet = generovat_kontrolny_sucet_suboru(nastavenia, cesta, &velkost_kontrolneho_suctu);
//prijem hashu, ktory vypocital server
char* prijaty_kontrolny_sucet = calloc(velkost_kontrolneho_suctu, sizeof(char));
uspech = 0;
while(uspech != velkost_kontrolneho_suctu)
{
uspech = wolfSSL_read(ssl, (char*)prijaty_kontrolny_sucet, velkost_kontrolneho_suctu);
if(uspech <= 0)
{
fprintf(stderr, "Nastala chyba pri prijati kontrolneho suctu.\n");
free(prijaty_kontrolny_sucet);
return -1;
}
}
//kontrola ci sa prijaty a vypocitany kontrolny sucet suboru zhoduju
if(!strcmp((char*)prijaty_kontrolny_sucet, (char*)kontrolny_sucet))
{
printf("Subor prisiel v poriadku.\n");
}
else
{
fprintf(stderr, "Kontrolne sucty sa nezhoduju.\n");
printf("Subor neprisiel v poriadku alebo neboli pouzite rovnake funkcie.\n");
return -1;
}
char*data = calloc(100, sizeof(char));
uspech = wolfSSL_read(ssl, data, 100);
free(data);
free(cesta);
free(velkost_suboru);
free(kontrolny_sucet);
free(prijaty_kontrolny_sucet);
return 0;
}
int pripojit_na_server(char *ip_adresa, int cislo_portu, int pocet_sekund)
{
struct timeval casovy_interval;
int uspech;
int cislo_soketu;
struct hostent* hostitel;
struct sockaddr_in adresa;
fd_set sada_soketov;
socklen_t velkost_soketu;
int optval;
if((hostitel = gethostbyname(ip_adresa)) == NULL)
{
printf("Nastala chyba pri spracovani nazvu hostitela.\n");
return 0;
}
printf("Vytvaranie soketu...\n");
cislo_soketu = socket(AF_INET, SOCK_STREAM, 0);
memset(&adresa, 0, sizeof(adresa));
adresa.sin_family = AF_INET; //IPv4
adresa.sin_port = htons(cislo_portu);
adresa.sin_addr.s_addr = *(long*)(hostitel->h_addr);
//pokus o pripojenie s casovym intervalom
uspech = connect(cislo_soketu, (struct sockaddr*)&adresa, sizeof(adresa));
if(uspech < 0)
{
#if defined(_WIN32)
if(errno == WSAEINPROGRESS )
#else
if(errno == EINPROGRESS )
#endif
{
fprintf(stderr, "Nebolo mozne okamzite vytvorit spojenie\n");
do
{
casovy_interval.tv_sec = pocet_sekund;
casovy_interval.tv_usec = 0;
FD_ZERO(&sada_soketov);
FD_SET(cislo_soketu, &sada_soketov);
uspech = select(cislo_soketu + 1, NULL, &sada_soketov, NULL, &casovy_interval);
#if defined(_WIN32)
if (uspech < 0 && errno != WSAEINTR)
#else
if (uspech < 0 && errno != EINTR)
#endif
{
fprintf(stderr, "Nastala chyba pri pokuse o vytvorenie spojenia\nCislo chyby: %d\nPopis: %s\n", errno, strerror(errno));
ukoncit_soket(cislo_soketu);
exit(0);
}
//bol zvoleny soket
else if(uspech > 0)
{
velkost_soketu = sizeof(int);
if (getsockopt(cislo_soketu, SOL_SOCKET, SO_ERROR, (void*)(&optval), &velkost_soketu) < 0)
{
fprintf(stderr, "Nastala chyba v nastaveni soketu\nCislo chyby: %d\nPopis: %s\n", errno, strerror(errno));
ukoncit_soket(cislo_soketu);
exit(0);
}
if(optval)
{
fprintf(stderr, "Nastala chyba v spojeni\nCislo chyby: %d\nPopis: %s\n", optval, strerror(optval));
ukoncit_soket(cislo_soketu);
exit(0);
}
break;
}
else
{
fprintf(stderr, "Casovy interval vyprsal\n");
ukoncit_soket(cislo_soketu);
exit(0);
}
} while(1);
}
else
{
fprintf(stderr, "Spojenie zlyhalo.\nCislo chyby: %d\nPopis: %s\n", errno, strerror(errno));
ukoncit_soket(cislo_soketu);
exit(0);
}
}
return cislo_soketu;
}
int cakat_na_komunikaciu(int cislo_portu)
{
int cislo_soketu;
struct sockaddr_in adresa;
printf("Vytvaranie socketu...\n");
cislo_soketu = socket(PF_INET, SOCK_STREAM, 0);
memset(&adresa, 0, sizeof(adresa));
adresa.sin_family = AF_INET; //IPv4
adresa.sin_port = htons(cislo_portu);
adresa.sin_addr.s_addr = INADDR_ANY;
if(bind(cislo_soketu, (struct sockaddr*)&adresa, sizeof(adresa)) != 0)
{
fprintf(stderr, "Nebolo mozne priradit soket ku danemu portu.\n");
return 0;
}
//maximalna velkost do ktorej rada cakajucich spojeni pre soket moze rast
int velkost_radu = 10;
if(listen(cislo_soketu, velkost_radu) != 0)
{
fprintf(stderr, "Na danom porte nie je mozne cakat na komunikaciu.\n");
return 0;
}
else
{
printf("Server caka na komunikaciu na porte %d.\n", cislo_portu);
}
return cislo_soketu;
}