Ssl समर्थन के साथ सबसे सरल क्रॉस-प्लेटफ़ॉर्म सर्वर

बहुत पहले नहीं, मुझे एक कार्य का सामना करना पड़ा: ssl प्रोटोकॉल का उपयोग करके प्रसंस्करण अनुरोधों के लिए एक क्रॉस-प्लेटफ़ॉर्म सर्वर लिखना। इससे पहले, मैंने नियमित रूप से प्रोटोकॉल के लिए सर्वर लिखा था, एन्क्रिप्टेड प्रोटोकॉल नहीं, लेकिन मुझे पहली बार एसएसएल का सामना करना पड़ा।
इंटरनेट की त्वरित समीक्षा से पता चला कि सबसे अच्छा समाधान बाइक निर्माण नहीं होगा, बल्कि ओपनएसएसएल पुस्तकालय का उपयोग होगा।
इस लेख में मैं लिनक्स और विंडोज पर ओपनएसएसएल स्थापित करने की प्रक्रिया पर विचार नहीं करना चाहता, मैं केवल यह ध्यान देता हूं कि विंडोज के लिए यह प्रक्रिया तुच्छ नहीं थी। और मैं इस बारे में बात करना चाहता हूं कि मैं विज़ुअल स्टूडियो में एक साधारण सर्वर का उदाहरण कैसे संकलित करने में कामयाब रहा, जो ओपनएसएसएल स्रोत कोड का हिस्सा है।
यह एक अनुभवहीन पाठक को लग सकता है: "ऐसा क्या खास है - मैंने एक परियोजना बनाई, इसमें एक तैयार स्रोत शामिल किया, इसे शुरू किया ..." हालांकि, पहले चीजें पहले।

मेरे लिए प्रोग्रामर के रूप में, चरणों में कदम बताना आसान है:

1. प्रयोगों के लिए एक निर्देशिका बनाएँ:
इसे उदाहरण C: \ testsl के लिए होने दें

2. ओपनएसएसएल स्रोत कोड डाउनलोड करें
इस कोड को निर्देशिका C: \ opensl-1.0.1c में उदाहरण के लिए संग्रहीत किया जाए
3. ओपनएसएसएल का संकलन
संकलन के बाद, आपके पास लाइब्रेरी और हेडर फ़ाइलों के साथ एक निर्देशिका होगी। इस निर्देशिका को हमारी परीक्षण निर्देशिका में कॉपी करें। परिणाम फ़ाइलों और निर्देशिकाओं की निम्न संरचना होनी चाहिए:
C: \ testsl
C: \ testsl \ खुलता है
C: \ testsl \ opensl \ bin
C: \ testsl \ opensl \ bin \ opensl.exe
C: \ testsl \ opensl \ शामिल हैं
C: \ testsl \ opensl \ शामिल \ खुलता है
C: \ testsl \ opensl \ शामिल \ \ssl \ anes.h
..... (बहुत सी हेडर फाइलें हैं)
C: \ testsl \ opensl \ शामिल \ \ssl \ x509v3.h
C: \ testsl \ खुलने का समय \ lib
C: \ testsl \ खुलता है \ lib \ libeay32.lib
C: \ testsl \ खुलने वाला \ lib \ ssleay32.lib
C: \ testsl \ opensl \ ssl
C: \ testsl \ खुलता है \ ssl \ खुलता है

4. C से वांछित उदाहरण की प्रतिलिपि बनाएँ : \ खुलने का समय- 1.0.1c \ demos \ ssl \ serv.cpp से C: \ testsl \ serv.cpp

5. काम करने के लिए उदाहरण के लिए, आपको एक गुप्त कुंजी के साथ एक फ़ाइल की आवश्यकता है। इस फाइल को सोर्स से भी लिया जा सकता है।
इसे C से कॉपी करें : \ opensl-1.0.1c \ certs \ Demo \ ca-cert.pem से C: \ testsl \ ca-cert.pem

