Esempio n. 1
0
int rlm_yubikey_ykclient_init(CONF_SECTION *conf, rlm_yubikey_t *inst)
{
	ykclient_rc status;
	CONF_SECTION *servers;

	char prefix[100];

	int count = 0;

	if (!inst->client_id) {
		ERROR("rlm_yubikey (%s): validation.client_id must be set (to a valid id) when validation is enabled",
		      inst->name);

		return -1;
	}

	if (!inst->api_key || !*inst->api_key || is_zero(inst->api_key)) {
		ERROR("rlm_yubikey (%s): validation.api_key must be set (to a valid key) when validation is enabled",
		      inst->name);

		return -1;
	}

	DEBUG("rlm_yubikey (%s): Initialising ykclient", inst->name);

	status = ykclient_global_init();
	if (status != YKCLIENT_OK) {
yk_error:
		ERROR("rlm_yubikey (%s): %s", ykclient_strerror(status), inst->name);

		return -1;
	}

	status = ykclient_init(&inst->ykc);
	if (status != YKCLIENT_OK) {
		goto yk_error;
	}

	servers = cf_section_sub_find(conf, "servers");
	if (servers) {
		CONF_PAIR *uri, *first;
		/*
		 *	If there were no uris configured we just use the default
		 *	ykclient uris which point to the yubico servers.
		 */
		first = uri = cf_pair_find(servers, "uri");
		if (!uri) {
			goto init;
		}

		while (uri) {
			count++;
			uri = cf_pair_find_next(servers, uri, "uri");
		}
		inst->uris = talloc_zero_array(inst, char const *, count);

		uri = first;
		count = 0;
		while (uri) {
			inst->uris[count++] = cf_pair_value(uri);
			uri = cf_pair_find_next(servers, uri, "uri");
		}
		if (count) {
			status = ykclient_set_url_templates(inst->ykc, count, inst->uris);
			if (status != YKCLIENT_OK) {
				goto yk_error;
			}
		}
	}

init:
	status = ykclient_set_client_b64(inst->ykc, inst->client_id, inst->api_key);
	if (status != YKCLIENT_OK) {
		ERROR("rlm_yubikey (%s): Failed setting API credentials: %s", ykclient_strerror(status), inst->name);

		return -1;
	}

	snprintf(prefix, sizeof(prefix), "rlm_yubikey (%s)", inst->name);
	inst->pool = module_connection_pool_init(conf, inst, mod_conn_create, NULL, prefix);
	if (!inst->pool) {
		ykclient_done(&inst->ykc);

		return -1;
	}

	return 0;
}
Esempio n. 2
0
int
main (void)
{
  int client_id = 1851;
  char client_key[] = {
    0xa0, 0x15, 0x5b, 0x36, 0xde, 0xc8, 0x65, 0xe8, 0x59, 0x19,
    0x1f, 0x7d, 0xae, 0xfa, 0xbc, 0x77, 0xa4, 0x59, 0xd4, 0x33
  };
  char *client_hexkey = "a0155b36dec865e859191f7daefabc77a459d433";
  char *client_b64key = "oBVbNt7IZehZGR99rvq8d6RZ1DM=";
  ykclient_t *ykc;
  int ret;

  curl_global_init(CURL_GLOBAL_ALL);

  TEST(("init self"));
  ret = ykclient_init (&ykc);
  printf ("ykclient_init (%d): %s\n", ret, ykclient_strerror (ret));
  assert(ret == YKCLIENT_OK);

  TEST(("null client_id, expect REPLAYED_OTP"));
  ykclient_set_verify_signature(ykc, 0);
  ykclient_set_client (ykc, client_id, 0, NULL);

#ifndef TEST_WITHOUT_INTERNET
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert(ret == YKCLIENT_REPLAYED_OTP);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("client_id set(20), correct client_key, expect REPLAYED_OTP"));
  ykclient_set_client (ykc, client_id, 20, client_key);

#ifndef TEST_WITHOUT_INTERNET
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_REPLAYED_OTP);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("wrong client_id set(10), correct client_key, expect BAD_SIGNATURE"));
  ykclient_set_client (ykc, client_id, 10, client_key);

#ifndef TEST_WITHOUT_INTERNET
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_BAD_SIGNATURE);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("invalid client_id set(a), correct client_key, expect HEX_DECODE_ERROR"));
  ret = ykclient_set_client_hex (ykc, client_id, "a");
  printf ("ykclient_set_client_hex (%d): %s\n", ret, ykclient_strerror (ret));
  assert (ret == YKCLIENT_HEX_DECODE_ERROR);

  TEST(("invalid client_id set(xx), correct client_key, expect HEX_DECODE_ERROR"));
  ret = ykclient_set_client_hex (ykc, client_id, "xx");
  printf ("ykclient_set_client_hex (%d): %s\n", ret, ykclient_strerror (ret));
  assert (ret == YKCLIENT_HEX_DECODE_ERROR);

  TEST(("hex client_id set, correct client_key, expect OK"));
  ret = ykclient_set_client_hex (ykc, client_id, client_hexkey);
  printf ("ykclient_set_client_hex (%d): %s\n", ret, ykclient_strerror (ret));
  assert (ret == YKCLIENT_OK);

