trilogy_w_prepared_statements 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +80 -0
  4. data/Rakefile +22 -0
  5. data/ext/trilogy-ruby/cast.c +277 -0
  6. data/ext/trilogy-ruby/cext.c +1048 -0
  7. data/ext/trilogy-ruby/extconf.rb +17 -0
  8. data/ext/trilogy-ruby/inc/trilogy/blocking.h +281 -0
  9. data/ext/trilogy-ruby/inc/trilogy/buffer.h +64 -0
  10. data/ext/trilogy-ruby/inc/trilogy/builder.h +165 -0
  11. data/ext/trilogy-ruby/inc/trilogy/charset.h +277 -0
  12. data/ext/trilogy-ruby/inc/trilogy/client.h +760 -0
  13. data/ext/trilogy-ruby/inc/trilogy/error.h +44 -0
  14. data/ext/trilogy-ruby/inc/trilogy/packet_parser.h +34 -0
  15. data/ext/trilogy-ruby/inc/trilogy/protocol.h +1014 -0
  16. data/ext/trilogy-ruby/inc/trilogy/reader.h +216 -0
  17. data/ext/trilogy-ruby/inc/trilogy/socket.h +111 -0
  18. data/ext/trilogy-ruby/inc/trilogy/vendor/curl_hostcheck.h +29 -0
  19. data/ext/trilogy-ruby/inc/trilogy/vendor/openssl_hostname_validation.h +51 -0
  20. data/ext/trilogy-ruby/inc/trilogy.h +8 -0
  21. data/ext/trilogy-ruby/src/blocking.c +358 -0
  22. data/ext/trilogy-ruby/src/buffer.c +60 -0
  23. data/ext/trilogy-ruby/src/builder.c +236 -0
  24. data/ext/trilogy-ruby/src/charset.c +212 -0
  25. data/ext/trilogy-ruby/src/client.c +903 -0
  26. data/ext/trilogy-ruby/src/error.c +17 -0
  27. data/ext/trilogy-ruby/src/packet_parser.c +140 -0
  28. data/ext/trilogy-ruby/src/protocol.c +1175 -0
  29. data/ext/trilogy-ruby/src/reader.c +282 -0
  30. data/ext/trilogy-ruby/src/socket.c +623 -0
  31. data/ext/trilogy-ruby/src/vendor/curl_hostcheck.c +206 -0
  32. data/ext/trilogy-ruby/src/vendor/openssl_hostname_validation.c +175 -0
  33. data/ext/trilogy-ruby/trilogy-ruby.h +37 -0
  34. data/lib/trilogy/version.rb +3 -0
  35. data/lib/trilogy.rb +61 -0
  36. data/trilogy.gemspec +27 -0
  37. metadata +107 -0
