1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
/*
* Copyright (C) 2020 Codership Oy <info@codership.com>
*
* This file is part of wsrep-API.
*
* Wsrep-API is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Wsrep-API is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wsrep-API. If not, see <https://www.gnu.org/licenses/>.
*/
/** @file wsrep_tls_service.h
*
* This file defines interface for TLS services provided by the application,
* used by the provider.
*
* In order to support both synchronous and asynchronous IO operations,
* the interface is designed to work with sockets in both blocking
* and non-blockig mode.
*
* The provider is in charge of opening and closing file
* descriptors and connecting transport. After the connection has
* been established, all further IO operations will be delegated
* to the TLS service implementation which is provided by the application.
*
* The provider which is capable of using the service interface v1 must
* export the following functions.
*
* int wsrep_init_tls_service_v1(wsrep_tls_service_v1_t*)
* void wsrep_deinit_tls_service_v1()
*
* which can be probed by the application.
*
* The application must initialize the service via above init function
* before the provider is initialized via wsrep->init(). The deinit
* function must be called after the provider side resources have been
* released via wsrep->free().
*/
#ifndef WSREP_TLS_SERVICE_H
#define WSREP_TLS_SERVICE_H
#include <sys/types.h> /* posix size_t */
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/**
* Type tag for application defined TLS context.
*
* Application may pass pointer to the context when initializing
* TLS service. This pointer is passed a first parameter for
* each service call.
*/
typedef struct wsrep_tls_context wsrep_tls_context_t;
/**
* TLS stream structure.
*/
typedef struct wsrep_tls_stream_st
{
/**
* File descriptor corresponding to the stream. The provider is
* responsible in opening and closing the socket.
*/
int fd;
/**
* Opaque pointer reserved for application use.
*/
void* opaque;
} wsrep_tls_stream_t;
/**
* Enumeration for return codes.
*/
enum wsrep_tls_result
{
/**
* The operation completed successfully, no further actions
* are necessary.
*/
wsrep_tls_result_success = 0,
/**
* The operation completed successfully, but the application side wants
* to make further reads. The provider must wait until the stream
* becomes readable and then try the same operation again.
*/
wsrep_tls_result_want_read,
/**
* The operation completed successfully, but the application side wants
* to make further writes. The provider must wait until the stream
* becomes writable and then try the same operation again.
*/
wsrep_tls_result_want_write,
/**
* End of file was read from the stream. This result is needed to
* make difference between graceful stream shutdown and zero length
* reads which result from errors.
*/
wsrep_tls_result_eof,
/**
* An error occurred. The specific error reason must be
* queried with wsrep_tls_stream_get_error_number and
* wsrep_tls_stream_get_error_category.
*/
wsrep_tls_result_error
};
/**
* Initialize a new TLS stream.
*
* Initialize the stream for IO operations. During this call the
* application must set up all of the data structures needed for
* IO, but must not do any reads or writes into the stream yet.
*
* @param stream TLS stream to be initialized.
*
* @return Zero on success, system error number on error.
*/
typedef int (*wsrep_tls_stream_init_t)(wsrep_tls_context_t*,
wsrep_tls_stream_t* stream);
/**
* Deinitialize the TLS stream.
*
* Deinitialize the TLS stream and free all allocated resources.
* Note that this function must not close the socket file descriptor
* associated the the stream.
*
* @param stream Stream to be deinitialized.
*/
typedef void (*wsrep_tls_stream_deinit_t)(wsrep_tls_context_t*,
wsrep_tls_stream_t* stream);
/**
* Get error number of the last stream error. The error numbers are
* defined by the application and must be integral type. By the convention
* zero value must denote success.
*
* For managing errors other than system errors, the application may
* provide several error categories via wsrep_tls_stream_get_error_category_t.
*
* @param stream TLS stream to get the last error from.
*
* @return Error number.
*/
typedef int (*wsrep_tls_stream_get_error_number_t)(
wsrep_tls_context_t*,
const wsrep_tls_stream_t* stream);
/**
* Get the error category of the last stream error.
*
* The category is represented via a const void pointer to the provider.
* If the category is NULL pointer, the error number is assumed to be
* system error.
*
* @param stream Stream to get last error category from.
*
* @return Pointer to error category.
*/
typedef const void* (*wsrep_tls_stream_get_error_category_t)(
wsrep_tls_context_t*,
const wsrep_tls_stream_t* stream);
/**
* Return human readable error message by error number and error
* category.
*
* The message string returned by the application must contain only
* printable characters and must be null terminated.
*
* @param error_number Error number returned by
* wsrep_tls_stream_get_error_number_t.
* @param category Error category returned by
* wsrep_tls_stream_get_error_category_t.
*
* @return Human readable message string.
*/
typedef const char* (*wsrep_tls_error_message_get_t)(
wsrep_tls_context_t*,
const wsrep_tls_stream_t* stream,
int error_number, const void* category);
/**
* Initiate TLS client side handshake. This function is called for the
* stream sockets which have been connected by the provider.
*
* If the stream socket is in non-blocking mode, the call should return
* immediately with appropriate result indicating if more actions are needed
* in the case the operation would block. The provider will call this function
* again until either a success or an error is returned.
*
* @param stream TLS stream.
*
* @return Enum wsrep_tls_result.
*/
typedef enum wsrep_tls_result (*wsrep_tls_stream_client_handshake_t)(
wsrep_tls_context_t*,
wsrep_tls_stream_t* stream);
/**
* Initiate TLS server side handshake. This function is called for stream
* sockets which have been accepted by the provider.
*
* If the stream socket is in non-blocking mode, the call should return
* immediately with appropriate result indicating if more actions are needed
* in the case the operation would block. The provider will call this function
* again until either a success or an error is returned.
*
* @param stream TLS stream.
*
* @return Enum wsrep_tls_result.
*/
typedef enum wsrep_tls_result (*wsrep_tls_stream_server_handshake_t)(
wsrep_tls_context_t*,
wsrep_tls_stream_t* stream);
/**
* Perform a read from the stream. If the file descriptor associated
* to the stream is in non-blocking mode, the call must return immediately
* with appropriate result if the stream processing would block.
*
* @param[in] stream TLS stream.
* @param[in] buf Buffer to read the data into.
* @param[in] max_count Maximum number of bytes to read.
* @param[out] bytes_transferred Number of bytes read into the buffer during
* the operation.
*
* @return Enum wsrep_tls_result.
*/
typedef enum wsrep_tls_result (*wsrep_tls_stream_read_t)(
wsrep_tls_context_t*,
wsrep_tls_stream_t* stream,
void* buf,
size_t max_count,
size_t* bytes_transferred);
/**
* Perform a write to the stream. If the file descriptor asociated to
* te stream is in non-blocking mode, the call must return immediately
* with appropriate result if the stream processing would block.
*
* @param[in] stream TLS stream.
* @param[in] buf Buffer which contains the data to write.
* @param[in] count Number of bytes to be written.
* @param[out] bytes_transferred Number of bytes written into the stream
* during the opration.
*
* @return Enum wsrep_tls_result.
*/
typedef enum wsrep_tls_result (*wsrep_tls_stream_write_t)(
wsrep_tls_context_t*,
wsrep_tls_stream_t* stream,
const void* buf,
size_t count,
size_t* bytes_transferred);
/**
* Shutdown the TLS stream.
*
* Note that the implementation must not close the associated stream
* socket, just shut down the protocol.
*
* If the shutdown call returns either wsrep_result_want_read or
* wsrep_result_want_write, the provider must wait until the socket
* becomes readable or writable and then call the function again
* until the return status is either success or an error occurs.
*
* @param stream TLS stream to be shut down.
*
* @return Enum wsrep_tls_result code.
*
*/
typedef enum wsrep_tls_result (*wsrep_tls_stream_shutdown_t)(
wsrep_tls_context_t*,
wsrep_tls_stream_t* stream);
/**
* TLS service struct.
*
* A pointer to this struct must be passed to the call to
* wsrep_init_tls_service_v1.
*
* The application must provide implementation to all functions defined
* in this struct.
*/
typedef struct wsrep_tls_service_v1_st
{
/* Stream */
wsrep_tls_stream_init_t stream_init;
wsrep_tls_stream_deinit_t stream_deinit;
wsrep_tls_stream_get_error_number_t stream_get_error_number;
wsrep_tls_stream_get_error_category_t stream_get_error_category;
wsrep_tls_stream_client_handshake_t stream_client_handshake;
wsrep_tls_stream_server_handshake_t stream_server_handshake;
wsrep_tls_stream_read_t stream_read;
wsrep_tls_stream_write_t stream_write;
wsrep_tls_stream_shutdown_t stream_shutdown;
/* Error */
wsrep_tls_error_message_get_t error_message_get;
/* Pointer to application defined TLS context. */
wsrep_tls_context_t* context;
} wsrep_tls_service_v1_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#define WSREP_TLS_SERVICE_INIT_FUNC_V1 "wsrep_init_tls_service_v1"
#define WSREP_TLS_SERVICE_DEINIT_FUNC_V1 "wsrep_deinit_tls_service_v1"
#endif /* WSREP_TLS_SERVICE_H */
|