5. Visual Studio में एक खाली कंसोल प्रोजेक्ट बनाएँ और उसमें serv.cpp फ़ाइल जोड़ें।
6. परियोजना के गुणों में, शीर्ष लेख के लिए पथ जोड़ें: C: \ testsl \ खुलने का स्थान \ _ और पुस्तकालयों के लिए पथ: C: \ testsl \ खुलता है \ lib । और यह भी libeay32.lib, ssleay32.lib पुस्तकालय खुद

7. अब हम कोड में सही करते हैं

#define CERTF HOME "foo-cert.pem" #define KEYF HOME "foo-cert.pem" 


पर
 #define CERTF HOME "ca-cert.pem" #define KEYF HOME "ca-cert.pem 


8. यह सब प्रतीत होगा, लेकिन निश्चित रूप से कोड संकलित नहीं होगा। तथ्य यह है कि विंडोज और लिनक्स पर आपको विभिन्न मानक हेडर फ़ाइलों को शामिल करने की आवश्यकता है।

ठीक करने की जरूरत है
 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <memory.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <openssl/rsa.h> /* SSLeay stuff */ #include <openssl/crypto.h> #include <openssl/x509.h> #include <openssl/pem.h> #include <openssl/ssl.h> #include <openssl/err.h> 


पर
 #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <errno.h> #include <sys/types.h> #ifndef WIN32 #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #else #include <io.h> #include <Winsock2.h> #pragma comment(lib, "ws2_32.lib") #endif #include <openssl/rsa.h> /* SSLeay stuff */ #include <openssl/crypto.h> #include <openssl/x509.h> #include <openssl/pem.h> #include <openssl/ssl.h> #include <openssl/err.h> 


जैसा कि आप देख सकते हैं, विंडोज के लिए आपको "Winsock2.h" फ़ाइल शामिल करने की आवश्यकता है, साथ ही साथ मामले में एक सॉकेट लाइब्रेरी भी।

9. लेकिन यह सब नहीं है! यदि अब परियोजना को संकलित करने का प्रयास किया जाता है, तो त्रुटियाँ उत्पन्न होंगी:
C2440 त्रुटि: '=': 'const SSL_METHOD *' से 'SSL_METHOD *' में परिवर्तित नहीं हो सकता
C2664 त्रुटि: 'स्वीकार': पैरामीटर 3 को 'size_t *' से 'int *' में नहीं बदल सकता

इन त्रुटियों को ढूंढना और ठीक करना आसान है, लेकिन यदि आप क्रॉस-प्लेटफ़ॉर्म चाहते हैं, तो आपको इसे सावधानीपूर्वक ठीक करने की आवश्यकता है:

पहली गलती के लिए आपको चाहिए
  meth = SSLv23_server_method(); 


ठीक करना

 #ifdef WIN32 const SSL_METHOD *meth = SSLv23_server_method(); #else SSL_METHOD *meth = SSLv23_server_method(); #endif 


दूसरी त्रुटि के लिए, आपको आवश्यकता है
  sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len); 


ठीक करना

 #ifdef WIN32 sd = accept (listen_sd, (struct sockaddr*) &sa_cli, (int *)&client_len); #else sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len); #endif 


