c++ boost 苹果内购 IAP验证

时间:2022-09-08 23:26:48
c++ boost 苹果内购 IAP验证c++ boost 苹果内购 IAP验证
  1 // 1111.cpp: 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <cstdlib>
  6 #include <iostream>
  7 #include <boost/bind.hpp>
  8 #include <boost/asio.hpp>
  9 #include <boost/asio/ssl.hpp>
 10 
 11 enum { max_length = 1024 };
 12 
 13 class client
 14 {
 15 public:
 16     client(boost::asio::io_service& io_service,
 17         boost::asio::ssl::context& context,
 18         boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
 19         : socket_(io_service, context)
 20     {
 21         //socket_.set_verify_mode(boost::asio::ssl::verify_peer);
 22         socket_.set_verify_mode(boost::asio::ssl::context::verify_none);
 23         socket_.set_verify_callback(
 24             boost::bind(&client::verify_certificate, this, _1, _2));
 25 
 26         boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
 27             boost::bind(&client::handle_connect, this,
 28                 boost::asio::placeholders::error));
 29     }
 30 
 31     bool verify_certificate(bool preverified,
 32         boost::asio::ssl::verify_context& ctx)
 33     {
 34         // The verify callback can be used to check whether the certificate that is
 35         // being presented is valid for the peer. For example, RFC 2818 describes
 36         // the steps involved in doing this for HTTPS. Consult the OpenSSL
 37         // documentation for more details. Note that the callback is called once
 38         // for each certificate in the certificate chain, starting from the root
 39         // certificate authority.
 40 
 41         // In this example we will simply print the certificate's subject name.
 42         char subject_name[256];
 43         X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
 44         X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
 45         std::cout << "Verifying " << subject_name << "\n";
 46 
 47         return preverified;
 48     }
 49 
 50     void handle_connect(const boost::system::error_code& error)
 51     {
 52         if (!error)
 53         {
 54             socket_.async_handshake(boost::asio::ssl::stream_base::client,
 55                 boost::bind(&client::handle_handshake, this,
 56                     boost::asio::placeholders::error));
 57         }
 58         else
 59         {
 60             std::cout << "Connect failed: " << error.message() << "\n";
 61         }
 62     }
 63 
 64     void handle_handshake(const boost::system::error_code& error)
 65     {
 66         if (!error)
 67         {
 68             std::cout << "Enter message: ";
 69         //    std::cin.getline(request_, max_length);
 70             size_t request_length = strlen(request_);
 71 
 72             std::stringstream ss;
 73             ss << "POST " << " https://sandbox.itunes.apple.com/verifyReceipt HTTP/1.1\r\n";
 74             ss << "User-Agent: Fiddler\r\n";
 75             ss << "Host: sandbox.itunes.apple.com\r\n";
 76             ss << "Accept: */*\r\n";
 77             ss << "Connection: close\r\n\r\n";
 78             
 79             std::string str = ss.str();
 80 
 81             boost::asio::async_write(socket_,
 82                 boost::asio::buffer(str, str.length()),
 83                 boost::bind(&client::handle_write, this,
 84                     boost::asio::placeholders::error,
 85                     boost::asio::placeholders::bytes_transferred));
 86         }
 87         else
 88         {
 89             std::cout << "Handshake failed: " << error.message() << "\n";
 90         }
 91     }
 92 
 93     void handle_write(const boost::system::error_code& error,
 94         size_t bytes_transferred)
 95     {
 96         if (!error)
 97         {
 98             /*boost::asio::async_read(socket_,
 99                 boost::asio::buffer(reply_, bytes_transferred),
100                 boost::bind(&client::handle_read, this,
101                     boost::asio::placeholders::error,
102                     boost::asio::placeholders::bytes_transferred));*/
103             boost::asio::streambuf response;
104             boost::asio::read_until(socket_, response, "\r\n");
105             std::istream response_stream(&response);
106             std::string http_version;
107             response_stream >> http_version;
108             unsigned int status_code;
109             response_stream >> status_code;
110             std::string status_message;
111             std::getline(response_stream, status_message);
112             if (!response_stream || http_version.substr(0, 5) != "HTTP/")
113             {
114                 std::cout << "Invalid response\n";
115                 return ;
116             }
117             if (status_code != 200)
118             {
119                 std::cout << "Response returned with status code " << status_code << "\n";
120                 return ;
121             }
122 
123             // Read the response headers, which are terminated by a blank line.
124             boost::asio::read_until(socket_, response, "\r\n\r\n");
125 
126             // Process the response headers.
127             std::string header;
128             while (std::getline(response_stream, header) && header != "\r")
129                 std::cout << header << "\n";
130             std::cout << "\n";
131 
132             // Write whatever content we already have to output.
133             if (response.size() > 0)
134                 std::cout << &response;
135 
136 
137             try{    // Read until EOF, writing data to output as we go.
138                 boost::system::error_code error;
139                 char buf[500] = { 0 };
140                 while ( socket_.read_some(boost::asio::buffer(buf, 500), error)>0 )
141                 {
142                     boost::system::error_code tmp = error;
143                     std::cout << buf;
144                 }
145                 
146                 if (error != boost::asio::error::eof)
147                     throw boost::system::system_error(error);
148                 /**
149                 * 21000 App Store不能读取你提供的JSON对象
150                 * 21002 receipt-data域的数据有问题
151                 * 21003 receipt无法通过验证
152                 * 21004 提供的shared secret不匹配你账号中的shared secret
153                 * 21005 receipt服务器当前不可用
154                 * 21006 receipt合法,但是订阅已过期。服务器接收到这个状态码时,receipt数据仍然会解码并一起发送
155                 * 21007 receipt是Sandbox receipt,但却发送至生产系统的验证服务
156                 * 21008 receipt是生产receipt,但却发送至Sandbox环境的验证服务
157                 */
158                 std::cout << "\r\n\nfinished !!\r\n";
159             }
160             catch (std::exception& e)
161             {
162                 std::cout << "Exception: " << e.what() << "\n";
163                 return;
164             }
165 
166 
167         }
168         else
169         {
170             std::cout << "Write failed: " << error.message() << "\n";
171         }
172     }
173 
174     void handle_read(const boost::system::error_code& error,
175         size_t bytes_transferred)
176     {
177         if (!error)
178         {
179             std::cout << "Reply: ";
180             std::cout.write(reply_, bytes_transferred);
181             std::cout << "\n";
182         }
183         else
184         {
185             std::cout << "Read failed: " << error.message() << "\n";
186         }
187     }
188 
189 private:
190     boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
191     char request_[max_length];
192     char reply_[max_length];
193 };
194 
195 int main(int argc, char* argv[])
196 {
197     try
198     {
199 
200         boost::asio::io_service io_service;
201 
202         boost::asio::ip::tcp::resolver resolver(io_service);
203         boost::asio::ip::tcp::resolver::query query("buy.itunes.apple.com", "443");
204         boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
205 
206         boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
207         ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
208         //ctx.load_verify_file("ca.pem");
209 
210         client c(io_service, ctx, iterator);
211 
212         io_service.run();
213     }
214     catch (std::exception& e)
215     {
216         std::cerr << "Exception: " << e.what() << "\n";
217     }
218 
219     return 0;
220 }
View Code