Klient.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. #include <openssl/bio.h>
  2. #include <openssl/ssl.h>
  3. #include "Klient.h"
  4. #ifndef WIN32
  5. #include <string.h>
  6. #include <netdb.h>
  7. #include <sys/select.h>
  8. #endif
  9. #include <Key.h>
  10. #include <Datei.h>
  11. using namespace Network;
  12. // inhalt der Klient Klasse aus Klient.h
  13. // Konstruktor
  14. Klient::Klient()
  15. : ReferenceCounter()
  16. {
  17. memset(&server, 0, sizeof(server));
  18. server.sin_family = AF_INET;
  19. downStreamBytes = 0;
  20. upStreamBytes = 0;
  21. sock = 0;
  22. sendeKey = 0;
  23. empfangKey = 0;
  24. }
  25. // Destruktoe
  26. Klient::~Klient()
  27. {
  28. if (sock)
  29. trenne();
  30. if (sendeKey)
  31. sendeKey->release();
  32. if (empfangKey)
  33. empfangKey->release();
  34. }
  35. // nicht constant
  36. void Klient::setSendeKeyZ(Encryption::Key* key) // Setzt den Key fürs Senden
  37. {
  38. if (sendeKey)
  39. sendeKey->release();
  40. sendeKey = key;
  41. }
  42. void Klient::setEmpfangKeyZ(Encryption::Key* key) // Setzt den Key fürs Empfangen
  43. {
  44. if (empfangKey)
  45. empfangKey->release();
  46. empfangKey = key;
  47. }
  48. void Klient::setSendeKey(const char* key, int len) // Setzt den Key fürs Senden
  49. {
  50. if (!sendeKey)
  51. sendeKey = new Encryption::Key();
  52. sendeKey->setKey(key, len);
  53. }
  54. void Klient::setEmpfangKey(const char* key, int len) // Setzt den Key fürs Empfangen
  55. {
  56. if (!empfangKey)
  57. empfangKey = new Encryption::Key();
  58. empfangKey->setKey(key, len);
  59. }
  60. bool Klient::verbinde(unsigned short port, const char* ip) // verbindet mit Server
  61. {
  62. if (sendeKey)
  63. sendeKey->setPos(0);
  64. if (empfangKey)
  65. empfangKey->setPos(0);
  66. if (sock)
  67. closesocket(sock);
  68. sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  69. long sIp = inet_addr(ip); // ip addresse
  70. if (sIp == INADDR_NONE)
  71. {
  72. struct hostent* pHostInfo = gethostbyname(ip);
  73. if (pHostInfo == 0)
  74. return 0;
  75. sIp = *(long*)pHostInfo->h_addr_list[0];
  76. }
  77. memcpy((char*)&server.sin_addr, &sIp, sizeof(sIp));
  78. server.sin_port = htons(port); // port
  79. if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) // verbinden
  80. return 0; // Fehler
  81. return 1;
  82. }
  83. bool Klient::sende(const char* nachricht, int len) // sendet zum Server
  84. {
  85. int ll = 0;
  86. while (len > 0)
  87. {
  88. #ifdef WIN32
  89. int l = send(sock, nachricht + ll, len, 0);
  90. #else
  91. int l = (int)send(sock, nachricht + ll, len, MSG_NOSIGNAL);
  92. #endif
  93. if (l <= 0)
  94. return 0; // Fehler
  95. len -= l;
  96. ll += l;
  97. }
  98. upStreamBytes += ll;
  99. return 1;
  100. }
  101. bool Klient::getNachricht(char* nachricht, int len) // empfängt Nachricht
  102. {
  103. int ll = 0;
  104. while (len > 0)
  105. {
  106. int l = (int)recv(sock, nachricht + ll, len, MSG_WAITALL);
  107. if (l <= 0)
  108. return 0; // Fehler
  109. len -= l;
  110. ll += l;
  111. }
  112. downStreamBytes += ll;
  113. return 1;
  114. }
  115. bool Klient::sendeEncrypted(const char* nachricht, int len) // sendet zum Server
  116. {
  117. if (!sendeKey)
  118. return sende(nachricht, len);
  119. Encryption::Bytes* n = new Encryption::Bytes(nachricht, len);
  120. sendeKey->codieren(dynamic_cast<Framework::Encryption::Bytes*>(n->getThis()));
  121. int ll = 0;
  122. while (len > 0)
  123. {
  124. #ifdef WIN32
  125. int l = send(sock, n->getBytes() + ll, len, 0);
  126. #else
  127. int l = (int)send(sock, n->getBytes() + ll, len, MSG_NOSIGNAL);
  128. #endif
  129. if (l <= 0)
  130. {
  131. n->release();
  132. return 0; // Fehler
  133. }
  134. len -= l;
  135. ll += l;
  136. }
  137. upStreamBytes += ll;
  138. n->release();
  139. return 1;
  140. }
  141. bool Klient::getNachrichtEncrypted(char* nachricht, int len) // empfängt Nachricht
  142. {
  143. if (!empfangKey)
  144. return getNachricht(nachricht, len);
  145. int ll = 0;
  146. while (len > 0)
  147. {
  148. int l = (int)recv(sock, nachricht + ll, len, MSG_WAITALL);
  149. if (l <= 0)
  150. return 0; // Fehler
  151. len -= l;
  152. ll += l;
  153. }
  154. Encryption::Bytes* n = new Encryption::Bytes();
  155. n->setBytesZ(nachricht, ll);
  156. empfangKey->decodieren(n);
  157. downStreamBytes += ll;
  158. return 1;
  159. }
  160. int Klient::getDownloadBytes(bool reset) // gibt die anzahl von empfangen bytes zurück
  161. {
  162. int ret = downStreamBytes;
  163. if (reset)
  164. downStreamBytes = 0;
  165. return ret;
  166. }
  167. int Klient::getUploadBytes(bool reset) // gibt die anzahl von versendeter bytes zurück
  168. {
  169. int ret = upStreamBytes;
  170. if (reset)
  171. upStreamBytes = 0;
  172. return ret;
  173. }
  174. bool Klient::trenne() // Trennt die Verbindung zum Server
  175. {
  176. if (!sock)
  177. return 1;
  178. if (sendeKey)
  179. sendeKey->setPos(0);
  180. if (empfangKey)
  181. empfangKey->setPos(0);
  182. if (closesocket(sock) < 0) // verbindung Trennen
  183. return 0; // Fehler
  184. sock = 0;
  185. return 1;
  186. }
  187. // constant
  188. bool Klient::hatNachricht(int zeit) // Wartet eine Zeit Lang auf eine Nachricht
  189. {
  190. fd_set set;
  191. FD_ZERO(&set);
  192. FD_SET(sock, &set);
  193. timeval time = { zeit / 1000, zeit };
  194. return select(0, &set, 0, 0, &time) == 1;
  195. }
  196. unsigned short Klient::getServerPort() const // gibt den Port zurück
  197. {
  198. return htons(server.sin_port);
  199. }
  200. const char* Klient::getServerIp() const // gibt die Ip zurück
  201. {
  202. return inet_ntoa(server.sin_addr);
  203. }
  204. bool Klient::waitForNextMessage() const // wartet bis es etwas zu empfangen gibt
  205. {
  206. fd_set set;
  207. int rv = 0;
  208. struct timeval timeout;
  209. while (rv == 0 && sock)
  210. {
  211. FD_ZERO(&set); /* clear the set */
  212. FD_SET(sock, &set); /* add our file descriptor to the set */
  213. timeout.tv_sec = 10;
  214. timeout.tv_usec = 0;
  215. rv = select((int)sock + 1, &set, NULL, NULL, &timeout);
  216. if (rv == -1) return 0;
  217. }
  218. if (!sock) return 0;
  219. char c;
  220. int l = (int)recv(sock, &c, 1, MSG_WAITALL | MSG_PEEK);
  221. if (l <= 0)
  222. return 0; // Fehler
  223. return 1;
  224. }
  225. // Inhalt der SSLKlient Klasse aus Klient.h
  226. // Konstruktor
  227. SSLKlient::SSLKlient()
  228. : ReferenceCounter()
  229. {
  230. ctx = SSL_CTX_new(TLS_client_method());
  231. SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
  232. SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
  233. ip = 0;
  234. port = 0;
  235. bio = BIO_new_ssl_connect(ctx);
  236. BIO_get_ssl(bio, &ssl);
  237. downStreamBytes = 0;
  238. upStreamBytes = 0;
  239. connected = 0;
  240. }
  241. // Destruktor
  242. SSLKlient::~SSLKlient()
  243. {
  244. if (this->ip)
  245. this->ip->release();
  246. if (connected)
  247. trenne();
  248. BIO_free_all(bio);
  249. SSL_CTX_free(ctx);
  250. #ifdef WIN32
  251. OPENSSL_thread_stop();
  252. #endif
  253. }
  254. bool SSLKlient::verbinde(unsigned short port, const char* ip) // verbindet mit Server
  255. {
  256. this->port = port;
  257. if (this->ip)
  258. this->ip->release();
  259. this->ip = new Text(ip);
  260. Text adr = ip;
  261. adr += ":";
  262. adr += port;
  263. BIO_set_conn_hostname(bio, (const char*)adr);
  264. connected = BIO_do_connect(bio) > 0;
  265. if (connected && BIO_do_handshake(bio) <= 0)
  266. trenne();
  267. return connected;
  268. }
  269. bool SSLKlient::sende(const char* nachricht, int len) // sendet zum Server
  270. {
  271. int ll = 0;
  272. while (len > 0)
  273. {
  274. int l = SSL_write(ssl, nachricht + ll, len);
  275. if (l <= 0)
  276. return 0; // Fehler
  277. len -= l;
  278. ll += l;
  279. }
  280. upStreamBytes += ll;
  281. return 1;
  282. }
  283. bool SSLKlient::getNachricht(char* nachricht, int len) // empfängt Nachricht
  284. {
  285. if (!connected)
  286. return 0;
  287. int ll = 0;
  288. while (len > 0)
  289. {
  290. int l = SSL_read(ssl, nachricht + ll, len);
  291. if (l <= 0)
  292. return 0; // Fehler
  293. len -= l;
  294. ll += l;
  295. }
  296. downStreamBytes += ll;
  297. return 1;
  298. }
  299. int SSLKlient::getDownloadBytes(bool reset) // gibt die anzahl von empfangen bytes zurück
  300. {
  301. int ret = downStreamBytes;
  302. if (reset)
  303. downStreamBytes = 0;
  304. return ret;
  305. }
  306. int SSLKlient::getUploadBytes(bool reset) // gibt die anzahl von versendeter bytes zurück
  307. {
  308. int ret = upStreamBytes;
  309. if (reset)
  310. upStreamBytes = 0;
  311. return ret;
  312. }
  313. bool SSLKlient::trenne() // Trennt die Verbindung zum Server
  314. {
  315. BIO_ssl_shutdown(bio);
  316. connected = 0;
  317. return 1;
  318. }
  319. // constant
  320. bool SSLKlient::hatNachricht(int zeit) // Wartet eine Zeit Lang auf eine Nachricht
  321. {
  322. fd_set set;
  323. FD_ZERO(&set);
  324. FD_SET(SSL_get_rfd(ssl), &set);
  325. timeval time = { zeit / 1000, zeit };
  326. return SSL_pending(ssl) > 0 || select(0, &set, 0, 0, &time) == 1;
  327. }
  328. unsigned short SSLKlient::getServerPort() const // gibt den Port des Servers zurück
  329. {
  330. return port;
  331. }
  332. const char* SSLKlient::getServerIp() const // gibt die Ip des Servers zurück
  333. {
  334. return ip->getText();
  335. }