@@ -0,0 +1,216 @@
1
+ #ifndef TRILOGY_READER_H
2
+ #define TRILOGY_READER_H
3
+
4
+ #include <stdbool.h>
5
+ #include <stddef.h>
6
+ #include <stdint.h>
7
+
8
+ /* Trilogy Packet Reader API
9
+ *
10
+ * The packet reader API is used to parse MySQL-compatible protocol packets.
11
+ */
12
+
13
+ /* trilogy_reader_t - The reader API's instance type.
14
+ */
15
+ typedef struct {
16
+ const uint8_t *buff;
17
+ size_t len;
18
+ size_t pos;
19
+ } trilogy_reader_t;
20
+
21
+ /* trilogy_reader_init - Initialize a pre-allocated trilogy_reader_t.
22
+ *
23
+ * reader - A pointer to a pre-allocated trilogy_reader_t.
24
+ * buff - A pointer to a buffer containing MySQL-compatible protocol packet data.
25
+ * len - The length of `buff` in bytes.
26
+ *
27
+ * Returns nothing.
28
+ */
29
+ void trilogy_reader_init(trilogy_reader_t *reader, const uint8_t *buff, size_t len);
30
+
31
+ #define TRILOGY_READER(buffer, length) ((trilogy_reader_t){.buff = (buffer), .len = (length), .pos = 0});
32
+
33
+ /* trilogy_reader_get_uint8 - Parse an unsigned 8-bit integer.
34
+ *
35
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
36
+ * out - Out parameter; A pointer to a uint8_t which will be set to the
37
+ * value read from the buffer.
38
+ *
39
+ * Return values:
40
+ * TRILOGY_OK - The value was parsed.
41
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
42
+ */
43
+ int trilogy_reader_get_uint8(trilogy_reader_t *reader, uint8_t *out);
44
+
45
+ /* trilogy_reader_get_uint16 - Parse an unsigned 16-bit integer.
46
+ *
47
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
48
+ * out - Out parameter; A pointer to a uint16_t which will be set to the
49
+ * value read from the buffer.
50
+ *
51
+ * Return values:
52
+ * TRILOGY_OK - The value was parsed.
53
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
54
+ */
55
+ int trilogy_reader_get_uint16(trilogy_reader_t *reader, uint16_t *out);
56
+
57
+ /* trilogy_reader_get_uint24 - Parse an unsigned 24-bit integer.
58
+ *
59
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
60
+ * out - Out parameter; A pointer to a uint32_t which will be set to the
61
+ * value read from the buffer.
62
+ *
63
+ * Return values:
64
+ * TRILOGY_OK - The value was parsed.
65
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
66
+ */
67
+ int trilogy_reader_get_uint24(trilogy_reader_t *reader, uint32_t *out);
68
+
69
+ /* trilogy_reader_get_uint32 - Parse an unsigned 32-bit integer.
70
+ *
71
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
72
+ * out - Out parameter; A pointer to a uint32_t which will be set to the
73
+ * value read from the buffer.
74
+ *
75
+ * Return values:
76
+ * TRILOGY_OK - The value was parsed.
77
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
78
+ */
79
+ int trilogy_reader_get_uint32(trilogy_reader_t *reader, uint32_t *out);
80
+
81
+ /* trilogy_reader_get_uint64 - Parse an unsigned 64-bit integer.
82
+ *
83
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
84
+ * out - Out parameter; A pointer to a uint64_t which will be set to the
85
+ * value read from the buffer.
86
+ *
87
+ * Return values:
88
+ * TRILOGY_OK - The value was parsed.
89
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
90
+ */
91
+ int trilogy_reader_get_uint64(trilogy_reader_t *reader, uint64_t *out);
92
+
93
+ int trilogy_reader_get_float(trilogy_reader_t *reader, float *out);
94
+
95
+ int trilogy_reader_get_double(trilogy_reader_t *reader, double *out);
96
+
97
+ /* trilogy_reader_get_lenenc - Parse an unsigned, length-encoded integer.
98
+ *
99
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
100
+ * out - Out parameter; A pointer to a uint64_t which will be set to the
101
+ * value read from the buffer.
102
+ *
103
+ * Return values:
104
+ * TRILOGY_OK - The value was parsed.
105
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
106
+ */
107
+ int trilogy_reader_get_lenenc(trilogy_reader_t *reader, uint64_t *out);
108
+
109
+ /* trilogy_reader_get_buffer - Parse an opaque set of bytes from the packet,
110
+ * pointing the dereferenced value of `out` to the beginning of the set.
111
+ *
112
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
113
+ * len - The number of bytes to attempt to read from the buffer.
114
+ * out - Out parameter; A pointer to a void* which will be set to the
115
+ * beginning of the opaque buffer. This will be a pointer into the
116
+ * buffer that was originally passed to trilogy_reader_init. No copies
117
+ * are made internally.
118
+ *
119
+ * Return values:
120
+ * TRILOGY_OK - The value was parsed and the dereferenced value of
121
+ * `out` now points to it.
122
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
123
+ */
124
+ int trilogy_reader_get_buffer(trilogy_reader_t *reader, size_t len, const void **out);
125
+
126
+ /* trilogy_reader_copy_buffer - Parse an opaque set of bytes from the packet and
127
+ * copy them into `out`. `out` must be allocated with at least `len` bytes.
128
+ *
129
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
130
+ * len - The number of bytes to attempt to read from the buffer.
131
+ * out - A pointer to the address to copy `len` bytes from the packet buffer
132
+ * to.
133
+ *
134
+ * Return values:
135
+ * TRILOGY_OK - The value was parsed and copied into the location
136
+ * `out` points to.
137
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
138
+ */
139
+ int trilogy_reader_copy_buffer(trilogy_reader_t *reader, size_t len, void *out);
140
+
141
+ /* trilogy_reader_get_lenenc_buffer - Parse an opaque set of bytes from the
142
+ * packet, pointing the dereferenced value of `out` to the beginning of the set.
143
+ * The length of the buffer is defined by a preceding length-encoded integer,
144
+ * who's value will be copied in to `out_len`.
145
+ *
146
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
147
+ * out_len - Out parameter; The length of the read buffer in bytes.
148
+ * out - Out parameter; A pointer to a void* which will be set to the
149
+ * beginning of the opaque buffer.
150
+ *
151
+ * Return values:
152
+ * TRILOGY_OK - The value was parsed and the dereferenced value of
153
+ * `out` now points to it.
154
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
155
+ */
156
+ int trilogy_reader_get_lenenc_buffer(trilogy_reader_t *reader, size_t *out_len, const void **out);
157
+
158
+ /* trilogy_reader_get_string - Parse a C-string from the packet, pointing the
159
+ * dereferenced value of `out` to the beginning of the set.
160
+ *
161
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
162
+ * out_len - Out parameter; The length of the C-string read from the buffer in
163
+ * bytes.
164
+ * out - Out parameter; A pointer to a void* which will be set to the
165
+ * beginning of the C-string.
166
+ *
167
+ * Return values:
168
+ * TRILOGY_OK - The value was parsed and the dereferenced value of
169
+ * `out` now points to it.
170
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data left in the buffer.
171
+ */
172
+ int trilogy_reader_get_string(trilogy_reader_t *reader, const char **out, size_t *out_len);
173
+
174
+ /* trilogy_reader_get_eof_buffer - Parse an opaque set of bytes from the packet,
175
+ * pointing the dereferenced value of `out` to the beginning of the set. The
176
+ * buffer pointed to by `out` will contain the remaining un-parsed bytes from
177
+ * the packet buffer.
178
+ *
179
+ * This will just hand the caller back a pointer into the remainder of the
180
+ * buffer, even if there aren't any more bytes left to read. As a result, this
181
+ * function will only ever return TRILOGY_OK.
182
+ *
183
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
184
+ * out_len - Out parameter; The length of the read buffer in bytes.
185
+ * out - Out parameter; A pointer to a void* which will be set to the
186
+ * beginning of the opaque buffer.
187
+ *
188
+ * Return values:
189
+ * TRILOGY_OK - The value was parsed and the dereferenced value of
190
+ * `out` now points to it.
191
+ */
192
+ int trilogy_reader_get_eof_buffer(trilogy_reader_t *reader, size_t *out_len, const void **out);
193
+
194
+ /* trilogy_reader_eof - Check if the reader is at the end of the buffer.
195
+ *
196
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
197
+ *
198
+ * Returns true if the reader is at the end of the buffer it's reading from,
199
+ * or false if not
200
+ */
201
+ bool trilogy_reader_eof(trilogy_reader_t *reader);
202
+
203
+ /* trilogy_reader_finish - Finalize the reader. This will ensure the entire buffer
204
+ * was parsed, otherwise TRILOGY_EXTRA_DATA_IN_PACKET will be returned.
205
+ *
206
+ * This can be useful to ensure an entire packet is fully read.
207
+ *
208
+ * reader - A pointer to a pre-initialized trilogy_reader_t.
209
+ *
210
+ * Return values:
211
+ * TRILOGY_OK - The entire buffer was parsed.
212
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the buffer.
213
+ */
214
+ int trilogy_reader_finish(trilogy_reader_t *reader);
215
+
216
+ #endif
@@ -0,0 +1,111 @@
1
+ #ifndef TRILOGY_SOCKET_H
2
+ #define TRILOGY_SOCKET_H
3
+
4
+ #include "trilogy/error.h"
5
+ #include "trilogy/protocol.h"
6
+ #include <openssl/err.h>
7
+ #include <openssl/ssl.h>
8
+ #include <openssl/x509v3.h>
9
+ #include <stdbool.h>
10
+ #include <sys/time.h>
11
+
12
+ typedef enum {
13
+ TRILOGY_WAIT_READ = 0,
14
+ TRILOGY_WAIT_WRITE = 1,
15
+ TRILOGY_WAIT_HANDSHAKE = 2,
16
+ } trilogy_wait_t;
17
+
18
+ // We use the most strict mode as value 1 so if anyone ever
19
+ // treats this as a boolean, they get the most strict behavior
20
+ // by default.
21
+ typedef enum {
22
+ TRILOGY_SSL_DISABLED = 0,
23
+ TRILOGY_SSL_VERIFY_IDENTITY = 1,
24
+ TRILOGY_SSL_VERIFY_CA = 2,
25
+ TRILOGY_SSL_REQUIRED_NOVERIFY = 3,
26
+ TRILOGY_SSL_PREFERRED_NOVERIFY = 4,
27
+ } trilogy_ssl_mode_t;
28
+
29
+ typedef enum {
30
+ TRILOGY_TLS_VERSION_UNDEF = 0,
31
+ TRILOGY_TLS_VERSION_10 = 1,
32
+ TRILOGY_TLS_VERSION_11 = 2,
33
+ TRILOGY_TLS_VERSION_12 = 3,
34
+ TRILOGY_TLS_VERSION_13 = 4,
35
+ } trilogy_tls_version_t;
36
+
37
+ typedef struct {
38
+ char *hostname;
39
+ char *path;
40
+ char *database;
41
+ char *username;
42
+ char *password;
43
+ size_t password_len;
44
+
45
+ trilogy_ssl_mode_t ssl_mode;
46
+ trilogy_tls_version_t tls_min_version;
47
+ trilogy_tls_version_t tls_max_version;
48
+ uint16_t port;
49
+
50
+ char *ssl_ca;
51
+ char *ssl_capath;
52
+ char *ssl_cert;
53
+ char *ssl_cipher;
54
+ char *ssl_crl;
55
+ char *ssl_crlpath;
56
+ char *ssl_key;
57
+ char *tls_ciphersuites;
58
+
59
+ struct timeval connect_timeout;
60
+ struct timeval read_timeout;
61
+ struct timeval write_timeout;
62
+
63
+ bool keepalive_enabled;
64
+ uint16_t keepalive_idle;
65
+ uint16_t keepalive_count;
66
+ uint16_t keepalive_interval;
67
+
68
+ TRILOGY_CAPABILITIES_t flags;
69
+ } trilogy_sockopt_t;
70
+
71
+ typedef struct trilogy_sock_t {
72
+ int (*connect_cb)(struct trilogy_sock_t *self);
73
+ ssize_t (*read_cb)(struct trilogy_sock_t *self, void *buf, size_t nread);
74
+ ssize_t (*write_cb)(struct trilogy_sock_t *self, const void *buf, size_t nwrite);
75
+ int (*wait_cb)(struct trilogy_sock_t *self, trilogy_wait_t wait);
76
+ int (*shutdown_cb)(struct trilogy_sock_t *self);
77
+ int (*close_cb)(struct trilogy_sock_t *self);
78
+ int (*fd_cb)(struct trilogy_sock_t *self);
79
+
80
+ trilogy_sockopt_t opts;
81
+ } trilogy_sock_t;
82
+
83
+ static inline int trilogy_sock_connect(trilogy_sock_t *sock) { return sock->connect_cb(sock); }
84
+
85
+ static inline ssize_t trilogy_sock_read(trilogy_sock_t *sock, void *buf, size_t n)
86
+ {
87
+ return sock->read_cb(sock, buf, n);
88
+ }
89
+
90
+ static inline ssize_t trilogy_sock_write(trilogy_sock_t *sock, const void *buf, size_t n)
91
+ {
92
+ return sock->write_cb(sock, buf, n);
93
+ }
94
+
95
+ static inline int trilogy_sock_wait(trilogy_sock_t *sock, trilogy_wait_t wait) { return sock->wait_cb(sock, wait); }
96
+
97
+ static inline int trilogy_sock_wait_read(trilogy_sock_t *sock) { return sock->wait_cb(sock, TRILOGY_WAIT_READ); }
98
+
99
+ static inline int trilogy_sock_wait_write(trilogy_sock_t *sock) { return sock->wait_cb(sock, TRILOGY_WAIT_WRITE); }
100
+
101
+ static inline int trilogy_sock_shutdown(trilogy_sock_t *sock) { return sock->shutdown_cb(sock); }
102
+
103
+ static inline int trilogy_sock_close(trilogy_sock_t *sock) { return sock->close_cb(sock); }
104
+
105
+ static inline int trilogy_sock_fd(trilogy_sock_t *sock) { return sock->fd_cb(sock); }
106
+
107
+ trilogy_sock_t *trilogy_sock_new(const trilogy_sockopt_t *opts);
108
+ int trilogy_sock_resolve(trilogy_sock_t *raw);
109
+ int trilogy_sock_upgrade_ssl(trilogy_sock_t *raw);
110
+
111
+ #endif
@@ -0,0 +1,29 @@
1
+ #ifndef HEADER_CURL_HOSTCHECK_H
2
+ #define HEADER_CURL_HOSTCHECK_H
3
+ /***************************************************************************
4
+ * _ _ ____ _
5
+ * Project ___| | | | _ \| |
6
+ * / __| | | | |_) | |
7
+ * | (__| |_| | _ <| |___
8
+ * \___|\___/|_| \_\_____|
9
+ *
10
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
11
+ *
12
+ * This software is licensed as described in the file COPYING, which
13
+ * you should have received as part of this distribution. The terms
14
+ * are also available at http://curl.haxx.se/docs/copyright.html.
15
+ *
16
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17
+ * copies of the Software, and permit persons to whom the Software is
18
+ * furnished to do so, under the terms of the COPYING file.
19
+ *
20
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21
+ * KIND, either express or implied.
22
+ *
23
+ ***************************************************************************/
24
+
25
+ #define CURL_HOST_NOMATCH 0
26
+ #define CURL_HOST_MATCH 1
27
+ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
28
+
29
+ #endif /* HEADER_CURL_HOSTCHECK_H */
@@ -0,0 +1,51 @@
1
+ #ifndef HEADER_OPENSSL_HOSTNAME_VALIDATION_H
2
+ #define HEADER_OPENSSL_HOSTNAME_VALIDATION_H
3
+ /* Obtained from: https://github.com/iSECPartners/ssl-conservatory */
4
+
5
+ /*
6
+ Copyright (C) 2012, iSEC Partners.
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
8
+ this software and associated documentation files (the "Software"), to deal in
9
+ the Software without restriction, including without limitation the rights to
10
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ of the Software, and to permit persons to whom the Software is furnished to do
12
+ so, subject to the following conditions:
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ */
23
+
24
+ /*
25
+ * Helper functions to perform basic hostname validation using OpenSSL.
26
+ *
27
+ * Please read "everything-you-wanted-to-know-about-openssl.pdf" before
28
+ * attempting to use this code. This whitepaper describes how the code works,
29
+ * how it should be used, and what its limitations are.
30
+ *
31
+ * Author: Alban Diquet
32
+ * License: See LICENSE
33
+ *
34
+ */
35
+
36
+ typedef enum { MatchFound, MatchNotFound, NoSANPresent, MalformedCertificate, Error } HostnameValidationResult;
37
+
38
+ /**
39
+ * Validates the server's identity by looking for the expected hostname in the
40
+ * server's certificate. As described in RFC 6125, it first tries to find a
41
+ * match in the Subject Alternative Name extension. If the extension is not
42
+ * present in the certificate, it checks the Common Name instead.
43
+ *
44
+ * Returns MatchFound if a match was found.
45
+ * Returns MatchNotFound if no matches were found.
46
+ * Returns MalformedCertificate if any of the hostnames had a NUL character
47
+ * embedded in it. Returns Error if there was an error.
48
+ */
49
+ HostnameValidationResult validate_hostname(const char *hostname, const X509 *server_cert);
50
+
51
+ #endif /* HEADER_OPENSSL_HOSTNAME_VALIDATION_H */
@@ -0,0 +1,8 @@
1
+ #ifndef TRILOGY_H
2
+ #define TRILOGY_H
3
+
4
+ #include "trilogy/blocking.h"
5
+ #include "trilogy/client.h"
6
+ #include "trilogy/error.h"
7
+
8
+ #endif