546 lines
16 KiB
C
546 lines
16 KiB
C
//////////////////////////////////////////////////
|
|
// Bakalarska praca //
|
|
// Meno studenta: Tomas Lukac //
|
|
// Veduci BP: prof. Ing. Milos Drutarovsky CSc. //
|
|
// Skola: KEMT FEI TUKE //
|
|
// Datum poslednej upravy: 6.5.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));
|
|
if(pole == NULL)
|
|
{
|
|
fprintf(stderr, "Nepodarilo sa dynamicky alokovat pamat pre pole\n");
|
|
return -1;
|
|
}
|
|
fseek(subor, 0, SEEK_SET);
|
|
fread((unsigned char*)pole, 1, velkost, subor);
|
|
|
|
//posielanie jednotlivych bajtov
|
|
uspech = 0;
|
|
while(uspech < velkost)
|
|
{
|
|
uspech = wolfSSL_write(ssl, 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
|
|
unsigned char* kontrolny_sucet;
|
|
int velkost_kontrolneho_suctu;
|
|
kontrolny_sucet = generovat_kontrolny_sucet_suboru(nastavenia, cesta, velkost, &velkost_kontrolneho_suctu);
|
|
|
|
uspech = 0;
|
|
while(uspech < velkost_kontrolneho_suctu)
|
|
{
|
|
uspech = wolfSSL_write(ssl, kontrolny_sucet, velkost_kontrolneho_suctu);
|
|
}
|
|
free(kontrolny_sucet);
|
|
fclose(subor);
|
|
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));
|
|
if(pole == NULL)
|
|
{
|
|
fprintf(stderr, "Nepodarilo sa dynamicky alokovat pamat pre pole\n");
|
|
return -1;
|
|
}
|
|
unsigned char* pole_uk = pole;
|
|
|
|
uspech = 0;
|
|
for(int i = 0; i < (velkost/16384) + 1; ++i)
|
|
{
|
|
uspech = wolfSSL_read(ssl, pole_uk, velkost);
|
|
pole_uk += 16384;
|
|
if(uspech <= 0)
|
|
{
|
|
fprintf(stderr, "Nastala chyba pri posielani suboru.\n");
|
|
return -1;
|
|
}
|
|
}
|
|
printf("Subor bol uspesne prijaty.\n");
|
|
|
|
//vypocet vlastneho kontrolneho suctu
|
|
unsigned char* 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, &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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
int rs232_otvorit_rozhranie(int cislo_rozhrania, int rychlost, char* rezim, int kontrola_toku_dat)
|
|
{
|
|
int uspech = 0;
|
|
uspech = RS232_OpenComport(cislo_rozhrania, rychlost, rezim, kontrola_toku_dat);
|
|
if(uspech == 1)
|
|
{
|
|
fprintf(stderr, "Nebolo mozne otvorit seriove rozhranie\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int rs232_zatvorit_rozhranie(int cislo_rozhrania)
|
|
{
|
|
RS232_CloseComport(cislo_rozhrania);
|
|
return 0;
|
|
}
|
|
|
|
int rs232_odoslat_spravu(int cislo_rozhrania, char* sprava, int velkost_spravy)
|
|
{
|
|
int uspech = 0;
|
|
int odoslane_data = 0;
|
|
|
|
//kontrolne vzory, ktore jednoznacne identifikuju zaciatok a koniec spravy
|
|
unsigned char kontrolny_vzor[] = {0xAA, 0xAA, 0xAA, 0xAA};
|
|
|
|
//vytvorenie bajtov ktore budu niest informaciu o velkosti posielanej spravy
|
|
unsigned char* velkost_spravy_hex = calloc(4, sizeof(unsigned char));
|
|
velkost_spravy_hex[0] = (velkost_spravy >> 24) & 0xFF;
|
|
velkost_spravy_hex[1] = (velkost_spravy >> 16) & 0xFF;
|
|
velkost_spravy_hex[2] = (velkost_spravy >> 8) & 0xFF;
|
|
velkost_spravy_hex[3] = velkost_spravy & 0xFF;
|
|
|
|
//vypocet kontrolneho suctu spravy
|
|
unsigned int kontrolny_sucet = crc32(0L, Z_NULL, 0);
|
|
if(velkost_spravy < 10)
|
|
{
|
|
kontrolny_sucet = crc32(kontrolny_sucet, (char*)sprava, velkost_spravy);
|
|
}
|
|
else
|
|
{
|
|
kontrolny_sucet = crc32(kontrolny_sucet, (char*)sprava, 10);
|
|
}
|
|
|
|
//vytvorenie bajtov ktore budu niest informaciu s kontrolnym suctom posielanej spravy
|
|
unsigned char* kontrolny_sucet_hex = calloc(4, sizeof(unsigned char));
|
|
kontrolny_sucet_hex[0] = (kontrolny_sucet >> 24) & 0xFF;
|
|
kontrolny_sucet_hex[1] = (kontrolny_sucet >> 16) & 0xFF;
|
|
kontrolny_sucet_hex[2] = (kontrolny_sucet >> 8) & 0xFF;
|
|
kontrolny_sucet_hex[3] = kontrolny_sucet & 0xFF;
|
|
|
|
//odoslanie kontrolneho vzoru
|
|
uspech = RS232_SendBuf(cislo_rozhrania, (unsigned char*)kontrolny_vzor, 4);
|
|
if(uspech <= 0)
|
|
{
|
|
fprintf(stderr, "Nastala chyba pri odoslani kontrolneho vzoru\n");
|
|
return -1;
|
|
}
|
|
|
|
//odoslanie velkosti spravy
|
|
uspech = RS232_SendBuf(cislo_rozhrania, (unsigned char*)velkost_spravy_hex, 4);
|
|
if(uspech <= 0)
|
|
{
|
|
fprintf(stderr, "Nastala chyba pri odoslani velkosti spravy\n");
|
|
return -1;
|
|
}
|
|
|
|
//odoslanie kontrolneho suctu
|
|
uspech = RS232_SendBuf(cislo_rozhrania, (unsigned char*)kontrolny_sucet_hex, 4);
|
|
if(uspech <= 0)
|
|
{
|
|
fprintf(stderr, "Nastala chyba pri odoslani kontrolneho suctu\n");
|
|
return -1;
|
|
}
|
|
|
|
//odoslanie dat
|
|
odoslane_data = RS232_SendBuf(cislo_rozhrania, (unsigned char*)sprava, velkost_spravy);
|
|
if(odoslane_data <= 0 || odoslane_data != velkost_spravy)
|
|
{
|
|
fprintf(stderr, "Nastala chyba pri odoslani dat\n");
|
|
return -1;
|
|
}
|
|
|
|
free(velkost_spravy_hex);
|
|
free(kontrolny_sucet_hex);
|
|
|
|
return odoslane_data;
|
|
}
|
|
int rs232_prijat_spravu(int cislo_rozhrania, const char* komunikacny_subor)
|
|
{
|
|
//otvorenie suboru do ktoreho sa zapisuju prijate binarne data
|
|
//ktore sa nasledne nacitaju do buffera (buf) pre desifrovanie
|
|
FILE* subor = fopen(komunikacny_subor, "ab+");
|
|
|
|
int uspech = 0;
|
|
int prebieha_nacitanie_velkosti_spravy = 0;
|
|
int prebieha_nacitanie_kontrolneho_suctu = 0;
|
|
int prebieha_nacitanie_dat = 0;
|
|
unsigned char znak;
|
|
|
|
//mnozstvo nacitanych dat
|
|
int nacitane_data = 0;
|
|
|
|
//velkost spravy, ktora sa bude prijmat
|
|
int velkost_spravy = 0;
|
|
unsigned char velkost_spravy_hex[4];
|
|
//urcuje kolko bajtov z informacie o velkosti spravy
|
|
//uz bolo prijatych z celkoveho poctu (4)
|
|
int velkost_spravy_pozicia = 0;
|
|
|
|
//kontrolny sucet, ktory sa bude prijimat
|
|
int kontrolny_sucet = 0;
|
|
unsigned char kontrolny_sucet_hex[4];
|
|
//urcuje kolko bajtov z kontrolneho suctu
|
|
//uz bolo prijatych z celkoveho poctu (4)
|
|
int kontrolny_sucet_pozicia = 0;
|
|
|
|
unsigned char* prijate_data;
|
|
|
|
//kontrolny vzor ktory jednoznacne identifikuje zaciatok spravy
|
|
unsigned char kontrolny_vzor[] = {0xAA, 0xAA, 0xAA, 0xAA};
|
|
int kontrolny_vzor_pozicia = 0; //aktualna pozicia v kontrolnom vzore
|
|
int velkost_kontrolneho_vzoru = sizeof(kontrolny_vzor)/sizeof(kontrolny_vzor[0]);
|
|
|
|
while(1)
|
|
{
|
|
uspech = RS232_PollComport(cislo_rozhrania, &znak, 1);
|
|
if(uspech > 0)
|
|
{
|
|
//nacitanie kontrolneho vzoru
|
|
if(!prebieha_nacitanie_velkosti_spravy && !prebieha_nacitanie_dat && !prebieha_nacitanie_kontrolneho_suctu &&
|
|
znak == kontrolny_vzor[kontrolny_vzor_pozicia])
|
|
{
|
|
kontrolny_vzor_pozicia++;
|
|
if(kontrolny_vzor_pozicia == 4)
|
|
{
|
|
prebieha_nacitanie_velkosti_spravy = 1;
|
|
kontrolny_vzor_pozicia = 0;
|
|
}
|
|
}
|
|
//nacitanie velkosti spravy
|
|
else if(!prebieha_nacitanie_dat && prebieha_nacitanie_velkosti_spravy)
|
|
{
|
|
velkost_spravy_hex[velkost_spravy_pozicia] = znak;
|
|
velkost_spravy_pozicia++;
|
|
if(velkost_spravy_pozicia == 4)
|
|
{
|
|
velkost_spravy = (uint32_t)velkost_spravy_hex[0] << 24 | (uint32_t)velkost_spravy_hex[1] << 16 |
|
|
(uint32_t)velkost_spravy_hex[2] << 8 | (uint32_t)velkost_spravy_hex[3];
|
|
prebieha_nacitanie_kontrolneho_suctu = 1;
|
|
prebieha_nacitanie_velkosti_spravy = 0;
|
|
|
|
prijate_data = calloc(velkost_spravy, sizeof(unsigned char));
|
|
if(prijate_data == NULL)
|
|
{
|
|
fprintf(stderr, "Nepodarilo sa dynamicky alokovat pamat pre prijate_data\n");
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
//nacitanie kontrolneho vzoru
|
|
else if(!prebieha_nacitanie_dat && prebieha_nacitanie_kontrolneho_suctu)
|
|
{
|
|
kontrolny_sucet_hex[kontrolny_sucet_pozicia] = znak;
|
|
kontrolny_sucet_pozicia++;
|
|
if(kontrolny_sucet_pozicia == 4)
|
|
{
|
|
kontrolny_sucet = (uint32_t)kontrolny_sucet_hex[0] << 24 | (uint32_t)kontrolny_sucet_hex[1] << 16 |
|
|
(uint32_t)kontrolny_sucet_hex[2] << 8 | (uint32_t)kontrolny_sucet_hex[3];
|
|
prebieha_nacitanie_dat = 1;
|
|
prebieha_nacitanie_velkosti_spravy = 0;
|
|
}
|
|
}
|
|
//nacitanie dat
|
|
else
|
|
{
|
|
if(prebieha_nacitanie_dat)
|
|
{
|
|
prijate_data[nacitane_data] = znak;
|
|
nacitane_data += uspech;
|
|
if(nacitane_data == velkost_spravy) break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//kontrola integrity prijatej spravy
|
|
//vypocet kontrolneho suctu prijatej spravy
|
|
unsigned int kontrolny_sucet_ps = crc32(0L, Z_NULL, 0);
|
|
if(velkost_spravy < 10)
|
|
{
|
|
kontrolny_sucet_ps = crc32(kontrolny_sucet_ps, (char*)prijate_data, velkost_spravy);
|
|
}
|
|
else
|
|
{
|
|
kontrolny_sucet_ps = crc32(kontrolny_sucet_ps, (char*)prijate_data, 10);
|
|
}
|
|
|
|
//porovnanie kontrolnych suctov
|
|
if(kontrolny_sucet_ps == kontrolny_sucet)
|
|
{
|
|
//ak sprava prisla v poriadku zapis nacitane data do suboru
|
|
fwrite((char*)prijate_data, 1, nacitane_data, subor);
|
|
}
|
|
else
|
|
{
|
|
printf("Sprava neprisla v poriadku");
|
|
return -1;
|
|
}
|
|
|
|
free(prijate_data);
|
|
fclose(subor);
|
|
|
|
return nacitane_data;
|
|
}
|
|
|
|
|
|
|