blob: 2bee2ecdce3da5c0f9513bfef0b1364b395e17bd [file] [log] [blame] [view]
Mark Slee54b7ab92007-03-06 00:06:27 +00001Thrift C++ Software Library
2
Roger Meier6370cfd2014-05-04 22:21:58 +02003# License
Bryan Duxburydef30a62009-04-08 00:19:37 +00004
5Licensed to the Apache Software Foundation (ASF) under one
6or more contributor license agreements. See the NOTICE file
7distributed with this work for additional information
8regarding copyright ownership. The ASF licenses this file
9to you under the Apache License, Version 2.0 (the
10"License"); you may not use this file except in compliance
11with the License. You may obtain a copy of the License at
12
13 http://www.apache.org/licenses/LICENSE-2.0
14
15Unless required by applicable law or agreed to in writing,
16software distributed under the License is distributed on an
17"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18KIND, either express or implied. See the License for the
19specific language governing permissions and limitations
20under the License.
Mark Slee54b7ab92007-03-06 00:06:27 +000021
Roger Meier6370cfd2014-05-04 22:21:58 +020022
23# Using Thrift with C++
Mark Slee54b7ab92007-03-06 00:06:27 +000024
25The Thrift C++ libraries are built using the GNU tools. Follow the instructions
Roger Meier6370cfd2014-05-04 22:21:58 +020026in the top-level README.md
Mark Slee54b7ab92007-03-06 00:06:27 +000027
Roger Meier6370cfd2014-05-04 22:21:58 +020028In case you do not want to open another README.md file, do this thrift src:
29
30 ./bootstrap.sh
31 ./configure (--with-boost=/usr/local)
32 make
33 sudo make install
Mark Slee54b7ab92007-03-06 00:06:27 +000034
35Thrift is divided into two libraries.
36
Roger Meier6370cfd2014-05-04 22:21:58 +020037* libthrift - The core Thrift library contains all the core Thrift code. It requires
Mark Slee54b7ab92007-03-06 00:06:27 +000038 boost shared pointers, pthreads, and librt.
39
Roger Meier6370cfd2014-05-04 22:21:58 +020040* libthriftnb - This library contains the Thrift nonblocking server, which uses libevent.
Mark Slee54b7ab92007-03-06 00:06:27 +000041 To link this library you will also need to link libevent.
42
Roger Meier6370cfd2014-05-04 22:21:58 +020043## Linking Against Thrift
Mark Slee54b7ab92007-03-06 00:06:27 +000044
45After you build and install Thrift the libraries are installed to
46/usr/local/lib by default. Make sure this is in your LDPATH.
47
48On Linux, the best way to do this is to ensure that /usr/local/lib is in
49your /etc/ld.so.conf and then run /sbin/ldconfig.
50
51Depending upon whether you are linking dynamically or statically and how
52your build environment it set up, you may need to include additional
53libraries when linking against thrift, such as librt and/or libpthread. If
54you are using libthriftnb you will also need libevent.
55
Roger Meier6370cfd2014-05-04 22:21:58 +020056## Dependencies
Mark Slee54b7ab92007-03-06 00:06:27 +000057
58boost shared pointers
59http://www.boost.org/libs/smart_ptr/smart_ptr.htm
60
61libevent (for libthriftnb only)
62http://monkey.org/~provos/libevent/
Roger Meier6370cfd2014-05-04 22:21:58 +020063
64# Using Thrift with C++ on Windows
65
Roger Meierfaf52db2014-06-09 22:41:06 +020066You need to define an environment variables for 3rd party components separately:
Roger Meier6370cfd2014-05-04 22:21:58 +020067
Roger Meierfaf52db2014-06-09 22:41:06 +020068BOOST_ROOT : For boost, e.g. D:\boost_1_55_0
69OPENSSL_ROOT_DIR : For OpenSSL, e.g. D:\OpenSSL-Win32
70
71only required by libthriftnb:
72
73LIBEVENT_ROOT_DIR : For Libevent e.g. D:\libevent-2.0.21-stable
74
75See /3rdparty.user for more details.
Roger Meier6370cfd2014-05-04 22:21:58 +020076
77Thrift is divided into two libraries.
78
79* libthrift - The core Thrift library contains all the core Thrift code. It requires
80 boost shared pointers, pthreads, and librt.
81
82* libthriftnb - This library contains the Thrift nonblocking server, which uses libevent.
83 To link this library you will also need to link libevent.
84
85## Linking Against Thrift
86
87You need to link your project that uses thrift against all the thrift
Roger Meierfaf52db2014-06-09 22:41:06 +020088dependencies; in the case of libthrift, boost and for
Roger Meier6370cfd2014-05-04 22:21:58 +020089libthriftnb, libevent.
90
91In the project properties you must also set HAVE_CONFIG_H as force include
92the config header: "windows/confg.h"
93
94## Dependencies
95
96boost shared pointers
97http://www.boost.org/libs/smart_ptr/smart_ptr.htm
98
99boost thread
100http://www.boost.org/doc/libs/release/doc/html/thread.html
101
102libevent (for libthriftnb only)
103http://monkey.org/~provos/libevent/
104
105## Notes on boost thread (static vs shared):
106
107By default lib/cpp/windows/force_inc.h defines:
108
109 #define BOOST_ALL_NO_LIB 1
110 #define BOOST_THREAD_NO_LIB 1
111
112This has for effect to have the host application linking against Thrift
113to have to link with boost thread as a static library.
114
115If you wanted instead to link with boost thread as a shared library,
116you'll need to uncomment those two lines, and recompile.
117
118## Windows version compatibility
119
120The Thrift library targets Windows XP for broadest compatbility. A notable
121difference is in the Windows-specific implementation of the socket poll
122function. To target Vista, Win7 or other versions, comment out the line
123
124 #define TARGET_WIN_XP.
125
126## Named Pipes
127
128Named Pipe transport has been added in the TPipe and TPipeServer classes. This
129is currently Windows-only. Named pipe transport for *NIX has not been
130implemented. Domain sockets are a better choice for local IPC under non-Windows
131OS's. *NIX named pipes only support 1:1 client-server connection.
132
133# Thrift/SSL
134
Roger Meier4fba9d22014-05-04 22:34:44 +0200135## Scope
Roger Meier6370cfd2014-05-04 22:21:58 +0200136
Roger Meier4fba9d22014-05-04 22:34:44 +0200137This SSL only supports blocking mode socket I/O. It can only be used with
138TSimpleServer, TThreadedServer, and TThreadPoolServer.
Roger Meier6370cfd2014-05-04 22:21:58 +0200139
Roger Meier4fba9d22014-05-04 22:34:44 +0200140## Implementation
Roger Meier6370cfd2014-05-04 22:21:58 +0200141
Roger Meier4fba9d22014-05-04 22:34:44 +0200142There're two main classes TSSLSocketFactory and TSSLSocket. Instances of
143TSSLSocket are always created from TSSLSocketFactory.
Roger Meier6370cfd2014-05-04 22:21:58 +0200144
Roger Meier4fba9d22014-05-04 22:34:44 +0200145PosixSSLThreadFactory creates PosixSSLThread. The only difference from the
146PthreadThread type is that it cleanups OpenSSL error queue upon exiting
147the thread. Ideally, OpenSSL APIs should only be called from PosixSSLThread.
Roger Meier6370cfd2014-05-04 22:21:58 +0200148
Roger Meier4fba9d22014-05-04 22:34:44 +0200149## How to use SSL APIs
Roger Meier6370cfd2014-05-04 22:21:58 +0200150
Roger Meier4fba9d22014-05-04 22:34:44 +0200151This is for demo. In real code, typically only one TSSLSocketFactory
152instance is needed.
Roger Meier6370cfd2014-05-04 22:21:58 +0200153
Roger Meier4fba9d22014-05-04 22:34:44 +0200154 shared_ptr<TSSLSocketFactory> getSSLSocketFactory() {
155 shared_ptr<TSSLSocketFactory> factory(new TSSLSocketFactory());
156 // client: load trusted certificates
157 factory->loadTrustedCertificates("my-trusted-ca-certificates.pem");
158 // client: optionally set your own access manager, otherwise,
159 // the default client access manager will be loaded.
160
161 factory->loadCertificate("my-certificate-signed-by-ca.pem");
162 factory->loadPrivateKey("my-private-key.pem");
163 // server: optionally setup access manager
164 // shared_ptr<AccessManager> accessManager(new MyAccessManager);
165 // factory->access(accessManager);
166 ...
167 }
Roger Meier6370cfd2014-05-04 22:21:58 +0200168
169
Roger Meier4fba9d22014-05-04 22:34:44 +0200170client code sample
171
172 shared_ptr<TSSLSocketFactory> factory = getSSLSocketFactory();
173 shared_ptr<TSocket> socket = factory.createSocket(host, port);
174 shared_ptr<TBufferedTransport> transport(new TBufferedTransport(socket));
175 ...
Roger Meier6370cfd2014-05-04 22:21:58 +0200176
177
Roger Meier4fba9d22014-05-04 22:34:44 +0200178server code sample
Roger Meier6370cfd2014-05-04 22:21:58 +0200179
Roger Meier4fba9d22014-05-04 22:34:44 +0200180 shared_ptr<TSSLSocketFactory> factory = getSSLSocketFactory();
181 shared_ptr<TSSLServerSocket> socket(new TSSLServerSocket(port, factory));
182 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory));
183 ...
Roger Meier6370cfd2014-05-04 22:21:58 +0200184
Roger Meier4fba9d22014-05-04 22:34:44 +0200185## AccessManager
Roger Meier6370cfd2014-05-04 22:21:58 +0200186
Roger Meier4fba9d22014-05-04 22:34:44 +0200187AccessManager defines a callback interface. It has three callback methods:
Roger Meier6370cfd2014-05-04 22:21:58 +0200188
Roger Meier4fba9d22014-05-04 22:34:44 +0200189(a) Decision verify(const sockaddr_storage& sa);
Roger Meier6370cfd2014-05-04 22:21:58 +0200190
Roger Meier4fba9d22014-05-04 22:34:44 +0200191(b) Decision verify(const string& host, const char* name, int size);
Roger Meier6370cfd2014-05-04 22:21:58 +0200192
Roger Meier4fba9d22014-05-04 22:34:44 +0200193(c) Decision verify(const sockaddr_storage& sa, const char* data, int size);
Roger Meier6370cfd2014-05-04 22:21:58 +0200194
Roger Meier4fba9d22014-05-04 22:34:44 +0200195After SSL handshake completes, additional checks are conducted. Application
196is given the chance to decide whether or not to continue the conversation
197with the remote. Application is queried through the above three "verify"
198method. They are called at different points of the verification process.
Roger Meier6370cfd2014-05-04 22:21:58 +0200199
Roger Meier4fba9d22014-05-04 22:34:44 +0200200Decisions can be one of ALLOW, DENY, and SKIP. ALLOW and DENY means the
201conversation should be continued or disconnected, respectively. ALLOW and
202DENY decision stops the verification process. SKIP means there's no decision
203based on the given input, continue the verification process.
Roger Meier6370cfd2014-05-04 22:21:58 +0200204
Roger Meier4fba9d22014-05-04 22:34:44 +0200205First, (a) is called with the remote IP. It is called once at the beginning.
206"sa" is the IP address of the remote peer.
Roger Meier6370cfd2014-05-04 22:21:58 +0200207
Roger Meier4fba9d22014-05-04 22:34:44 +0200208Then, the certificate of remote peer is loaded. SubjectAltName extensions
209are extracted and sent to application for verification. When a DNS
210subjectAltName field is extracted, (b) is called. When an IP subjectAltName
211field is extracted, (c) is called.
Roger Meier6370cfd2014-05-04 22:21:58 +0200212
Roger Meier4fba9d22014-05-04 22:34:44 +0200213The "host" in (b) is the value from TSocket::getHost() if this is a client
214side socket, or TSocket::getPeerHost() if this is a server side socket. The
215reason is client side socket initiates the connection. TSocket::getHost()
216is the remote host name. On server side, the remote host name is unknown
217unless it's retrieved through TSocket::getPeerHost(). Either way, "host"
218should be the remote host name. Keep in mind, if TSocket::getPeerHost()
219failed, it would return the remote host name in numeric format.
Roger Meier6370cfd2014-05-04 22:21:58 +0200220
Roger Meier4fba9d22014-05-04 22:34:44 +0200221If all subjectAltName extensions were "skipped", the common name field would
222be checked. It is sent to application through (c), where "sa" is the remote
223IP address. "data" is the IP address extracted from subjectAltName IP
224extension, and "size" is the length of the extension data.
Roger Meier6370cfd2014-05-04 22:21:58 +0200225
Roger Meier4fba9d22014-05-04 22:34:44 +0200226If any of the above "verify" methods returned a decision ALLOW or DENY, the
227verification process would be stopped.
Roger Meier6370cfd2014-05-04 22:21:58 +0200228
Roger Meier4fba9d22014-05-04 22:34:44 +0200229If any of the above "verify" methods returned SKIP, that decision would be
230ignored and the verification process would move on till the last item is
231examined. At that point, if there's still no decision, the connection is
232terminated.
Roger Meier6370cfd2014-05-04 22:21:58 +0200233
Roger Meier4fba9d22014-05-04 22:34:44 +0200234Thread safety, an access manager should not store state information if it's
235to be used by many SSL sockets.
Roger Meier6370cfd2014-05-04 22:21:58 +0200236
Roger Meier4fba9d22014-05-04 22:34:44 +0200237## SIGPIPE signal
Roger Meier6370cfd2014-05-04 22:21:58 +0200238
Roger Meier4fba9d22014-05-04 22:34:44 +0200239Applications running OpenSSL over network connections may crash if SIGPIPE
240is not ignored. This happens when they receive a connection reset by remote
241peer exception, which somehow triggers a SIGPIPE signal. If not handled,
242this signal would kill the application.
Roger Meier6370cfd2014-05-04 22:21:58 +0200243
Roger Meier4fba9d22014-05-04 22:34:44 +0200244## How to run test client/server in SSL mode
Roger Meier6370cfd2014-05-04 22:21:58 +0200245
Roger Meier4fba9d22014-05-04 22:34:44 +0200246The server and client expects the followings from the directory /test/
Roger Meier6370cfd2014-05-04 22:21:58 +0200247
Roger Meier4fba9d22014-05-04 22:34:44 +0200248- keys/server.crt
249- keys/server.key
250- keys/CA.pem
Roger Meier6370cfd2014-05-04 22:21:58 +0200251
Roger Meier4fba9d22014-05-04 22:34:44 +0200252The file names are hard coded in the source code. You need to create these
253certificates before you can run the test code in SSL mode. Make sure at least
254one of the followings is included in "keys/server.crt",
Roger Meier6370cfd2014-05-04 22:21:58 +0200255
Roger Meier4fba9d22014-05-04 22:34:44 +0200256- subjectAltName, DNS localhost
257- subjectAltName, IP 127.0.0.1
258- common name, localhost
Roger Meier6370cfd2014-05-04 22:21:58 +0200259
Roger Meier4fba9d22014-05-04 22:34:44 +0200260Run within /test/ folder,
Roger Meier6370cfd2014-05-04 22:21:58 +0200261
Roger Meier4fba9d22014-05-04 22:34:44 +0200262 ./cpp/TestServer --ssl &
263 ./cpp/TestClient --ssl
Roger Meier6370cfd2014-05-04 22:21:58 +0200264
Roger Meier4fba9d22014-05-04 22:34:44 +0200265If "-h <host>" is used to run client, the above "localhost" in the above
266keys/server.crt has to be replaced with that host name.
267
268## TSSLSocketFactory::randomize()
269
270The default implementation of OpenSSLSocketFactory::randomize() simply calls
271OpenSSL's RAND_poll() when OpenSSL library is first initialized.
272
273The PRNG seed is key to the application security. This method should be
274overridden if it's not strong enough for you.