test3.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2012, 2020 IBM Corp. and others
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v2.0
6  * and Eclipse Distribution License v1.0 which accompany this distribution.
7  *
8  * The Eclipse Public License is available at
9  * https://www.eclipse.org/legal/epl-2.0/
10  * and the Eclipse Distribution License is available at
11  * http://www.eclipse.org/org/documents/edl-v10.php.
12  *
13  * Contributors:
14  * Allan Stockdill-Mander - initial API and implementation and/or initial documentation
15  * Ian Craggs - add SSL options NULL test
16  *******************************************************************************/
17 
23 #include "MQTTClient.h"
24 #include <string.h>
25 #include <stdlib.h>
26 
27 #if defined(_WINDOWS)
28  #include <windows.h>
29  #include <openssl/applink.c>
30  #define MAXHOSTNAMELEN 256
31  #define snprintf _snprintf
32  #define setenv(a, b, c) _putenv_s(a, b)
33 #else
34  #include <sys/time.h>
35  #include <sys/socket.h>
36  #include <unistd.h>
37  #include <errno.h>
38 #endif
39 
40 #if defined(IOS)
41 char skeytmp[1024];
42 char ckeytmp[1024];
43 char persistenceStore[1024];
44 #else
45 char* persistenceStore = NULL;
46 #endif
47 
48 #define LOGA_DEBUG 0
49 #define LOGA_INFO 1
50 #include <stdarg.h>
51 #include <time.h>
52 #include <sys/timeb.h>
53 
54 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
55 
56 void usage(void)
57 {
58  printf("Options:\n");
59  printf("\t--test_no <test_no> - Run test number <test_no>\n");
60  printf("\t--connection <mqtt URL> - Connect to <mqtt URL> for tests\n");
61  printf("\t--haconnections \"<mqtt URLs>\" - Use \"<mqtt URLs>\" as the list of servers for HA tests (space separated)\n");
62  printf("\t--client_key <key_file> - Use <key_file> as the client certificate for SSL authentication\n");
63  printf("\t--client_key_pass <password> - Use <password> to access the private key in the client certificate\n");
64  printf("\t--client_privatekey <file> - Client private key file if not in certificate file\n");
65  printf("\t--server_key <key_file> - Use <key_file> as the trusted certificate for server\n");
66  printf("\t--verbose - Enable verbose output \n");
67  printf("\tserver connection URLs should be in the form; (tcp|ssl)://hostname:port\n");
68  printf("\t--help - This help output\n");
69  exit(EXIT_FAILURE);
70 }
71 
72 struct Options
73 {
74  char connection[100];
78  char anon_connection[100];
79  char psk_connection[100];
80  char** haconnections;
81  int hacount;
86  int verbose;
87  int test_no;
89 } options =
90 {
91  "ssl://m2m.eclipse.org:18883",
92  "ssl://m2m.eclipse.org:18884",
93  "ssl://m2m.eclipse.org:18887",
94  "ssl://m2m.eclipse.org:18885",
95  "ssl://m2m.eclipse.org:18886",
96  "ssl://m2m.eclipse.org:18888",
97  NULL,
98  0,
99  "../../../test/ssl/client.pem",
100  NULL,
101  "../../../test/ssl/test-root-ca.crt",
102  NULL,
103  0,
104  0,
105  0,
106 };
107 
108 
109 char* test_map[] =
110 {
111  "none",
112  "1", // 1
113  "2a_s", // 2
114  "2a_m", // 3
115  "2b", // 4
116  "2c", // 5
117  "3a_s", // 6
118  "3a_m", // 7
119  "3b", // 8
120  "4s", // 9
121  "4m", // 10
122  "5a", // 11
123  "5b", // 12
124  "5c", // 13
125 };
126 
127 
128 void getopts(int argc, char** argv)
129 {
130  int count = 1;
131 
132  while (count < argc)
133  {
134  if (strcmp(argv[count], "--help") == 0)
135  usage();
136  else if (strcmp(argv[count], "--test_no") == 0)
137  {
138  if (++count < argc)
139  {
140  int i;
141 
142  for (i = 1; i < ARRAY_SIZE(test_map); ++i)
143  {
144  if (strcmp(argv[count], test_map[i]) == 0)
145  {
146  options.test_no = i;
147  break;
148  }
149  }
150  if (options.test_no == 0)
151  options.test_no = atoi(argv[count]);
152 
153  }
154  else
155  usage();
156  }
157  else if (strcmp(argv[count], "--hostname") == 0)
158  {
159  if (++count < argc)
160  {
161  char* prefix = (options.websockets) ? "wss" : "ssl";
162 
163  sprintf(options.connection, "%s://%s:18883", prefix, argv[count]);
164  printf("Setting connection to %s\n", options.connection);
165  sprintf(options.mutual_auth_connection, "%s://%s:18884", prefix, argv[count]);
166  printf("Setting mutual_auth_connection to %s\n", options.mutual_auth_connection);
167  sprintf(options.nocert_mutual_auth_connection, "%s://%s:18887", prefix, argv[count]);
168  printf("Setting nocert_mutual_auth_connection to %s\n",
170  sprintf(options.server_auth_connection, "%s://%s:18885", prefix, argv[count]);
171  printf("Setting server_auth_connection to %s\n", options.server_auth_connection);
172  sprintf(options.anon_connection, "%s://%s:18886", prefix, argv[count]);
173  printf("Setting anon_connection to %s\n", options.anon_connection);
174  sprintf(options.psk_connection, "%s://%s:18888", prefix, argv[count]);
175  printf("Setting psk_connection to %s\n", options.psk_connection);
176  }
177  else
178  usage();
179  }
180  else if (strcmp(argv[count], "--haconnections") == 0)
181  {
182  if (++count < argc)
183  {
184  char* tok = strtok(argv[count], " ");
185  options.hacount = 0;
186  options.haconnections = malloc(sizeof(char*) * 5);
187  while (tok)
188  {
189  options.haconnections[options.hacount] = malloc(strlen(tok) + 1);
190  strcpy(options.haconnections[options.hacount], tok);
191  options.hacount++;
192  tok = strtok(NULL, " ");
193  }
194  }
195  else
196  usage();
197  }
198  else if (strcmp(argv[count], "--client_key") == 0)
199  {
200  if (++count < argc)
201  {
202 #if defined(IOS)
203  strcat(ckeytmp, getenv("HOME"));
204  strcat(ckeytmp, argv[count]);
205  options.client_key_file = ckeytmp;
206 #else
207  options.client_key_file = argv[count];
208 #endif
209  }
210  else
211  usage();
212  }
213  else if (strcmp(argv[count], "--client_privatekey") == 0)
214  {
215  if (++count < argc)
216  {
217 #if defined(IOS)
218  strcat(ckeytmp, getenv("HOME"));
219  strcat(ckeytmp, argv[count]);
221 #else
223 #endif
224  }
225  else
226  usage();
227  }
228  else if (strcmp(argv[count], "--client_key_pass") == 0)
229  {
230  if (++count < argc)
231  options.client_key_pass = argv[count];
232  else
233  usage();
234  }
235  else if (strcmp(argv[count], "--server_key") == 0)
236  {
237  if (++count < argc)
238  {
239 #if defined(IOS)
240  strcat(skeytmp, getenv("HOME"));
241  strcat(skeytmp, argv[count]);
242  options.server_key_file = skeytmp;
243 #else
244  options.server_key_file = argv[count];
245 #endif
246  }
247  else
248  usage();
249  }
250  else if (strcmp(argv[count], "--verbose") == 0)
251  {
252  options.verbose = 1;
253  printf("\nSetting verbose on\n");
254  }
255  else if (strcmp(argv[count], "--ws") == 0)
256  {
257  options.websockets = 1;
258  printf("\nSetting websockets on\n");
259  }
260  count++;
261  }
262 #if defined(IOS)
263  strcpy(persistenceStore, getenv("HOME"));
264  strcat(persistenceStore, "/Library/Caches");
265 #endif
266 }
267 
268 void MyLog(int LOGA_level, char* format, ...)
269 {
270  static char msg_buf[256];
271  va_list args;
272 #if defined(_WIN32) || defined(_WINDOWS)
273  struct timeb ts;
274 #else
275  struct timeval ts;
276 #endif
277  struct tm timeinfo;
278 
279  if (LOGA_level == LOGA_DEBUG && options.verbose == 0)
280  return;
281 
282 #if defined(_WIN32) || defined(_WINDOWS)
283  ftime(&ts);
284  localtime_s(&timeinfo, &ts.time);
285 #else
286  gettimeofday(&ts, NULL);
287  localtime_r(&ts.tv_sec, &timeinfo);
288 #endif
289  strftime(msg_buf, 80, "%Y%m%d %H%M%S", &timeinfo);
290 
291 #if defined(_WIN32) || defined(_WINDOWS)
292  sprintf(&msg_buf[strlen(msg_buf)], ".%.3hu ", ts.millitm);
293 #else
294  sprintf(&msg_buf[strlen(msg_buf)], ".%.3lu ", ts.tv_usec / 1000);
295 #endif
296 
297  va_start(args, format);
298  vsnprintf(&msg_buf[strlen(msg_buf)], sizeof(msg_buf) - strlen(msg_buf), format, args);
299  va_end(args);
300 
301  printf("%s\n", msg_buf);
302  fflush(stdout);
303 }
304 
305 
306 #if defined(_WIN32) || defined(_WINDOWS)
307 #define mqsleep(A) Sleep(1000*A)
308 #define START_TIME_TYPE DWORD
309 static DWORD start_time = 0;
311 {
312  return GetTickCount();
313 }
314 #elif defined(AIX)
315 #define mqsleep sleep
316 #define START_TIME_TYPE struct timespec
318 {
319  static struct timespec start;
320  clock_gettime(CLOCK_REALTIME, &start);
321  return start;
322 }
323 #else
324 #define mqsleep sleep
325 #define START_TIME_TYPE struct timeval
326 /* TODO - unused - remove? static struct timeval start_time; */
328 {
329  struct timeval start_time;
330  gettimeofday(&start_time, NULL);
331  return start_time;
332 }
333 #endif
334 
335 
336 #if defined(_WIN32)
337 long elapsed(START_TIME_TYPE start_time)
338 {
339  return GetTickCount() - start_time;
340 }
341 #elif defined(AIX)
342 #define assert(a)
343 long elapsed(struct timespec start)
344 {
345  struct timespec now, res;
346 
347  clock_gettime(CLOCK_REALTIME, &now);
348  ntimersub(now, start, res);
349  return (res.tv_sec)*1000L + (res.tv_nsec)/1000000L;
350 }
351 #else
352 long elapsed(START_TIME_TYPE start_time)
353 {
354  struct timeval now, res;
355 
356  gettimeofday(&now, NULL);
357  timersub(&now, &start_time, &res);
358  return (res.tv_sec)*1000 + (res.tv_usec)/1000;
359 }
360 #endif
361 
362 
363 #define assert(a, b, c, d) myassert(__FILE__, __LINE__, a, b, c, d)
364 #define assert1(a, b, c, d, e) myassert(__FILE__, __LINE__, a, b, c, d, e)
365 
366 
367 int tests = 0;
368 int failures = 0;
369 FILE* xml;
371 char output[3000];
373 
374 
376 {
377  long duration = elapsed(global_start_time);
378 
379  fprintf(xml, " time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
380  if (cur_output != output)
381  {
382  fprintf(xml, "%s", output);
383  cur_output = output;
384  }
385  fprintf(xml, "</testcase>\n");
386 }
387 
388 
389 int myassert(char* filename, int lineno, char* description, int value, char* format, ...)
390 {
391  ++tests;
392  if (!value)
393  {
394  va_list args;
395 
396  ++failures;
397  printf("Assertion failed, file %s, line %d, description: %s\n", filename, lineno, description);
398 
399  va_start(args, format);
400  vprintf(format, args);
401  va_end(args);
402 
403  cur_output += sprintf(cur_output, "<failure type=\"%s\">file %s, line %d </failure>\n",
404  description, filename, lineno);
405  }
406  else
407  MyLog(LOGA_DEBUG, "Assertion succeeded, file %s, line %d, description: %s", filename, lineno, description);
408  return value;
409 }
410 
411 
412 /*********************************************************************
413 
414 Test: single-threaded client
415 
416 *********************************************************************/
418 {
421  MQTTClient_message* m = NULL;
422  char* topicName = NULL;
423  int topicLen;
424  int i = 0;
425  int iterations = 50;
426  int rc;
427 
428  MyLog(LOGA_DEBUG, "%d messages at QoS %d", iterations, qos);
429  pubmsg.payload = "a much longer message that we can shorten to the extent that we need to payload up to 11";
430  pubmsg.payloadlen = 11;
431  pubmsg.qos = qos;
432  pubmsg.retained = 0;
433 
434  for (i = 0; i< iterations; ++i)
435  {
436  if (i % 10 == 0)
437  rc = MQTTClient_publish(c, test_topic, pubmsg.payloadlen, pubmsg.payload, pubmsg.qos, pubmsg.retained, NULL);
438  else
439  rc = MQTTClient_publishMessage(c, test_topic, &pubmsg, &dt);
440  assert("Good rc from publish", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
441 
442  if (qos > 0)
443  {
444  rc = MQTTClient_waitForCompletion(c, dt, 20000L);
445  assert("Good rc from waitforCompletion", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
446  }
447 
448  rc = MQTTClient_receive(c, &topicName, &topicLen, &m, 10000);
449  assert("Good rc from receive", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
450  if (topicName)
451  {
452  MyLog(LOGA_DEBUG, "Message received on topic %s is %.*s", topicName, m->payloadlen, (char*)(m->payload));
453  if (pubmsg.payloadlen != m->payloadlen ||
454  memcmp(m->payload, pubmsg.payload, m->payloadlen) != 0)
455  {
456  failures++;
457  MyLog(LOGA_INFO, "Error: wrong data - received lengths %d %d", pubmsg.payloadlen, m->payloadlen);
458  break;
459  }
460  MQTTClient_free(topicName);
462  }
463  else
464  printf("No message received within timeout period\n");
465  }
466 
467  /* receive any outstanding messages */
468  MQTTClient_receive(c, &topicName, &topicLen, &m, 1000);
469  while (topicName)
470  {
471  printf("Message received on topic %s is %.*s.\n", topicName, m->payloadlen, (char*)(m->payload));
472  MQTTClient_free(topicName);
474  MQTTClient_receive(c, &topicName, &topicLen, &m, 1000);
475  }
476 }
477 
478 /*********************************************************************
479 
480 Test: multi-threaded client using callbacks
481 
482 *********************************************************************/
483 volatile int multiThread_arrivedcount = 0;
486 
488 {
490 }
491 
492 int multiThread_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* m)
493 {
495  MyLog(LOGA_DEBUG, "Callback: %d message received on topic %s is %.*s.",
496  multiThread_arrivedcount, topicName, m->payloadlen, (char*)(m->payload));
497  if (multiThread_pubmsg.payloadlen != m->payloadlen ||
498  memcmp(m->payload, multiThread_pubmsg.payload, m->payloadlen) != 0)
499  {
500  failures++;
501  MyLog(LOGA_INFO, "Error: wrong data received lengths %d %d\n", multiThread_pubmsg.payloadlen, m->payloadlen);
502  }
503  MQTTClient_free(topicName);
505  return 1;
506 }
507 
508 
510 {
512  int i = 0;
513  int iterations = 50;
514  int rc = 0;
515  int wait_seconds = 0;
516 
519 
520  MyLog(LOGA_DEBUG, "%d messages at QoS %d", iterations, qos);
521  multiThread_pubmsg.payload = "a much longer message that we can shorten to the extent that we need to";
522  multiThread_pubmsg.payloadlen = 27;
523  multiThread_pubmsg.qos = qos;
524  multiThread_pubmsg.retained = 0;
525 
526  for (i = 1; i <= iterations; ++i)
527  {
528  if (i % 10 == 0)
529  rc = MQTTClient_publish(c, test_topic, multiThread_pubmsg.payloadlen, multiThread_pubmsg.payload,
530  multiThread_pubmsg.qos, multiThread_pubmsg.retained, NULL);
531  else
532  rc = MQTTClient_publishMessage(c, test_topic, &multiThread_pubmsg, &dt);
533  assert("Good rc from publish", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
534 
535  #if defined(_WIN32)
536  Sleep(100);
537  #else
538  usleep(100000L);
539  #endif
540 
541  wait_seconds = 20;
542  while ((multiThread_arrivedcount < i) && (wait_seconds-- > 0))
543  {
544  MyLog(LOGA_DEBUG, "Arrived %d count %d", multiThread_arrivedcount, i);
545  #if defined(_WIN32)
546  Sleep(1000);
547  #else
548  usleep(1000000L);
549  #endif
550  }
551  assert("Message Arrived", wait_seconds > 0,
552  "Time out waiting for message %d\n", i );
553  }
554  if (qos > 0)
555  {
556  /* MQ Telemetry can send a message to a subscriber before the server has
557  completed the QoS 2 handshake with the publisher. For QoS 1 and 2,
558  allow time for the final delivery complete callback before checking
559  that all expected callbacks have been made */
560  wait_seconds = 10;
561  while ((multiThread_deliveryCompleted < iterations) && (wait_seconds-- > 0))
562  {
563  MyLog(LOGA_DEBUG, "Delivery Completed %d count %d", multiThread_deliveryCompleted, i);
564  #if defined(_WIN32)
565  Sleep(1000);
566  #else
567  usleep(1000000L);
568  #endif
569  }
570  assert("All Deliveries Complete", wait_seconds > 0,
571  "Number of deliveryCompleted callbacks was %d\n",
573  }
574 }
575 
576 
577 /*********************************************************************
578 
579 Test1: SSL connection to non SSL MQTT server
580 
581 *********************************************************************/
582 int test1(struct Options options)
583 {
584  char* testname = "test1";
585  char* test_topic = "C client SSL test1";
586  int subsqos = 2;
587  MQTTClient c;
591  int rc = 0;
592 
593  failures = 0;
594  MyLog(LOGA_INFO, "Starting SSL test 1 - connection to nonSSL MQTT server");
595  fprintf(xml, "<testcase classname=\"test3\" name=\"SSL connect fail to nonSSL MQTT server\"");
597 
598  rc = MQTTClient_create(&c, "a b://wrong protocol", "test1", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
599  assert("bad rc from create", rc == MQTTCLIENT_BAD_PROTOCOL, "rc was %d \n", rc);
600 
602  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d \n", rc)))
603  goto exit;
604 
605  opts.keepAliveInterval = 20;
606  opts.cleansession = 1;
607  opts.username = "testuser";
608  opts.password = "testpassword";
609  if (options.haconnections != NULL)
610  {
611  opts.serverURIs = options.haconnections;
612  opts.serverURIcount = options.hacount;
613  }
614 
615  /* Try with ssl opts == NULL - should get error */
616  rc = MQTTClient_connect(c, &opts);
617  assert("Connect should fail", rc == MQTTCLIENT_NULL_PARAMETER, "rc was %d ", rc);
618 
619  opts.ssl = &sslopts;
620  if (options.server_key_file != NULL)
621  opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
622 
623  MyLog(LOGA_DEBUG, "Connecting");
624 
625  rc = MQTTClient_connect(c, &opts);
626  if (!(assert("Connect should fail", rc == MQTTCLIENT_FAILURE, "rc was %d ", rc)))
627  goto exit;
628 
629 exit:
630  MQTTClient_destroy(&c);
631  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
632  (failures == 0) ? "passed" : "failed", testname, tests, failures);
634  return failures;
635 }
636 
637 
638 /*********************************************************************
639 
640 Test2a: Mutual SSL Authentication - Certificates in place on client and server - single threaded
641 
642 *********************************************************************/
643 
645 {
646  char* testname = "test2a_s";
647  char* test_topic = "C client test2a_s";
648  int subsqos = 2;
649  MQTTClient c;
653  int rc = 0;
654 
655  failures = 0;
656  MyLog(LOGA_INFO, "Starting test 2a_s - Mutual SSL authentication - single threaded client using receive");
657  fprintf(xml, "<testcase classname=\"test3\" name=\"test 2a_s\"");
659 
661  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
662  goto exit;
663 
664  opts.keepAliveInterval = 20;
665  opts.cleansession = 1;
666  opts.username = "testuser";
667  opts.password = "testpassword";
668  if (options.haconnections != NULL) {
669  opts.serverURIs = options.haconnections;
670  opts.serverURIcount = options.hacount;
671  }
672 
673  opts.ssl = &sslopts;
674  if (options.server_key_file)
675  opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
676  opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
677  if (options.client_key_pass)
678  opts.ssl->privateKeyPassword = options.client_key_pass;
679  if (options.client_private_key_file)
680  opts.ssl->privateKey = options.client_private_key_file;
681  opts.ssl->verify = 1;
682 
683  MyLog(LOGA_DEBUG, "Connecting");
684 
685  rc = MQTTClient_connect(c, &opts);
686  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
687  goto exit;
688 
689  rc = MQTTClient_subscribe(c, test_topic, subsqos);
690  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
691  goto exit;
692 
693  singleThread_sendAndReceive(c, 0, test_topic);
694  singleThread_sendAndReceive(c, 1, test_topic);
695  singleThread_sendAndReceive(c, 2, test_topic);
696 
697  MyLog(LOGA_DEBUG, "Stopping\n");
698 
699  rc = MQTTClient_unsubscribe(c, test_topic);
700  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
701  goto exit;
702  rc = MQTTClient_disconnect(c, 0);
703  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
704  goto exit;
705 
706  /* Just to make sure we can connect again */
707  rc = MQTTClient_connect(c, &opts);
708  if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
709  goto exit;
710  rc = MQTTClient_disconnect(c, 0);
711  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
712  goto exit;
713 
714 exit:
715  MQTTClient_destroy(&c);
716  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
717  (failures == 0) ? "passed" : "failed", testname, tests, failures);
719  return failures;
720 }
721 
722 /*********************************************************************
723 
724 Test2a: Mutual SSL Authentication - Certificates in place on client and server - multi threaded
725 
726 *********************************************************************/
727 
729 {
730  char* testname = "test2a_m";
731  char* test_topic = "C client test2a_m";
732  int subsqos = 2;
733  /* TODO - usused - remove ? MQTTClient_deliveryToken* dt = NULL; */
734  MQTTClient c;
738  int rc = 0;
739 
740  failures = 0;
741  MyLog(LOGA_INFO, "Starting test 2a_m - Mutual SSL authentication - multi-threaded client using callbacks");
742  fprintf(xml, "<testcase classname=\"test3\" name=\"test 2a_m\"");
744 
746  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
747  goto exit;
748 
749  opts.keepAliveInterval = 20;
750  opts.cleansession = 1;
751  opts.username = "testuser";
752  opts.password = "testpassword";
753  if (options.haconnections != NULL)
754  {
755  opts.serverURIs = options.haconnections;
756  opts.serverURIcount = options.hacount;
757  }
758 
759  opts.ssl = &sslopts;
760  if (options.server_key_file)
761  opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
762  opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
763  if (options.client_key_pass)
764  opts.ssl->privateKeyPassword = options.client_key_pass;
765  if (options.client_private_key_file)
766  opts.ssl->privateKey = options.client_private_key_file;
767  //opts.ssl->enabledCipherSuites = "DEFAULT";
768  //opts.ssl->enabledServerCertAuth = 1;
769 
771  if (!(assert("Good rc from setCallbacks", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
772  goto exit;
773 
774  MyLog(LOGA_DEBUG, "Connecting");
775 
776  rc = MQTTClient_connect(c, &opts);
777  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
778  goto exit;
779 
780  rc = MQTTClient_subscribe(c, test_topic, subsqos);
781  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
782  goto exit;
783 
784  multiThread_sendAndReceive(c, 0, test_topic);
785  multiThread_sendAndReceive(c, 1, test_topic);
786  multiThread_sendAndReceive(c, 2, test_topic);
787 
788  MyLog(LOGA_DEBUG, "Stopping");
789 
790  rc = MQTTClient_unsubscribe(c, test_topic);
791  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
792  goto exit;
793  rc = MQTTClient_disconnect(c, 0);
794  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
795  goto exit;
796 
797 exit:
798  MQTTClient_destroy(&c);
799  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
800  (failures == 0) ? "passed" : "failed", testname, tests, failures);
802  return failures;
803 }
804 
805 /*********************************************************************
806 
807 Test2b: Mutual SSL Authentication - Server does not have Client cert, connection fails
808 
809 *********************************************************************/
810 int test2b(struct Options options)
811 {
812  char* testname = "test2b";
813  char* test_topic = "C client test2b";
814  int subsqos = 2;
815  MQTTClient c;
819  int rc = 0;
820 
821  failures = 0;
822  MyLog(LOGA_INFO, "Starting test 2b - connection to SSL MQTT server with clientauth=req but server does not have client cert");
823  fprintf(xml, "<testcase classname=\"test3\" name=\"test 2b\"");
825 
827  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
828  goto exit;
829 
830  opts.keepAliveInterval = 20;
831  opts.cleansession = 1;
832  opts.username = "testuser";
833  opts.password = "testpassword";
834  if (options.haconnections != NULL)
835  {
836  opts.serverURIs = options.haconnections;
837  opts.serverURIcount = options.hacount;
838  }
839 
840  opts.ssl = &sslopts;
841  if (options.server_key_file)
842  opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
843  opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
844  if (options.client_key_pass)
845  opts.ssl->privateKeyPassword = options.client_key_pass;
846  if (options.client_private_key_file)
847  opts.ssl->privateKey = options.client_private_key_file;
848  //opts.ssl->enabledCipherSuites = "DEFAULT";
849  //opts.ssl->enabledServerCertAuth = 0;
850 
851  MyLog(LOGA_DEBUG, "Connecting");
852 
853  rc = MQTTClient_connect(c, &opts);
854  if (!(assert("Bad rc from connect", rc == MQTTCLIENT_FAILURE, "rc was %d\n", rc)))
855  goto exit;
856 
857 exit:
858  MQTTClient_destroy(&c);
859  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
860  (failures == 0) ? "passed" : "failed", testname, tests, failures);
862  return failures;
863 }
864 
865 /*********************************************************************
866 
867 Test2c: Mutual SSL Authentication - Client does not have Server cert
868 
869 *********************************************************************/
870 int test2c(struct Options options)
871 {
872  char* testname = "test2c";
873  char* test_topic = "C client test2c";
874  int subsqos = 2;
875  MQTTClient c;
879  int rc = 0;
880 
881  failures = 0;
882  MyLog(LOGA_INFO, "Starting test 2c - connection to SSL MQTT server, server auth enabled but unknown cert");
883  fprintf(xml, "<testcase classname=\"test3\" name=\"test 2c\"");
885 
887  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
888  goto exit;
889 
890  opts.keepAliveInterval = 20;
891  opts.cleansession = 1;
892  opts.username = "testuser";
893  opts.password = "testpassword";
894  if (options.haconnections != NULL)
895  {
896  opts.serverURIs = options.haconnections;
897  opts.serverURIcount = options.hacount;
898  }
899 
900  opts.ssl = &sslopts;
901  //if (options.server_key_file)
902  // opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
903  opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
904  if (options.client_key_pass)
905  opts.ssl->privateKeyPassword = options.client_key_pass;
906  if (options.client_private_key_file)
907  opts.ssl->privateKey = options.client_private_key_file;
908  //opts.ssl->enabledCipherSuites = "DEFAULT";
909  //opts.ssl->enabledServerCertAuth = 0;
910 
911  MyLog(LOGA_DEBUG, "Connecting");
912 
913  rc = MQTTClient_connect(c, &opts);
914  if (!(assert("Good rc from connect", rc == MQTTCLIENT_FAILURE, "rc was %d", rc)))
915  goto exit;
916 
917 exit:
918  MQTTClient_destroy(&c);
919  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
920  (failures == 0) ? "passed" : "failed", testname, tests, failures);
922  return failures;
923 }
924 
925 /*********************************************************************
926 
927 Test2e: Mutual SSL Authentication - high availability
928 
929 *********************************************************************/
930 
932 {
933  char* testname = "test2e_s";
934  char* test_topic = "C client test2e_s";
935  int subsqos = 2;
936  MQTTClient c;
940  char* uris[2] = {"wrong", options.mutual_auth_connection};
941  int rc = 0;
942 
943  failures = 0;
944  MyLog(LOGA_INFO, "Starting test 2e_s - Mutual SSL authentication - HA");
945  fprintf(xml, "<testcase classname=\"test3\" name=\"test 2e_s\"");
947 
948  rc = MQTTClient_create(&c, "not used", "test2e_s", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
949  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
950  goto exit;
951 
952  opts.keepAliveInterval = 20;
953  opts.cleansession = 1;
954  opts.username = "testuser";
955  opts.password = "testpassword";
956  opts.serverURIs = uris;
957  opts.serverURIcount = 2;
958 
959  opts.ssl = &sslopts;
960  if (options.server_key_file)
961  opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
962  opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
963  if (options.client_key_pass)
964  opts.ssl->privateKeyPassword = options.client_key_pass;
965  if (options.client_private_key_file)
966  opts.ssl->privateKey = options.client_private_key_file;
967  opts.ssl->verify = 1;
968 
969  MyLog(LOGA_DEBUG, "Connecting");
970 
971  rc = MQTTClient_connect(c, &opts);
972  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
973  goto exit;
974 
975  rc = MQTTClient_subscribe(c, test_topic, subsqos);
976  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
977  goto exit;
978 
979  singleThread_sendAndReceive(c, 0, test_topic);
980  singleThread_sendAndReceive(c, 1, test_topic);
981  singleThread_sendAndReceive(c, 2, test_topic);
982 
983  MyLog(LOGA_DEBUG, "Stopping\n");
984 
985  rc = MQTTClient_unsubscribe(c, test_topic);
986  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
987  goto exit;
988  rc = MQTTClient_disconnect(c, 0);
989  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
990  goto exit;
991 
992  /* Just to make sure we can connect again */
993  rc = MQTTClient_connect(c, &opts);
994  if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
995  goto exit;
996  rc = MQTTClient_disconnect(c, 0);
997  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
998  goto exit;
999 
1000 exit:
1001  MQTTClient_destroy(&c);
1002  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1003  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1005  return failures;
1006 }
1007 
1008 /*********************************************************************
1009 
1010 Test3a: Server Authentication - server certificate in client trust store - single threaded
1011 
1012 *********************************************************************/
1013 
1015 {
1016  char* testname = "test3a_s";
1017  char* test_topic = "C client test3a_s";
1018  int subsqos = 2;
1019  MQTTClient c;
1023  int rc = 0;
1024 
1025  failures = 0;
1026  MyLog(LOGA_INFO, "Starting test 3a_s - Server authentication - single threaded client using receive");
1027  fprintf(xml, "<testcase classname=\"test3\" name=\"test 3a_s\"");
1029 
1031  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1032  goto exit;
1033 
1034  opts.keepAliveInterval = 20;
1035  opts.cleansession = 1;
1036  opts.username = "testuser";
1037  opts.password = "testpassword";
1038  if (options.haconnections != NULL)
1039  {
1040  opts.serverURIs = options.haconnections;
1041  opts.serverURIcount = options.hacount;
1042  }
1043 
1044  opts.ssl = &sslopts;
1045  if (options.server_key_file != NULL)
1046  opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
1047 
1048  MyLog(LOGA_DEBUG, "Connecting");
1049 
1050  rc = MQTTClient_connect(c, &opts);
1051  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1052  goto exit;
1053 
1054  rc = MQTTClient_subscribe(c, test_topic, subsqos);
1055  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1056 
1057  singleThread_sendAndReceive(c, 0, test_topic);
1058  singleThread_sendAndReceive(c, 1, test_topic);
1059  singleThread_sendAndReceive(c, 2, test_topic);
1060 
1061  MyLog(LOGA_DEBUG, "Stopping\n");
1062 
1063  rc = MQTTClient_unsubscribe(c, test_topic);
1064  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1065  goto exit;
1066  rc = MQTTClient_disconnect(c, 0);
1067  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1068  goto exit;
1069 
1070  /* Just to make sure we can connect again */
1071 
1072  rc = MQTTClient_connect(c, &opts);
1073  if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1074  goto exit;
1075  rc = MQTTClient_disconnect(c, 0);
1076  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1077  goto exit;
1078 
1079 exit:
1080  MQTTClient_destroy(&c);
1081  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1082  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1084  return failures;
1085 }
1086 
1087 /*********************************************************************
1088 
1089 Test3a: Server Authentication - server certificate in client trust store - multi threaded
1090 
1091 *********************************************************************/
1092 
1094 {
1095  char* testname = "test3a_m";
1096  char* test_topic = "C client test3a_m";
1097  int subsqos = 2;
1098  MQTTClient c;
1102  int rc = 0;
1103 
1104  failures = 0;
1105  MyLog(LOGA_INFO, "Starting test 3a_m - Server authentication - multi-threaded client using callbacks");
1106  fprintf(xml, "<testcase classname=\"test3\" name=\"test 3a_m\"");
1108 
1110  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1111  goto exit;
1112 
1113  opts.keepAliveInterval = 20;
1114  opts.cleansession = 1;
1115  opts.username = "testuser";
1116  opts.password = "testpassword";
1117  if (options.haconnections != NULL)
1118  {
1119  opts.serverURIs = options.haconnections;
1120  opts.serverURIcount = options.hacount;
1121  }
1122 
1123  opts.ssl = &sslopts;
1124  if (options.server_key_file != NULL)
1125  opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
1126 
1128  if (!(assert("Good rc from setCallbacks", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1129  goto exit;
1130 
1131  MyLog(LOGA_DEBUG, "Connecting");
1132 
1133  rc = MQTTClient_connect(c, &opts);
1134  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1135  goto exit;
1136 
1137  rc = MQTTClient_subscribe(c, test_topic, subsqos);
1138  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1139  goto exit;
1140 
1141  multiThread_sendAndReceive(c, 0, test_topic);
1142  multiThread_sendAndReceive(c, 1, test_topic);
1143  multiThread_sendAndReceive(c, 2, test_topic);
1144 
1145  MyLog(LOGA_DEBUG, "Stopping\n");
1146 
1147  rc = MQTTClient_unsubscribe(c, test_topic);
1148  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1149  goto exit;
1150  rc = MQTTClient_disconnect(c, 0);
1151  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1152  goto exit;
1153 
1154 exit:
1155  MQTTClient_destroy(&c);
1156  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1157  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1159  return failures;
1160 }
1161 
1162 /*********************************************************************
1163 
1164 Test3b: Server Authentication - Client does not have server cert
1165 
1166 *********************************************************************/
1168 {
1169  char* testname = "test3b";
1170  char* test_topic = "C client test3b";
1171  int subsqos = 2;
1172  MQTTClient c;
1176  int rc = 0;
1177 
1178  failures = 0;
1179  MyLog(LOGA_INFO, "Starting test 3b - connection to SSL MQTT server with clientauth=opt but client does not have server cert");
1180  fprintf(xml, "<testcase classname=\"test3\" name=\"test 3b\"");
1182 
1184  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1185  goto exit;
1186 
1187  opts.keepAliveInterval = 20;
1188  opts.cleansession = 1;
1189  opts.username = "testuser";
1190  opts.password = "testpassword";
1191  if (options.haconnections != NULL)
1192  {
1193  opts.serverURIs = options.haconnections;
1194  opts.serverURIcount = options.hacount;
1195  }
1196 
1197  opts.ssl = &sslopts;
1198 
1199  MyLog(LOGA_DEBUG, "Connecting");
1200 
1201  rc = MQTTClient_connect(c, &opts);
1202  if (!(assert("Bad rc from connect", rc == MQTTCLIENT_FAILURE, "rc was %d", rc)))
1203  goto exit;
1204 
1205 exit:
1206  MQTTClient_destroy(&c);
1207  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1208  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1210  return failures;
1211 }
1212 
1213 /*********************************************************************
1214 
1215 Test4_s: Accept invalid server certificates - single threaded
1216 
1217 *********************************************************************/
1218 
1220 {
1221  char* testname = "test4_s";
1222  char* test_topic = "C client test4_s";
1223  int subsqos = 2;
1224  MQTTClient c;
1228  int rc = 0;
1229 
1230  failures = 0;
1231  MyLog(LOGA_INFO, "Starting test 4_s - accept invalid server certificates - single threaded");
1232  fprintf(xml, "<testcase classname=\"test3\" name=\"test 4_s\"");
1234 
1236  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1237  goto exit;
1238 
1239  opts.keepAliveInterval = 20;
1240  opts.cleansession = 1;
1241  opts.username = "testuser";
1242  opts.password = "testpassword";
1243  if (options.haconnections != NULL)
1244  {
1245  opts.serverURIs = options.haconnections;
1246  opts.serverURIcount = options.hacount;
1247  }
1248 
1249  opts.ssl = &sslopts;
1250  opts.ssl->enableServerCertAuth = 0;
1251 
1252  MyLog(LOGA_DEBUG, "Connecting");
1253 
1254  rc = MQTTClient_connect(c, &opts);
1255  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1256  goto exit;
1257  rc = MQTTClient_subscribe(c, test_topic, subsqos);
1258  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1259  goto exit;
1260 
1261  singleThread_sendAndReceive(c, 0, test_topic);
1262  singleThread_sendAndReceive(c, 1, test_topic);
1263  singleThread_sendAndReceive(c, 2, test_topic);
1264 
1265  MyLog(LOGA_DEBUG, "Stopping\n");
1266 
1267  rc = MQTTClient_unsubscribe(c, test_topic);
1268  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1269  goto exit;
1270  rc = MQTTClient_disconnect(c, 0);
1271  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1272  goto exit;
1273 
1274  /* Just to make sure we can connect again */
1275  rc = MQTTClient_connect(c, &opts);
1276  if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1277  goto exit;
1278  rc = MQTTClient_disconnect(c, 0);
1279  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1280  goto exit;
1281 
1282 exit:
1283  MQTTClient_destroy(&c);
1284  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1285  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1287  return failures;
1288 }
1289 
1290 /*********************************************************************
1291 
1292 Test4_m: Accept invalid server certificates - multi threaded
1293 
1294 *********************************************************************/
1295 
1297 {
1298  char* testname = "test4_m";
1299  char* test_topic = "C client test4_m";
1300  int subsqos = 2;
1301  MQTTClient c;
1305  int rc = 0;
1306 
1307  failures = 0;
1308  MyLog(LOGA_INFO, "Starting test 4_m - accept invalid server certificates - multi-threaded");
1309  fprintf(xml, "<testcase classname=\"test3\" name=\"test 4_m\"");
1311 
1313  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1314  goto exit;
1315 
1316  opts.keepAliveInterval = 20;
1317  opts.cleansession = 1;
1318  opts.username = "testuser";
1319  opts.password = "testpassword";
1320  if (options.haconnections != NULL)
1321  {
1322  opts.serverURIs = options.haconnections;
1323  opts.serverURIcount = options.hacount;
1324  }
1325 
1326  opts.ssl = &sslopts;
1327  opts.ssl->enableServerCertAuth = 0;
1328 
1330  if (!(assert("Good rc from setCallbacks", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1331  goto exit;
1332 
1333  MyLog(LOGA_DEBUG, "Connecting");
1334 
1335  rc = MQTTClient_connect(c, &opts);
1336  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1337  goto exit;
1338  rc = MQTTClient_subscribe(c, test_topic, subsqos);
1339  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1340  goto exit;
1341 
1342  multiThread_sendAndReceive(c, 0, test_topic);
1343  multiThread_sendAndReceive(c, 1, test_topic);
1344  multiThread_sendAndReceive(c, 2, test_topic);
1345 
1346  MyLog(LOGA_DEBUG, "Stopping");
1347 
1348  rc = MQTTClient_unsubscribe(c, test_topic);
1349  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1350  goto exit;
1351  rc = MQTTClient_disconnect(c, 0);
1352  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1353  goto exit;
1354 
1355 exit:
1356  MQTTClient_destroy(&c);
1357 
1358  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1359  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1361  return failures;
1362 }
1363 
1364 /*********************************************************************
1365 
1366 Test5a: Anonymous ciphers - server auth disabled
1367 
1368 *********************************************************************/
1369 
1371 {
1372  char* testname = "test5a";
1373  char* test_topic = "C client SSL test5a";
1374  int subsqos = 2;
1375  MQTTClient c;
1379  int rc = 0;
1380 
1381  failures = 0;
1382  MyLog(LOGA_INFO, "Starting SSL test 5a - Anonymous ciphers - server authentication disabled");
1383  fprintf(xml, "<testcase classname=\"test3\" name=\"test 5a\"");
1385 
1387  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1388  goto exit;
1389 
1390  opts.keepAliveInterval = 20;
1391  opts.cleansession = 1;
1392  opts.username = "testuser";
1393  opts.password = "testpassword";
1394  if (options.haconnections != NULL)
1395  {
1396  opts.serverURIs = options.haconnections;
1397  opts.serverURIcount = options.hacount;
1398  }
1399 
1400  opts.ssl = &sslopts;
1401  opts.ssl->enabledCipherSuites = "aNULL";
1402  opts.ssl->enableServerCertAuth = 0;
1403 
1404  MyLog(LOGA_DEBUG, "Connecting");
1405 
1406  rc = MQTTClient_connect(c, &opts);
1407  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1408  goto exit;
1409  rc = MQTTClient_subscribe(c, test_topic, subsqos);
1410  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1411  goto exit;
1412 
1413  singleThread_sendAndReceive(c, 0, test_topic);
1414  singleThread_sendAndReceive(c, 1, test_topic);
1415  singleThread_sendAndReceive(c, 2, test_topic);
1416 
1417  MyLog(LOGA_DEBUG, "Stopping\n");
1418 
1419  rc = MQTTClient_unsubscribe(c, test_topic);
1420  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1421  goto exit;
1422  rc = MQTTClient_disconnect(c, 0);
1423  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1424  goto exit;
1425 
1426  /* Just to make sure we can connect again */
1427 
1428  rc = MQTTClient_connect(c, &opts);
1429  if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1430  goto exit;
1431  rc = MQTTClient_disconnect(c, 0);
1432  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1433  goto exit;
1434 
1435 exit:
1436  MQTTClient_destroy(&c);
1437  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1438  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1440  return failures;
1441 }
1442 
1443 /*********************************************************************
1444 
1445 Test5b: Anonymous ciphers - server auth enabled
1446 
1447 *********************************************************************/
1448 
1450 {
1451  char* testname = "test5b";
1452  char* test_topic = "C client SSL test5b";
1453  int subsqos = 2;
1454  MQTTClient c;
1458  int rc = 0;
1459 
1460  failures = 0;
1461  MyLog(LOGA_INFO, "Starting SSL test 5b - Anonymous ciphers - server authentication enabled");
1462  fprintf(xml, "<testcase classname=\"test3\" name=\"test 5b\"");
1464 
1466  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1467  goto exit;
1468 
1469  opts.keepAliveInterval = 20;
1470  opts.cleansession = 1;
1471  opts.username = "testuser";
1472  opts.password = "testpassword";
1473  if (options.haconnections != NULL)
1474  {
1475  opts.serverURIs = options.haconnections;
1476  opts.serverURIcount = options.hacount;
1477  }
1478 
1479  opts.ssl = &sslopts;
1480  //opts.ssl->trustStore = /*file of certificates trusted by client*/
1481  //opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
1482  //if (options.client_key_pass != NULL) opts.ssl->privateKeyPassword = options.client_key_pass;
1483  opts.ssl->enabledCipherSuites = "aNULL";
1484  opts.ssl->enableServerCertAuth = 1;
1485 
1486  MyLog(LOGA_DEBUG, "Connecting");
1487 
1488  rc = MQTTClient_connect(c, &opts);
1489  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1490  goto exit;
1491  rc = MQTTClient_subscribe(c, test_topic, subsqos);
1492  if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1493  goto exit;
1494 
1495  singleThread_sendAndReceive(c, 0, test_topic);
1496  singleThread_sendAndReceive(c, 1, test_topic);
1497  singleThread_sendAndReceive(c, 2, test_topic);
1498 
1499  MyLog(LOGA_DEBUG, "Stopping\n");
1500 
1501  rc = MQTTClient_unsubscribe(c, test_topic);
1502  if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1503  goto exit;
1504  rc = MQTTClient_disconnect(c, 0);
1505  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1506  goto exit;
1507 
1508  /* Just to make sure we can connect again */
1509  rc = MQTTClient_connect(c, &opts);
1510  if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1511  goto exit;
1512  rc = MQTTClient_disconnect(c, 0);
1513  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
1514  goto exit;
1515 
1516 exit:
1517  MQTTClient_destroy(&c);
1518  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1519  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1521  return failures;
1522 }
1523 
1524 
1525 /*********************************************************************
1526 
1527 Test5c: Anonymous ciphers - client not using anonymous ciphers
1528 
1529 *********************************************************************/
1530 
1532 {
1533  char* testname = "test5c";
1534  char* test_topic = "C client SSL test5c";
1535  int subsqos = 2;
1536  MQTTClient c;
1540  int rc = 0;
1541 
1542  failures = 0;
1543  MyLog(LOGA_INFO, "Starting SSL test 5c - Anonymous ciphers - client not using anonymous cipher");
1544  fprintf(xml, "<testcase classname=\"test3\" name=\"test 5c\"");
1546 
1548  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1549  goto exit;
1550 
1551  opts.keepAliveInterval = 20;
1552  opts.cleansession = 1;
1553  opts.username = "testuser";
1554  opts.password = "testpassword";
1555  if (options.haconnections != NULL)
1556  {
1557  opts.serverURIs = options.haconnections;
1558  opts.serverURIcount = options.hacount;
1559  }
1560 
1561  opts.ssl = &sslopts;
1562  //opts.ssl->trustStore = /*file of certificates trusted by client*/
1563  //opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
1564  //if (options.client_key_pass != NULL) opts.ssl->privateKeyPassword = options.client_key_pass;
1565  opts.ssl->enabledCipherSuites = "DEFAULT";
1566  opts.ssl->enableServerCertAuth = 0;
1567 
1568  MyLog(LOGA_DEBUG, "Connecting");
1569 
1570  rc = MQTTClient_connect(c, &opts);
1571  if (!(assert("Good rc from connect", rc == MQTTCLIENT_FAILURE, "rc was %d", rc)))
1572  goto exit;
1573 
1574 exit:
1575  MQTTClient_destroy(&c);
1576  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1577  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1579  return failures;
1580 }
1581 
1582 
1583 /*********************************************************************
1584 
1585 Test6: TLS-PSK - client and server has a common pre-shared key
1586 
1587 *********************************************************************/
1588 static unsigned int onPSKAuth(const char* hint,
1589  char* identity,
1590  unsigned int max_identity_len,
1591  unsigned char* psk,
1592  unsigned int max_psk_len,
1593  void* context)
1594 {
1595  unsigned char test_psk[] = {0x50, 0x53, 0x4B, 0x00}; /* {'P', 'S', 'K', '\0' } */
1596  MyLog(LOGA_DEBUG, "PSK auth callback");
1597 
1598  if (!(assert("Good application context in onPSKAuth", context == (void *) 42, "context was %d\n", context)))
1599  return 0;
1600 
1601  strncpy(identity, "id", max_identity_len);
1602  memcpy(psk, test_psk, sizeof(test_psk));
1603  return sizeof(test_psk);
1604 }
1605 
1606 
1607 int test6(struct Options options)
1608 {
1609  char* testname = "test6";
1610  MQTTClient c;
1614  int rc = 0;
1615 
1616  failures = 0;
1617  MyLog(LOGA_INFO, "Starting test 6 - TLS-PSK - client and server has a common pre-shared key");
1618  fprintf(xml, "<testcase classname=\"test6\" name=\"test 6\"");
1620 
1622  if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1623  goto exit;
1624 
1625  opts.keepAliveInterval = 20;
1626  opts.cleansession = 1;
1627  opts.username = "testuser";
1628  opts.password = "testpassword";
1629  if (options.haconnections != NULL)
1630  {
1631  opts.serverURIs = options.haconnections;
1632  opts.serverURIcount = options.hacount;
1633  }
1634 
1635  opts.ssl = &sslopts;
1636  opts.ssl->ssl_psk_cb = onPSKAuth;
1637  opts.ssl->ssl_psk_context = (void *) 42;
1638  opts.ssl->enabledCipherSuites = "PSK-AES128-CBC-SHA";
1639 
1640  MyLog(LOGA_DEBUG, "Connecting");
1641 
1642  rc = MQTTClient_connect(c, &opts);
1643  if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1644  goto exit;
1645 
1646  MyLog(LOGA_DEBUG, "Stopping\n");
1647 
1648  rc = MQTTClient_disconnect(c, 0);
1649  if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
1650  goto exit;
1651 exit:
1652  MQTTClient_destroy(&c);
1653  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
1654  (failures == 0) ? "passed" : "failed", testname, tests, failures);
1656  return failures;
1657 }
1658 
1659 
1660 typedef struct
1661 {
1662  char* clientID;
1663  char* username;
1664  char* password;
1665  unsigned int cleansession : 1;
1666  unsigned int connected : 1;
1667  unsigned int good : 1;
1668  unsigned int ping_outstanding : 1;
1669  unsigned int connect_state : 2;
1670  int socket;
1671  int msgID;
1672  int keepAliveInterval;
1673  int retryInterval;
1674  int maxInflightMessages;
1675  time_t lastContact;
1676  void* will;
1680  void* phandle; /* the persistence handle */
1681  MQTTClient_persistence* persistence; /* a persistence implementation */
1683 } Clients;
1684 
1685 typedef struct
1686 {
1687  char* serverURI;
1688  Clients* c;
1692  void* context;
1693 
1694  int connect_sem;
1695  int rc; /* getsockopt return code in connect */
1696  int connack_sem;
1697  int suback_sem;
1698  int unsuback_sem;
1699  void* pack;
1700 } MQTTClients;
1701 
1702 
1703 int main(int argc, char** argv)
1704 {
1705  int* numtests = &tests;
1706  int rc = 0;
1708  test2e_s /*test5a, test5b,test5c */};
1709  //MQTTClient_nameValue* info;
1710 
1711  xml = fopen("TEST-test3.xml", "w");
1712  fprintf(xml, "<testsuite name=\"test3\" tests=\"%d\">\n", (int)(ARRAY_SIZE(tests) - 1));
1713 
1714  setenv("MQTT_C_CLIENT_TRACE", "ON", 1);
1715  setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1);
1716  getopts(argc, argv);
1717  if (options.test_no == 0)
1718  { /* run all the tests */
1720  rc += tests[options.test_no](options); /* return number of failures. 0 = test succeeded */
1721  }
1722  else
1723  rc = tests[options.test_no](options); /* run just the selected test */
1724 
1725  MyLog(LOGA_INFO, "Total tests run: %d", *numtests);
1726  if (rc == 0)
1727  MyLog(LOGA_INFO, "verdict pass");
1728  else
1729  MyLog(LOGA_INFO, "verdict fail");
1730 
1731  fprintf(xml, "</testsuite>\n");
1732  fclose(xml);
1733 
1734  return rc;
1735 }
void * outboundMsgs
Definition: test3.c:1678
char * test_map[]
Definition: test3.c:109
char nocert_mutual_auth_connection[100]
Definition: test3.c:76
int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken mdt, unsigned long timeout)
Definition: MQTTClient.c:2772
time_t lastContact
Definition: test3.c:1675
enum MQTTPropertyCodes value
#define MQTTCLIENT_FAILURE
Definition: MQTTClient.h:136
char ** haconnections
Definition: test1.c:50
int MQTTClient_receive(MQTTClient handle, char **topicName, int *topicLen, MQTTClient_message **message, unsigned long timeout)
Definition: MQTTClient.c:2674
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&...args)
Definition: core.h:2081
#define MQTTCLIENT_SUCCESS
Definition: MQTTClient.h:131
char * client_private_key_file
Definition: test3.c:85
int failures
Definition: test3.c:368
int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions *options)
Definition: MQTTClient.c:1644
void MyLog(int LOGA_level, char *format,...)
Definition: test3.c:268
int MQTTClient_publish(MQTTClient handle, const char *topicName, int payloadlen, const void *payload, int qos, int retained, MQTTClient_deliveryToken *deliveryToken)
Definition: MQTTClient.c:2387
FILE * xml
Definition: test3.c:369
int MQTTClient_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)
Definition: MQTTClient.h:359
char * connection
void MQTTClient_connectionLost(void *context, char *cause)
Definition: MQTTClient.h:398
int MQTTClient_disconnect(MQTTClient handle, int timeout)
Definition: MQTTClient.c:1908
char output[3000]
Definition: test3.c:371
char * password
#define START_TIME_TYPE
Definition: test3.c:325
const char * enabledCipherSuites
Definition: MQTTClient.h:696
struct pubsub_opts opts
Definition: paho_c_pub.c:42
int multiThread_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *m)
Definition: test3.c:492
char psk_connection[100]
Definition: test3.c:79
size_t strftime(char *str, size_t count, const char *format, const std::tm *time)
Definition: chrono.h:375
#define malloc(x)
Definition: Heap.h:41
int myassert(char *filename, int lineno, char *description, int value, char *format,...)
Definition: test3.c:389
int test3b(struct Options options)
Definition: test3.c:1167
#define MQTTClient_message_initializer
Definition: MQTTClient.h:327
static char msg_buf[512]
Definition: Log.c:122
char * client_key_pass
Definition: test3.c:83
#define MQTTClient_willOptions_initializer
Definition: MQTTClient.h:639
const char * privateKey
Definition: MQTTClient.h:683
int MQTTClient_setCallbacks(MQTTClient handle, void *context, MQTTClient_connectionLost *cl, MQTTClient_messageArrived *ma, MQTTClient_deliveryComplete *dc)
Definition: MQTTClient.c:1032
int test6(struct Options options)
Definition: test3.c:1607
MQTTClient_SSLOptions * ssl
Definition: MQTTClient.h:895
constexpr size_t count()
Definition: core.h:960
int MQTTClient_publishMessage(MQTTClient handle, const char *topicName, MQTTClient_message *message, MQTTClient_deliveryToken *deliveryToken)
Definition: MQTTClient.c:2432
void write_test_result(void)
Definition: test3.c:375
int hacount
Definition: test1.c:52
#define assert(a, b, c, d)
Definition: test3.c:363
START_TIME_TYPE global_start_time
Definition: test3.c:370
unsigned int(* ssl_psk_cb)(const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u)
Definition: MQTTClient.h:738
description
Definition: setup.py:19
#define MQTTCLIENT_BAD_PROTOCOL
Definition: MQTTClient.h:185
int MQTTClient_unsubscribe(MQTTClient handle, const char *topic)
Definition: MQTTClient.c:2239
int tests
Definition: test3.c:367
char mutual_auth_connection[100]
Definition: test3.c:75
void * will
Definition: test3.c:1676
int test4_s(struct Options options)
Definition: test3.c:1219
int test1(struct Options options)
Definition: test3.c:582
#define MQTTCLIENT_NULL_PARAMETER
Definition: MQTTClient.h:156
int qos
Definition: test6.c:56
volatile int multiThread_arrivedcount
Definition: test3.c:483
int test2e_s(struct Options options)
Definition: test3.c:931
int connectOptionsVersion
Definition: test3.c:1682
void MQTTClient_freeMessage(MQTTClient_message **message)
Definition: MQTTClient.c:601
const char * keyStore
Definition: MQTTClient.h:678
char * persistenceStore
Definition: test3.c:45
void * inboundMsgs
Definition: test3.c:1677
void * MQTTClient
Definition: MQTTClient.h:246
#define ARRAY_SIZE(a)
Definition: test3.c:54
int test3a_m(struct Options options)
Definition: test3.c:1093
void MQTTClient_destroy(MQTTClient *handle)
Definition: MQTTClient.c:556
int persistence
Definition: test6.c:61
#define MQTTCLIENT_PERSISTENCE_DEFAULT
void MQTTClient_deliveryComplete(void *context, MQTTClient_deliveryToken dt)
Definition: MQTTClient.h:381
int test2b(struct Options options)
Definition: test3.c:810
START_TIME_TYPE start_clock(void)
Definition: test3.c:327
int main(int argc, char **argv)
Definition: test3.c:1703
const char * trustStore
Definition: MQTTClient.h:673
#define LOGA_INFO
Definition: test3.c:49
char server_auth_connection[100]
Definition: test3.c:77
int test5a(struct Options options)
Definition: test3.c:1370
int MQTTClient_subscribe(MQTTClient handle, const char *topic, int qos)
Definition: MQTTClient.c:2104
char * test_topic
Definition: test11.c:307
MQTTClient c
Definition: test10.c:1656
int test2c(struct Options options)
Definition: test3.c:870
dictionary context
Definition: test2.py:57
struct Options options
void MQTTClient_free(void *memory)
Definition: MQTTClient.c:612
null localtime_s(...)
Definition: chrono.h:286
#define MQTTClient_connectOptions_initializer
Definition: MQTTClient.h:953
void multiThread_sendAndReceive(MQTTClient *c, int qos, char *test_topic)
Definition: test3.c:509
int MQTTClient_deliveryToken
Definition: MQTTClient.h:257
int test5b(struct Options options)
Definition: test3.c:1449
int socket
Definition: test3.c:1670
long elapsed(START_TIME_TYPE start_time)
Definition: test3.c:352
void multiThread_deliveryComplete(void *context, MQTTClient_deliveryToken dt)
Definition: test3.c:487
A structure containing the function pointers to a persistence implementation and the context or state...
int test2a_s(struct Options options)
Definition: test3.c:644
char * username
#define MQTTClient_SSLOptions_initializer
Definition: MQTTClient.h:769
int multiThread_deliveryCompleted
Definition: test3.c:484
static unsigned int onPSKAuth(const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *context)
Definition: test3.c:1588
const char * privateKeyPassword
Definition: MQTTClient.h:686
int test3a_s(struct Options options)
Definition: test3.c:1014
volatile int connected
MQTTClient_message multiThread_pubmsg
Definition: test3.c:485
char *const * serverURIs
Definition: MQTTClient.h:913
int websockets
Definition: test3.c:88
int test5c(struct Options options)
Definition: test3.c:1531
void getopts(int argc, char **argv)
Definition: test3.c:128
enum MQTTReasonCodes rc
Definition: test10.c:1112
void usage(void)
Definition: test3.c:56
int MQTTClient_create(MQTTClient *handle, const char *serverURI, const char *clientId, int persistence_type, void *persistence_context)
Definition: MQTTClient.c:507
void singleThread_sendAndReceive(MQTTClient *c, int qos, char *test_topic)
Definition: test3.c:417
#define LOGA_DEBUG
Definition: test3.c:48
int test2a_m(struct Options options)
Definition: test3.c:728
char anon_connection[100]
Definition: test3.c:78
int test4_m(struct Options options)
Definition: test3.c:1296
char * cur_output
Definition: test3.c:372
int test_no
Definition: test1.c:54
char * server_key_file
Definition: test3.c:84
void * messageQueue
Definition: test3.c:1679
char * client_key_file
Definition: test3.c:82


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 04:02:48