James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one |
| 3 | * or more contributor license agreements. See the NOTICE file |
| 4 | * distributed with this work for additional information |
| 5 | * regarding copyright ownership. The ASF licenses this file |
| 6 | * to you under the Apache License, Version 2.0 (the |
| 7 | * "License"); you may not use this file except in compliance |
| 8 | * with the License. You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, |
| 13 | * software distributed under the License is distributed on an |
| 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 15 | * KIND, either express or implied. See the License for the |
| 16 | * specific language governing permissions and limitations |
| 17 | * under the License. |
| 18 | */ |
| 19 | |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 20 | #include <netdb.h> |
| 21 | #include <sys/wait.h> |
| 22 | #include <sys/types.h> |
| 23 | #include <sys/socket.h> |
| 24 | #include <netdb.h> |
| 25 | #include <arpa/inet.h> |
| 26 | |
| 27 | #include <thrift/c_glib/transport/thrift_transport.h> |
| 28 | #include <thrift/c_glib/transport/thrift_buffered_transport.h> |
| 29 | #include <thrift/c_glib/transport/thrift_server_transport.h> |
| 30 | #include <thrift/c_glib/transport/thrift_server_socket.h> |
| 31 | #include <thrift/c_glib/transport/thrift_ssl_socket.h> |
| 32 | |
| 33 | //#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } |
| 34 | #define TEST_DATA { "GET / HTTP/1.1\n\n" } |
| 35 | |
| 36 | |
| 37 | /* substituted functions to test failures of system and library calls */ |
| 38 | static int socket_error = 0; |
| 39 | int |
| 40 | my_socket(int domain, int type, int protocol) |
| 41 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 42 | if (socket_error == 0) |
| 43 | { |
| 44 | return socket (domain, type, protocol); |
| 45 | } |
| 46 | return -1; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 47 | } |
| 48 | |
| 49 | static int recv_error = 0; |
| 50 | ssize_t |
| 51 | my_recv(int socket, void *buffer, size_t length, int flags) |
| 52 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 53 | if (recv_error == 0) |
| 54 | { |
| 55 | return recv (socket, buffer, length, flags); |
| 56 | } |
| 57 | return -1; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | static int send_error = 0; |
| 61 | ssize_t |
| 62 | my_send(int socket, const void *buffer, size_t length, int flags) |
| 63 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 64 | if (send_error == 0) |
| 65 | { |
| 66 | return send (socket, buffer, length, flags); |
| 67 | } |
| 68 | return -1; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 69 | } |
| 70 | |
| 71 | #define socket my_socket |
| 72 | #define recv my_recv |
| 73 | #define send my_send |
| 74 | #include "../src/thrift/c_glib/transport/thrift_ssl_socket.c" |
| 75 | #undef socket |
| 76 | #undef recv |
| 77 | #undef send |
| 78 | |
| 79 | static void thrift_ssl_socket_server (const int port); |
| 80 | |
| 81 | /* test object creation and destruction */ |
| 82 | static void |
| 83 | test_ssl_create_and_destroy(void) |
| 84 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 85 | gchar *hostname = NULL; |
| 86 | guint port = 0; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 87 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 88 | GObject *object = NULL; |
| 89 | object = g_object_new (THRIFT_TYPE_SSL_SOCKET, NULL); |
| 90 | g_assert (object != NULL); |
| 91 | g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, NULL); |
| 92 | g_free (hostname); |
| 93 | g_object_unref (object); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | static void |
| 97 | test_ssl_create_and_set_properties(void) |
| 98 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 99 | gchar *hostname = NULL; |
| 100 | guint port = 0; |
| 101 | SSL_CTX* ssl_ctx= NULL; |
| 102 | GError *error=NULL; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 103 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 104 | GObject *object = NULL; |
| 105 | object = thrift_ssl_socket_new(SSLTLS, &error); |
| 106 | g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, "ssl_context", &ssl_ctx, NULL); |
| 107 | g_assert (ssl_ctx!=NULL); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 108 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 109 | g_free (hostname); |
| 110 | g_object_unref (object); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | static void |
| 114 | test_ssl_open_and_close(void) |
| 115 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 116 | ThriftSSLSocket *tSSLSocket = NULL; |
| 117 | ThriftTransport *transport = NULL; |
| 118 | GError *error=NULL; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 119 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 120 | /* open a connection and close it */ |
| 121 | tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188, &error); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 122 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 123 | transport = THRIFT_TRANSPORT (tSSLSocket); |
| 124 | thrift_ssl_socket_open (transport, NULL); |
| 125 | g_assert (thrift_ssl_socket_is_open (transport) == TRUE); |
| 126 | thrift_ssl_socket_close (transport, NULL); |
| 127 | g_assert (thrift_ssl_socket_is_open (transport) == FALSE); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 128 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 129 | /* test close failure */ |
| 130 | THRIFT_SOCKET(tSSLSocket)->sd = -1; |
| 131 | thrift_ssl_socket_close (transport, NULL); |
| 132 | g_object_unref (tSSLSocket); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 133 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 134 | /* try a hostname lookup failure */ |
| 135 | tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost.broken", 51188, &error); |
| 136 | transport = THRIFT_TRANSPORT (tSSLSocket); |
| 137 | g_assert (thrift_ssl_socket_open (transport, &error) == FALSE); |
| 138 | g_object_unref (tSSLSocket); |
| 139 | g_error_free (error); |
| 140 | error = NULL; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 141 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 142 | /* try an error call to socket() */ |
| 143 | tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188, &error); |
| 144 | transport = THRIFT_TRANSPORT (tSSLSocket); |
| 145 | socket_error = 1; |
| 146 | g_assert (thrift_ssl_socket_open (transport, &error) == FALSE); |
| 147 | socket_error = 0; |
| 148 | g_object_unref (tSSLSocket); |
| 149 | g_error_free (error); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | |
| 153 | |
| 154 | /** |
| 155 | * Print the common name of certificate |
| 156 | */ |
| 157 | unsigned char * get_cn_name(X509_NAME* const name) |
| 158 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 159 | int idx = -1; |
| 160 | unsigned char *utf8 = NULL; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 161 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 162 | do |
| 163 | { |
| 164 | if(!name) break; /* failed */ |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 165 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 166 | idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1); |
| 167 | if(!(idx > -1)) break; /* failed */ |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 168 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 169 | X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx); |
| 170 | if(!entry) break; /* failed */ |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 171 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 172 | ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry); |
| 173 | if(!data) break; /* failed */ |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 174 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 175 | int length = ASN1_STRING_to_UTF8(&utf8, data); |
| 176 | if(!utf8 || !(length > 0)) break; /* failed */ |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 177 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 178 | } while (0); |
| 179 | return utf8; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 180 | } |
| 181 | |
| 182 | /* |
| 183 | * Handle IPV4 and IPV6 addr |
| 184 | */ |
| 185 | void *get_in_addr(struct sockaddr *sa) |
| 186 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 187 | if (sa->sa_family == AF_INET) |
| 188 | return &(((struct sockaddr_in*)sa)->sin_addr); |
| 189 | return &(((struct sockaddr_in6*)sa)->sin6_addr); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | int verify_ip(char * hostname, struct sockaddr_storage *addr) |
| 193 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 194 | struct addrinfo *addr_info,*p; |
| 195 | struct addrinfo hints; |
| 196 | int res; |
| 197 | int retval = 0; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 198 | |
| 199 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 200 | memset(&hints, 0, sizeof hints); |
| 201 | hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 |
| 202 | hints.ai_socktype = SOCK_STREAM; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 203 | |
| 204 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 205 | if ( (res = getaddrinfo(hostname, NULL, &hints, &addr_info) ) != 0) |
| 206 | { |
| 207 | // get the host info |
| 208 | g_error("Cannot get the host address"); |
| 209 | return retval; |
| 210 | } |
| 211 | // loop through all the results and connect to the first we can |
| 212 | char dnshost[INET6_ADDRSTRLEN]; // bigger addr supported IPV6 |
| 213 | char socket_ip[INET6_ADDRSTRLEN]; |
| 214 | if(inet_ntop(addr->ss_family, get_in_addr(addr), socket_ip, INET6_ADDRSTRLEN)==socket_ip){ |
| 215 | g_debug("We are connected to host %s checking against certificate...", socket_ip); |
| 216 | int sizeip = socket_ip!=NULL ? strlen(socket_ip) : 0; |
| 217 | for(p = addr_info; p != NULL; p = p->ai_next) { |
| 218 | if(inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), dnshost, INET6_ADDRSTRLEN)==dnshost){ |
| 219 | if(dnshost!=NULL){ |
| 220 | g_info("DNS address [%i -> %s]", p->ai_addr, dnshost); |
| 221 | if(!strncmp(dnshost, socket_ip, sizeip)){ |
| 222 | retval=1; |
| 223 | break; // if we get here, we must have connected successfully |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 229 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 230 | if(addr_info) |
| 231 | freeaddrinfo(addr_info); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 232 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 233 | return retval; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 234 | } |
| 235 | |
| 236 | static void |
| 237 | read_from_file(char *buffer, long size, const char *file_name) |
| 238 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 239 | char ch; |
| 240 | long index=0; |
| 241 | FILE *fp; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 242 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 243 | fp = fopen(file_name,"r"); // read mode |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 244 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 245 | if( fp == NULL ) |
| 246 | { |
| 247 | perror("Error while opening the file.\n"); |
| 248 | exit(EXIT_FAILURE); |
| 249 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 250 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 251 | printf("The contents of %s file are :\n", file_name); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 252 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 253 | while(index<size && ( ch = fgetc(fp) ) != EOF ){ |
| 254 | buffer[index++] = ch; |
| 255 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 256 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 257 | fclose(fp); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 258 | } |
| 259 | |
| 260 | #define ISSUER_CN_PINNING "The Apache Software Foundation" |
| 261 | #define SUBJECT_CN_PINNING "localhost" |
| 262 | #define CERT_SERIAL_NUMBER "1" |
| 263 | |
| 264 | gboolean verify_certificate_sn(X509 *cert, const unsigned char *serial_number) |
| 265 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 266 | gboolean retval = FALSE; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 267 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 268 | ASN1_INTEGER *serial = X509_get_serialNumber(cert); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 269 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 270 | BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL); |
| 271 | if (!bn) { |
| 272 | fprintf(stderr, "unable to convert ASN1INTEGER to BN\n"); |
| 273 | return EXIT_FAILURE; |
| 274 | } |
| 275 | char *tmp = BN_bn2dec(bn); |
| 276 | if (!tmp) { |
| 277 | g_warning(stderr, "unable to convert BN to decimal string.\n"); |
| 278 | BN_free(bn); |
| 279 | return EXIT_FAILURE; |
| 280 | } |
| 281 | // if (strlen(tmp) >= len) { |
| 282 | // g_warn(stderr, "buffer length shorter than serial number\n"); |
| 283 | // BN_free(bn); |
| 284 | // OPENSSL_free(tmp); |
| 285 | // return EXIT_FAILURE; |
| 286 | // } |
| 287 | if(!strncmp(serial_number, tmp, strlen(serial_number))){ |
| 288 | retval=TRUE; |
| 289 | }else{ |
| 290 | g_warning("Serial number is not valid"); |
| 291 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 292 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 293 | BN_free(bn); |
| 294 | OPENSSL_free(tmp); |
| 295 | return retval; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 296 | } |
| 297 | |
| 298 | gboolean my_access_manager(ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error) |
| 299 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 300 | ThriftSSLSocket *sslSocket = THRIFT_SSL_SOCKET (transport); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 301 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 302 | g_info("Processing access to the server"); |
| 303 | X509_NAME* iname = cert ? X509_get_issuer_name(cert) : NULL; |
| 304 | X509_NAME* sname = cert ? X509_get_subject_name(cert) : NULL; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 305 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 306 | /* Issuer is the authority we trust that warrants nothing useful */ |
| 307 | const unsigned char * issuer = get_cn_name(iname); |
| 308 | if(issuer){ |
| 309 | gboolean valid = TRUE; |
| 310 | g_info("Issuer (cn) %s", issuer); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 311 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 312 | // Issuer pinning |
| 313 | if(strncmp(ISSUER_CN_PINNING, issuer, strlen(ISSUER_CN_PINNING))){ |
| 314 | g_warning("The Issuer of the certificate is not valid"); |
| 315 | valid=FALSE; |
| 316 | } |
| 317 | OPENSSL_free(issuer); |
| 318 | if(!valid) |
| 319 | return valid; |
| 320 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 321 | |
| 322 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 323 | /* Subject is who the certificate is issued to by the authority */ |
| 324 | const unsigned char * subject = get_cn_name(sname); |
| 325 | if(subject){ |
| 326 | g_info("Subject (cn) %s", subject); |
| 327 | gboolean valid = TRUE; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 328 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 329 | // Subject pinning |
| 330 | if(strncmp(SUBJECT_CN_PINNING, subject, strlen(SUBJECT_CN_PINNING))){ |
| 331 | g_warning("The subject of the certificate is not valid"); |
| 332 | valid=FALSE; |
| 333 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 334 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 335 | if(!valid) |
| 336 | return valid; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 337 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 338 | // Host pinning |
| 339 | if(verify_ip(subject, addr)){ |
| 340 | g_info("Verified subject"); |
| 341 | }else{ |
| 342 | g_info("Cannot verify subject"); |
| 343 | valid=FALSE; |
| 344 | } |
| 345 | OPENSSL_free(subject); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 346 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 347 | if(!valid) |
| 348 | return valid; |
| 349 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 350 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 351 | if(!verify_certificate_sn(cert, CERT_SERIAL_NUMBER)){ |
| 352 | return FALSE; |
| 353 | }else{ |
| 354 | g_info("Verified serial number"); |
| 355 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 356 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 357 | return TRUE; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 358 | |
| 359 | } |
| 360 | |
| 361 | |
| 362 | |
| 363 | |
| 364 | #ifdef BUILD_SERVER |
| 365 | static void |
| 366 | test_ssl_authorization_manager(void) |
| 367 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 368 | int status=0; |
| 369 | pid_t pid; |
| 370 | ThriftSSLSocket *tSSLsocket = NULL; |
| 371 | ThriftTransport *transport = NULL; |
| 372 | // int port = 51199; |
| 373 | int port = 443; |
| 374 | GError *error=NULL; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 375 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 376 | guchar buf[17] = TEST_DATA; /* a buffer */ |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 377 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 378 | // pid = fork (); |
| 379 | // g_assert ( pid >= 0 ); |
| 380 | // |
| 381 | // if ( pid == 0 ) |
| 382 | // { |
| 383 | // /* child listens */ |
| 384 | // thrift_ssl_socket_server (port); |
| 385 | // exit (0); |
| 386 | // } else { |
| 387 | /* parent connects, wait a bit for the socket to be created */ |
| 388 | sleep (1); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 389 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 390 | // Test against level2 owncloud certificate |
| 391 | tSSLsocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error); |
| 392 | thrift_ssl_socket_set_manager(tSSLsocket, my_access_manager); // Install pinning manager |
| 393 | //thrift_ssl_load_cert_from_file(tSSLsocket, "./owncloud.level2crm.pem"); |
| 394 | unsigned char cert_buffer[65534]; |
| 395 | read_from_file(cert_buffer, 65534, "../../keys/client.pem"); |
| 396 | if(!thrift_ssl_load_cert_from_buffer(tSSLsocket, cert_buffer)){ |
| 397 | g_warning("Certificates cannot be loaded!"); |
| 398 | } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 399 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 400 | transport = THRIFT_TRANSPORT (tSSLsocket); |
| 401 | g_assert (thrift_ssl_socket_open (transport, NULL) == TRUE); |
| 402 | g_assert (thrift_ssl_socket_is_open (transport)); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 403 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 404 | thrift_ssl_socket_write (transport, buf, 17, NULL); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 405 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 406 | /* write fail */ |
| 407 | send_error = 1; |
| 408 | // thrift_ssl_socket_write (transport, buf, 1, NULL); |
| 409 | // send_error = 0; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 410 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 411 | // thrift_ssl_socket_write_end (transport, NULL); |
| 412 | // thrift_ssl_socket_flush (transport, NULL); |
| 413 | thrift_ssl_socket_close (transport, NULL); |
| 414 | g_object_unref (tSSLsocket); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 415 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 416 | // g_assert ( wait (&status) == pid ); |
| 417 | g_assert ( status == 0 ); |
| 418 | // } |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 419 | } |
| 420 | #endif |
| 421 | |
| 422 | |
| 423 | /* test ThriftSocket's peek() implementation */ |
| 424 | //static void |
| 425 | //test_ssl_peek(void) |
| 426 | //{ |
| 427 | // gint status; |
| 428 | // pid_t pid; |
| 429 | // guint port = 51199; |
| 430 | // gchar data = 'A'; |
| 431 | // ThriftTransport *client_transport; |
| 432 | // GError *error = NULL; |
| 433 | // |
| 434 | // client_transport = g_object_new (THRIFT_TYPE_SSL_SOCKET, |
| 435 | // "hostname", "localhost", |
| 436 | // "port", port, |
| 437 | // NULL); |
| 438 | // |
| 439 | // /* thrift_transport_peek returns FALSE when the socket is closed */ |
| 440 | // g_assert (thrift_transport_is_open (client_transport) == FALSE); |
| 441 | // g_assert (thrift_transport_peek (client_transport, &error) == FALSE); |
| 442 | // g_assert (error == NULL); |
| 443 | // |
| 444 | // pid = fork (); |
| 445 | // g_assert (pid >= 0); |
| 446 | // |
| 447 | // if (pid == 0) |
| 448 | // { |
| 449 | // ThriftServerTransport *server_transport = NULL; |
| 450 | // |
| 451 | // g_object_unref (client_transport); |
| 452 | // |
| 453 | // /* child listens */ |
| 454 | // server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET, |
| 455 | // "port", port, |
| 456 | // NULL); |
| 457 | // g_assert (server_transport != NULL); |
| 458 | // |
| 459 | // thrift_server_transport_listen (server_transport, &error); |
| 460 | // g_assert (error == NULL); |
| 461 | // |
| 462 | // client_transport = g_object_new |
| 463 | // (THRIFT_TYPE_BUFFERED_TRANSPORT, |
| 464 | // "transport", thrift_server_transport_accept (server_transport, &error), |
| 465 | // "r_buf_size", 0, |
| 466 | // "w_buf_size", sizeof data, |
| 467 | // NULL); |
| 468 | // g_assert (error == NULL); |
| 469 | // g_assert (client_transport != NULL); |
| 470 | // |
| 471 | // /* write exactly one character to the client */ |
| 472 | // g_assert (thrift_transport_write (client_transport, |
| 473 | // &data, |
| 474 | // sizeof data, |
| 475 | // &error) == TRUE); |
| 476 | // |
| 477 | // thrift_transport_flush (client_transport, &error); |
| 478 | // thrift_transport_write_end (client_transport, &error); |
| 479 | // thrift_transport_close (client_transport, &error); |
| 480 | // |
| 481 | // g_object_unref (client_transport); |
| 482 | // g_object_unref (server_transport); |
| 483 | // |
| 484 | // exit (0); |
| 485 | // } |
| 486 | // else { |
| 487 | // /* parent connects, wait a bit for the socket to be created */ |
| 488 | // sleep (1); |
| 489 | // |
| 490 | // /* connect to the child */ |
| 491 | // thrift_transport_open (client_transport, &error); |
| 492 | // g_assert (error == NULL); |
| 493 | // g_assert (thrift_transport_is_open (client_transport) == TRUE); |
| 494 | // |
| 495 | // /* thrift_transport_peek returns TRUE when the socket is open and there is |
| 496 | // data available to be read */ |
| 497 | // g_assert (thrift_transport_peek (client_transport, &error) == TRUE); |
| 498 | // g_assert (error == NULL); |
| 499 | // |
| 500 | // /* read exactly one character from the server */ |
| 501 | // g_assert_cmpint (thrift_transport_read (client_transport, |
| 502 | // &data, |
| 503 | // sizeof data, |
| 504 | // &error), ==, sizeof data); |
| 505 | // |
| 506 | // /* thrift_transport_peek returns FALSE when the socket is open but there is |
| 507 | // no (more) data available to be read */ |
| 508 | // g_assert (thrift_transport_is_open (client_transport) == TRUE); |
| 509 | // g_assert (thrift_transport_peek (client_transport, &error) == FALSE); |
| 510 | // g_assert (error == NULL); |
| 511 | // |
| 512 | // thrift_transport_read_end (client_transport, &error); |
| 513 | // thrift_transport_close (client_transport, &error); |
| 514 | // |
| 515 | // g_object_unref (client_transport); |
| 516 | // |
| 517 | // g_assert (wait (&status) == pid); |
| 518 | // g_assert (status == 0); |
| 519 | // } |
| 520 | //} |
| 521 | |
| 522 | static void |
| 523 | thrift_ssl_socket_server (const int port) |
| 524 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 525 | int bytes = 0; |
| 526 | ThriftServerTransport *transport = NULL; |
| 527 | ThriftTransport *client = NULL; |
| 528 | guchar buf[10]; /* a buffer */ |
| 529 | guchar match[10] = TEST_DATA; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 530 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 531 | ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, |
| 532 | "port", port, NULL); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 533 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 534 | transport = THRIFT_SERVER_TRANSPORT (tsocket); |
| 535 | thrift_server_transport_listen (transport, NULL); |
| 536 | client = thrift_server_transport_accept (transport, NULL); |
| 537 | g_assert (client != NULL); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 538 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 539 | /* read 10 bytes */ |
| 540 | bytes = thrift_ssl_socket_read (client, buf, 10, NULL); |
| 541 | g_assert (bytes == 10); /* make sure we've read 10 bytes */ |
| 542 | g_assert ( memcmp(buf, match, 10) == 0 ); /* make sure what we got matches */ |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 543 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 544 | /* failed read */ |
| 545 | recv_error = 1; |
| 546 | thrift_ssl_socket_read (client, buf, 1, NULL); |
| 547 | recv_error = 0; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 548 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 549 | thrift_ssl_socket_read_end (client, NULL); |
| 550 | thrift_ssl_socket_close (client, NULL); |
| 551 | g_object_unref (tsocket); |
| 552 | g_object_unref (client); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 553 | } |
| 554 | |
| 555 | int |
| 556 | main(int argc, char *argv[]) |
| 557 | { |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 558 | int retval; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 559 | #if (!GLIB_CHECK_VERSION (2, 36, 0)) |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 560 | g_type_init(); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 561 | #endif |
| 562 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 563 | g_test_init (&argc, &argv, NULL); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 564 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 565 | thrift_ssl_socket_initialize_openssl(); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 566 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 567 | g_test_add_func ("/testtransportsslsocket/CreateAndDestroy", test_ssl_create_and_destroy); |
| 568 | g_test_add_func ("/testtransportsslsocket/CreateAndSetProperties", test_ssl_create_and_set_properties); |
| 569 | g_test_add_func ("/testtransportsslsocket/OpenAndClose", test_ssl_open_and_close); |
| 570 | // This test is disabled because server is not ready |
| 571 | // g_test_add_func ("/testtransportsslsocket/AuthorizationManagerPinning", test_ssl_authorization_manager); |
| 572 | // g_test_add_func ("/testtransportsslsocket/Peek", test_ssl_peek); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 573 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 574 | retval = g_test_run (); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 575 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 576 | thrift_ssl_socket_finalize_openssl(); |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 577 | |
James E. King, III | 43f4bf2 | 2017-10-28 12:54:02 -0400 | [diff] [blame] | 578 | return retval; |
James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame] | 579 | } |
| 580 | |