10. अब कोड संकलित और चला जाएगा, लेकिन यह लाइन में एक त्रुटि फेंक देगा
"सुनो_एसडी = सॉकेट (AF_INET, SOCK_STREAM, 0); CHK_ERR (Listen_sd,) सॉकेट ");"
हां। विंडोज़ पर, सॉकेट्स के साथ काम करने के लिए, आपको पहले WSAStartup () फ़ंक्शन को कॉल करना होगा!
इसे कार्यक्रम की शुरुआत में जोड़ें:
 void main () { int err; int listen_sd; int sd; struct sockaddr_in sa_serv; struct sockaddr_in sa_cli; size_t client_len; SSL_CTX* ctx; SSL* ssl; X509* client_cert; char* str; char buf [4096]; #ifdef WIN32 WSADATA wsaData; if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 ) { printf("Could not to find usable WinSock in WSAStartup\n"); return; } #endif 


11. प्रोग्राम को चलाएं, विंडोज अनुमति मांगता है ताकि एप्लिकेशन पोर्ट को खोल सके। हम अनुमति देते हैं।
आवेदन लाइन तक पहुंचता है
 sd = accept (listen_sd, (struct sockaddr*) &sa_cli, (int *)&client_len); 

और जमा देता है।
यह सही है, हमारा सर्वर किसी से कनेक्ट होने का इंतजार कर रहा है।
इस बिंदु पर, आप कमांड लाइन से कनेक्ट कर सकते हैं: "टेलनेट लोकलहोस्ट 1111"। जैसे ही कनेक्शन होता है, प्रोग्राम लाइन पर चलता रहेगा
 close (listen_sd); 

विजुअल स्टूडियो इस लाइन पर एक अयोग्य त्रुटि प्रदर्शित करेगा।
लेकिन अगर आप देखते हैं, तो यह पता चलता है कि विंडोज पर सॉकेट किसी अन्य फ़ंक्शन के साथ बंद हो गए हैं: "क्लोज़बोर्ड ()"।
त्रुटियों से बचने के लिए, हम हर जगह क्लोजबोर्ड के करीब, और क्रॉस-प्लेटफॉर्म ऐड कोड के लिए बदलते हैं:
 #ifndef WIN32 #define closesocket close #endif 


12. अब आवेदन शुरू हुआ और लाइन तक चला गया
 err = SSL_accept (ssl); CHK_SSL(err); 

यहाँ यह फिर से लटका, जाहिरा तौर पर एक ssl संदेश क्लाइंट की उम्मीद है।
टेलनेट के साथ इन संदेशों को मैन्युअल रूप से कैसे एक्सचेंज किया जाए, मुझे व्यक्तिगत रूप से नहीं पता है। लेकिन कार्यक्रम के संचालन को अंत तक जांचने के लिए, आप एक नियमित ब्राउज़र का उपयोग कर सकते हैं!

13. हमारे सर्वर के स्वास्थ्य का परीक्षण करने के लिए, इसे चलाएं, और कमांड लाइन के बजाय, ब्राउज़र लॉन्च करें।
ब्राउज़र के एड्रेस बार में, टाइप करें: localhost:1111
ब्राउज़र असुरक्षित प्रमाणपत्र की चेतावनी देता है। जोखिम लेने की जरूरत है। हालाँकि, जब हम ब्राउज़र के साथ संचार कर रहे हैं, सर्वर फिर से विफल हो सकता है। यह सामान्य है, इसे फिर से चलाएं।

14. अब जब सर्वर चल रहा है, और ब्राउज़र को याद है कि हम इस सर्वर पर भरोसा करते हैं, तो हमारा प्रोग्राम अंततः एक एन्क्रिप्टेड कनेक्शन पर ब्राउज़र से "G" ("GET" अनुरोध की शुरुआत) पत्र "G" प्राप्त करेगा और प्राप्त करेगा!

15. कोई भी इस पर समाप्त हो सकता है, लेकिन मैंने प्रयोग की शुद्धता के लिए लिनक्स पर परिणामी फ़ाइल संकलित करने का फैसला किया। यह पता चला कि कुछ आश्चर्य थे।
संकलन चरण में, मुझे एक त्रुटि मिली:
serv.cpp: 51: error: ':: मुख्य' को 'int' वापस करना होगा

यहाँ यह है। यह स्रोत से एक उदाहरण देता है ओपनएसएसएल न केवल विंडोज पर, बल्कि लिनक्स पर भी संकलन करता है।
बेशक, मैंने "रिटर्न मेन ()" से "इंट मेन ()" और हर जगह "रिटर्न" के बजाय "रिटर्न 0" लिखा, लेकिन तलछट बनी रही।

और अगर अचानक दिलचस्प है, तो यह निम्न पंक्ति के साथ लिनक्स पर संकलित करता है: "g ++ -L / usr / lib -lssl -lcrypto serv.cpp"।

पुनश्च: यह हब पर मेरी पहली पोस्ट है, इसलिए मैं समुदाय से माफी मांगता हूं अगर यह लंबा और भ्रमित हो जाए। विज़ुअल स्टूडियो 2012 की परियोजना संग्रह में उपलब्ध है: e0.3s3s.org

PPP: इस लेख को जारी रखना: habrahabr.ru/post/211661

Source: https://habr.com/ru/post/In211474/


All Articles