#ifndef TEST_WITHOUT_INTERNET
  TEST(("validation request, expect REPLAYED_OTP"));
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_REPLAYED_OTP);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("set deadbeef client_id, expect OK"));
  ret = ykclient_set_client_hex (ykc, client_id, "deadbeef");
  printf ("ykclient_set_client_hex (%d): %s\n", ret, ykclient_strerror (ret));
  assert (ret == YKCLIENT_OK);

#ifndef TEST_WITHOUT_INTERNET
  TEST(("validation request, expect BAD_SIGNATURE"));
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_BAD_SIGNATURE);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("b64 set deadbeef client_id, expect OK"));
  ret = ykclient_set_client_b64 (ykc, client_id, "deadbeef");
  printf ("ykclient_set_client_b64 (%d): %s\n", ret, ykclient_strerror (ret));
  assert (ret == YKCLIENT_OK);

#ifndef TEST_WITHOUT_INTERNET
  /* When the server dislikes our signature, it will sign the response with a
     NULL key, so the API call will fail with BAD_SERVER_SIGNATURE even though
     the server returned status=BAD_SIGNATURE.
  */
  TEST(("validation request, expect BAD_SERVER_SIGNATURE"));
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_BAD_SERVER_SIGNATURE);
#else
  printf ("Test SKIPPED\n");
#endif

#ifndef TEST_WITHOUT_INTERNET
  /* Now, disable our checking of the servers signature to get the error
     the server returned (server will use 00000 as key when signing this
     error response).
  */
  TEST(("validation request, expect BAD_SIGNATURE"));
  ykclient_set_verify_signature (ykc, 0);
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_BAD_SIGNATURE);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("b64 set client_b64key, expect OK"));
  ret = ykclient_set_client_b64 (ykc, client_id, client_b64key);
  printf ("ykclient_set_client_b64 (%d): %s\n", ret, ykclient_strerror (ret));
  assert (ret == YKCLIENT_OK);

#ifndef TEST_WITHOUT_INTERNET
  TEST(("validation request, expect REPLAYED_OTP"));
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_REPLAYED_OTP);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("set WS 2.0 URL template"));
  /* Set one URL and run tests with that. */
  ykclient_set_url_template
    (ykc, "http://api.yubico.com/wsapi/2.0/verify?id=%d&otp=%s");

#ifndef TEST_WITHOUT_INTERNET
  TEST(("validation request, expect REPLAYED_OTP"));
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("yubikey_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_REPLAYED_OTP);
#else
  printf ("Test SKIPPED\n");
#endif

  ykclient_set_verify_signature(ykc, 1);

  TEST(("validation request with valid signature, expect REPLAYED_OTP"));
  // Check a genuine signature.
  ykclient_set_client (ykc, client_id, 20, client_key);
#ifndef TEST_WITHOUT_INTERNET
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_REPLAYED_OTP);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("validation request with bad key, expect YKCLIENT_BAD_SERVER_SIGNATURE"));
  // Check a genuine signature with a truncated key.
  ykclient_set_client (ykc, client_id, 10, client_key);
#ifndef TEST_WITHOUT_INTERNET
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_BAD_SERVER_SIGNATURE);
#else
  printf ("Test SKIPPED\n");
#endif

  TEST(("Set and use several V2.0 URLs"));
  const char *templates[] = {
    "http://api.yubico.com/wsapi/2.0/verify?id=%d&otp=%s",
    "http://api2.yubico.com/wsapi/2.0/verify?id=%d&otp=%s",
    "http://api3.yubico.com/wsapi/2.0/verify?id=%d&otp=%s",
    "http://api4.yubico.com/wsapi/2.0/verify?id=%d&otp=%s",
    "http://api5.yubico.com/wsapi/2.0/verify?id=%d&otp=%s",
  };
  ykclient_set_url_templates(ykc, 5, templates);
  ykclient_set_client (ykc, client_id, 20, client_key);
#ifndef TEST_WITHOUT_INTERNET
  ret = ykclient_request (ykc, "dteffujehknhfjbrjnlnldnhcujvddbikngjrtgh");
  printf ("ykclient_request (%d): %s\n", ret, ykclient_strerror (ret));
  printf ("used url: %s\n", ykclient_get_last_url (ykc));
  assert (ret == YKCLIENT_REPLAYED_OTP);
#else
  printf ("Test SKIPPED\n");
#endif

  ykclient_done (&ykc);

  TEST(("strerror 0"));
  printf ("strerror(0): %s\n", ykclient_strerror (0));
  ret = strcmp(ykclient_strerror (0), "Success"); assert (ret == 0);

  TEST(("strerror BAD_OTP"));
  printf ("strerror(BAD_OTP): %s\n", ykclient_strerror (YKCLIENT_BAD_OTP));
  ret = strcmp(ykclient_strerror (YKCLIENT_BAD_OTP), "Yubikey OTP was bad (BAD_OTP)"); assert (ret == 0);

  test_v1_validation(client_id, client_b64key);

  test_base64();

  test_hmac();

  printf ("All tests passed\n");

  curl_global_cleanup();

  return 0;
}