Klient.cpp 8.6 KB

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