Example #1
0
int
main (int argc, char *argv[])
{
  int exit_code = EXIT_FAILURE;
  char challenge[BUFSIZ];
  size_t chal_len;
  char *response = NULL;
  u2fh_devs *devs = NULL;
  u2fh_cmdflags flags = 0;
  u2fh_rc rc;

  rc = u2fh_global_init (1);
  if (rc != U2FH_OK)
    {
      fprintf (stderr, "error: u2fh_global_init (%d): %s\n", rc,
	       u2fh_strerror (rc));
      exit (EXIT_FAILURE);
    }

  rc = u2fh_devs_init (&devs);
  if (rc != U2FH_OK)
    {
      fprintf (stderr, "error: u2fh_devs_init (%d): %s\n", rc,
	       u2fh_strerror (rc));
      goto done;
    }

  int num_devices = 0;
  rc = u2fh_devs_discover (devs, &num_devices);
  if (rc != U2FH_OK)
    {
      fprintf (stderr, "error: u2fh_devs_discover (%d): %s\n", rc,
	       u2fh_strerror (rc));
      goto done;
    }

  int i;
  for (i = 0; i <= num_devices; i++) {
    fprintf (stderr, "pinging device %d = %d\n", i,
             ping_device(devs, i));
  }

  exit_code = EXIT_SUCCESS;

done:
  u2fh_devs_done (devs);
  u2fh_global_done ();

  exit (exit_code);
}
Example #2
0
int
main (void)
{
  u2fh_devs *devs;
  int rc;

  if (strcmp (U2FH_VERSION_STRING, u2fh_check_version (NULL)) != 0)
    {
      printf ("version mismatch %s != %s\n", U2FH_VERSION_STRING,
	      u2fh_check_version (NULL));
      return EXIT_FAILURE;
    }

  if (u2fh_check_version (U2FH_VERSION_STRING) == NULL)
    {
      printf ("version NULL?\n");
      return EXIT_FAILURE;
    }

  if (u2fh_check_version ("99.99.99") != NULL)
    {
      printf ("version not NULL?\n");
      return EXIT_FAILURE;
    }

  printf ("u2fh version: header %s library %s\n",
	  U2FH_VERSION_STRING, u2fh_check_version (NULL));

  rc = u2fh_global_init (0);
  if (rc != U2FH_OK)
    {
      printf ("u2fh_global_init rc %d\n", rc);
      return EXIT_FAILURE;
    }

  if (u2fh_strerror (U2FH_OK) == NULL)
    {
      printf ("u2fh_strerror NULL\n");
      return EXIT_FAILURE;
    }

  {
    const char *s;
    s = u2fh_strerror_name (U2FH_OK);
    if (s == NULL || strcmp (s, "U2FH_OK") != 0)
      {
	printf ("u2fh_strerror_name %s\n", s);
	return EXIT_FAILURE;
      }
  }

  rc = u2fh_devs_init (&devs);
  if (rc != U2FH_OK)
    {
      printf ("u2fh_devs_init %d\n", rc);
      return EXIT_FAILURE;
    }

  rc = u2fh_devs_discover (devs, NULL);
  if (rc == U2FH_OK)
    {
      printf ("Found U2F device\n");
      /* XXX: register+authenticate */
    }
  else if (rc != U2FH_NO_U2F_DEVICE)
    {
      printf ("u2fh_devs_discover %d\n", rc);
      return EXIT_FAILURE;
    }

  u2fh_devs_done (devs);

  u2fh_global_done ();

  return EXIT_SUCCESS;
}
Example #3
0
int
main(int argc, char *argv[]) {
  int exit_code = EXIT_FAILURE;
  char *response = NULL;
  u2fh_devs *devs = NULL;
  u2fh_rc rc;
  OP *action = NULL;
  char device_state = 'u';
  u2fh_rc device_disappeared_rc = U2FH_OK;
  char *device_disappeared_msg = NULL;

  reset_quit_timer();

  rc = u2fh_global_init(0);
  if (rc != U2FH_OK) {
    report_error(rc, "global_init");
    exit(1);
  }

  rc = u2fh_devs_init(&devs);
  if (rc != U2FH_OK) {
    report_error(rc, "devs_init");
    goto done;
  }

  while (1) {
    int need_sleep = 1;
    rc = u2fh_devs_discover(devs, NULL);
    if (device_disappeared_rc != U2FH_OK && rc != U2FH_NO_U2F_DEVICE) {
      report_error(device_disappeared_rc, device_disappeared_msg);

      free(response);
      free(action);
      action = NULL;
    }
    if (rc != U2FH_OK && rc != U2FH_NO_U2F_DEVICE) {
      report_error(rc, "devs_discover");
      goto done;
    }

    if (rc == U2FH_OK && device_state == 'm') {
      printf("j");
      fflush(stdout);
      device_state = 'p';
      need_sleep = 0;
    }

    if (rc == U2FH_NO_U2F_DEVICE && device_state != 'm') {
      printf("i");
      fflush(stdout);
      device_state = 'm';
    }

    device_disappeared_rc = U2FH_OK;

    if (!action) {
      action = read_action(1000);
      if (action)
        reset_quit_timer();
    } else if (need_sleep)
      sleep(1);

    if (action && (rc == U2FH_OK || action->op == 'e')) {
      if (action->op == 'e')
        goto done;
      else if (action->op == 'r' || action->op == 's') {
        int requests_count = 0;
        do {
          int i = 0;
          do {
            if (action->op == 'r') {
              rc = u2fh_register(devs, action->challenges[i], action->domain,
                                 &response,
                                 U2FH_REQUEST_USER_PRESENCE | U2FH_REQUEST_NON_BLOCKING);
            } else {
              rc = u2fh_authenticate(devs, action->challenges[i], action->domain,
                                     &response,
                                     U2FH_REQUEST_USER_PRESENCE | U2FH_REQUEST_NON_BLOCKING);
            }
            i++;
          } while (action->challenges[i] && rc == U2FH_AUTHENTICATOR_ERROR);

          if (rc == U2FH_NOT_FINISHED_ERROR) {
            if (device_state != 'b') {
              printf("b");
              fflush(stdout);
              device_state = 'b';
            }
            sleep(1);
          } else
            break;
        } while (requests_count++ < 15);

        if (requests_count >= 15) {
          report_error(U2FH_TIMEOUT_ERROR, NULL);
        } else if (rc != U2FH_OK) {
          device_disappeared_rc = rc;
          device_disappeared_msg = action->op == 'r' ? "register" : "authenticate";
          continue;
        } else {
          printf("r%04lx%s", strlen(response), response);
          fflush(stdout);
        }

        free(response);
        free(action);
        action = NULL;
      } else {
        report_error(U2FH_TRANSPORT_ERROR, NULL);
        goto done;
      }
    }
  }

  done:
  u2fh_devs_done(devs);
  u2fh_global_done();

  exit(exit_code);
}
Example #4
0
int main(int argc, char *argv[])
{
  int exit_code = EXIT_FAILURE;
  struct gengetopt_args_info args_info;
  char buf[BUFSIZE];
  char *p;
  char *response;
  u2fs_ctx_t *ctx;
  u2fs_reg_res_t *reg_result;
  u2fs_rc s_rc;
  u2fh_rc h_rc;
  char *origin = NULL;
  char *appid = NULL;
  char *user = NULL;
  const char *kh = NULL;
  const char *pk = NULL;
  u2fh_devs *devs = NULL;
  unsigned i;
  unsigned max_index = 0;


  if (cmdline_parser(argc, argv, &args_info) != 0)
    exit(EXIT_FAILURE);

  if (args_info.help_given) {
    cmdline_parser_print_help();
    printf
        ("\nReport bugs at <https://github.com/Yubico/libu2f-server>.\n");
    exit(EXIT_SUCCESS);
  }

  s_rc = u2fs_global_init(args_info.debug_flag ? U2FS_DEBUG : 0);
  if (s_rc != U2FS_OK) {
    fprintf(stderr, "error: u2fs_global_init (%d): %s\n", s_rc,
            u2fs_strerror(s_rc));
    exit(EXIT_FAILURE);
  }

  s_rc = u2fs_init(&ctx);
  if (s_rc != U2FS_OK) {
    fprintf(stderr, "error: u2fs_init (%d): %s\n", s_rc,
            u2fs_strerror(s_rc));
    exit(EXIT_FAILURE);
  }

  if (args_info.origin_given)
    origin = args_info.origin_arg;
  else {
    if (!strcpy(buf, PAM_PREFIX))
      fprintf(stderr, "strcpy failed\n");
    if (gethostname(buf + strlen(PAM_PREFIX), BUFSIZE - strlen(PAM_PREFIX))
        == -1) {
      perror("gethostname");
      exit(EXIT_FAILURE);
    }
    origin = buf;
  }

  s_rc = u2fs_set_origin(ctx, origin);
  if (s_rc != U2FS_OK) {
    printf("error: u2fs_set_origin (%d): %s\n", s_rc, u2fs_strerror(s_rc));
    exit(EXIT_FAILURE);
  }

  if (args_info.appid_given)
    appid = args_info.appid_arg;
  else {
    if (args_info.origin_given) {
      if (!strcpy(buf, PAM_PREFIX))
        fprintf(stderr, "strcpy failed\n");
      if (gethostname
          (buf + strlen(PAM_PREFIX), BUFSIZE - strlen(PAM_PREFIX)) == -1) {
        perror("gethostname");
        exit(EXIT_FAILURE);
      }
    }
    appid = buf;
  }

  s_rc = u2fs_set_appid(ctx, appid);
  if (s_rc != U2FS_OK) {
    fprintf(stderr, "error: u2fs_set_appid (%d): %s\n", s_rc,
            u2fs_strerror(s_rc));
    exit(EXIT_FAILURE);
  }

  if (args_info.username_given)
    user = args_info.username_arg;
  else {
    user = getlogin();
    if (!user) {
      perror("getlogin");
      exit(EXIT_FAILURE);
    }
  }

  if (u2fh_global_init(args_info.debug_flag ? U2FS_DEBUG : 0) != U2FH_OK
      || u2fh_devs_init(&devs) != U2FH_OK) {
    fprintf(stderr, "Unable to initialize libu2f-host");
    exit(EXIT_FAILURE);
  }

  h_rc = u2fh_devs_discover(devs, &max_index);
  if (h_rc != U2FH_OK && h_rc != U2FH_NO_U2F_DEVICE) {
    fprintf(stderr, "Unable to discover device(s), %s (%d)",
            u2fh_strerror(h_rc), h_rc);
    exit(EXIT_FAILURE);
  }

  if (h_rc == U2FH_NO_U2F_DEVICE) {
    for (i = 0; i < TIMEOUT; i += FREQUENCY) {
      fprintf(stderr,
              "\rNo U2F device available, please insert one now, you have %2d seconds",
              TIMEOUT - i);
      fflush(stderr);
      sleep(FREQUENCY);

      h_rc = u2fh_devs_discover(devs, &max_index);
      if (h_rc == U2FH_OK) {
        fprintf(stderr, "\nDevice found!\n");
        break;
      }

      if (h_rc != U2FH_NO_U2F_DEVICE) {
        fprintf(stderr, "\nUnable to discover device(s), %s (%d)",
                u2fh_strerror(h_rc), h_rc);
        exit(EXIT_FAILURE);
      }
    }
  }

  if (h_rc != U2FH_OK) {
    fprintf(stderr,
            "\rNo device found. Aborting.                                         \n");
    exit(EXIT_FAILURE);
  }

  s_rc = u2fs_registration_challenge(ctx, &p);
  if (s_rc != U2FS_OK) {
    fprintf(stderr, "Unable to generate registration challenge, %s (%d)",
            u2fs_strerror(s_rc), s_rc);
    exit(EXIT_FAILURE);
  }

  h_rc =
      u2fh_register(devs, p, origin, &response,
                    U2FH_REQUEST_USER_PRESENCE);
  if (s_rc != U2FS_OK) {
    fprintf(stderr, "Unable to generate registration challenge, %s (%d)",
            u2fs_strerror(s_rc), s_rc);
    exit(EXIT_FAILURE);
  }

  s_rc = u2fs_registration_verify(ctx, response, &reg_result);
  if (s_rc != U2FS_OK) {
    fprintf(stderr, "error: (%d) %s\n", s_rc, u2fs_strerror(s_rc));
    exit(EXIT_FAILURE);
  }

  kh = u2fs_get_registration_keyHandle(reg_result);
  if (!kh) {
    fprintf(stderr, "Unable to extract keyHandle: (%d) %s\n", s_rc,
            u2fs_strerror(s_rc));
    exit(EXIT_FAILURE);
  }

  pk = u2fs_get_registration_publicKey(reg_result);
  if (!pk) {
    fprintf(stderr, "Unable to extract public key: (%d) %s\n", s_rc,
            u2fs_strerror(s_rc));
    exit(EXIT_FAILURE);
  }

  if (!args_info.nouser_given)
    printf("%s", user);

  printf(":%s,", kh);
  for (i = 0; i < U2FS_PUBLIC_KEY_LEN; i++) {
    printf("%02x", pk[i] & 0xFF);
  }

  exit_code = EXIT_SUCCESS;

  u2fs_done(ctx);
  u2fs_global_done();
  exit(exit_code);
}
Example #5
0
int do_authentication(const cfg_t *cfg, const device_t *devices,
                      const unsigned n_devs, pam_handle_t *pamh) {
  u2fs_ctx_t *ctx;
  u2fs_auth_res_t *auth_result;
  u2fs_rc s_rc;
  u2fh_rc h_rc;
  u2fh_devs *devs = NULL;
  char *response = NULL;
  char *buf;
  int retval = -2;
  int cued = 0;
  unsigned i = 0;
  unsigned max_index = 0;
  unsigned max_index_prev = 0;

  h_rc = u2fh_global_init(cfg->debug ? U2FH_DEBUG : 0);
  if (h_rc != U2FH_OK) {
    D(cfg->debug_file, "Unable to initialize libu2f-host: %s", u2fh_strerror(h_rc));
    return retval;
  }
  h_rc = u2fh_devs_init(&devs);
  if (h_rc != U2FH_OK) {
    D(cfg->debug_file, "Unable to initialize libu2f-host device handles: %s",
       u2fh_strerror(h_rc));
    return retval;
  }

  if ((h_rc = u2fh_devs_discover(devs, &max_index)) != U2FH_OK) {
    if (cfg->debug)
      D(cfg->debug_file, "Unable to discover device(s), %s", u2fh_strerror(h_rc));
    return retval;
  }
  max_index_prev = max_index;

  if (cfg->debug)
    D(cfg->debug_file, "Device max index is %u", max_index);

  s_rc = u2fs_global_init(cfg->debug ? U2FS_DEBUG : 0);
  if (s_rc != U2FS_OK) {
    D(cfg->debug_file, "Unable to initialize libu2f-server: %s", u2fs_strerror(s_rc));
    return retval;
  }
  s_rc = u2fs_init(&ctx);
  if (s_rc != U2FS_OK) {
    D(cfg->debug_file, "Unable to initialize libu2f-server context: %s", u2fs_strerror(s_rc));
    return retval;
  }

  if ((s_rc = u2fs_set_origin(ctx, cfg->origin)) != U2FS_OK) {
    if (cfg->debug)
      D(cfg->debug_file, "Unable to set origin: %s", u2fs_strerror(s_rc));
    return retval;
  }

  if ((s_rc = u2fs_set_appid(ctx, cfg->appid)) != U2FS_OK) {
    if (cfg->debug)
      D(cfg->debug_file, "Unable to set appid: %s", u2fs_strerror(s_rc));
    return retval;
  }

  if (cfg->nodetect && cfg->debug)
    D(cfg->debug_file, "nodetect option specified, suitable key detection will be skipped");

  i = 0;
  while (i < n_devs) {

    retval = -2;

    if (cfg->debug)
      D(cfg->debug_file, "Attempting authentication with device number %d", i + 1);

    if ((s_rc = u2fs_set_keyHandle(ctx, devices[i].keyHandle)) != U2FS_OK) {
      if (cfg->debug)
        D(cfg->debug_file, "Unable to set keyHandle: %s", u2fs_strerror(s_rc));
      return retval;
    }

    if ((s_rc = u2fs_set_publicKey(ctx, devices[i].publicKey)) != U2FS_OK) {
      if (cfg->debug)
        D(cfg->debug_file, "Unable to set publicKey %s", u2fs_strerror(s_rc));
      return retval;
    }

    if ((s_rc = u2fs_authentication_challenge(ctx, &buf)) != U2FS_OK) {
      if (cfg->debug)
        D(cfg->debug_file, "Unable to produce authentication challenge: %s",
           u2fs_strerror(s_rc));
      free(buf);
      buf = NULL;
      return retval;
    }

    if (cfg->debug)
      D(cfg->debug_file, "Challenge: %s", buf);

    if (cfg->nodetect || (h_rc = u2fh_authenticate(devs, buf, cfg->origin, &response, 0)) == U2FH_OK ) {

      if (cfg->manual == 0 && cfg->cue && !cued) {
        cued = 1;
        converse(pamh, PAM_TEXT_INFO, DEFAULT_CUE);
      }

      retval = -1;

      if ((h_rc = u2fh_authenticate(devs, buf, cfg->origin, &response, U2FH_REQUEST_USER_PRESENCE)) ==
          U2FH_OK) {
        if (cfg->debug)
          D(cfg->debug_file, "Response: %s", response);

        s_rc = u2fs_authentication_verify(ctx, response, &auth_result);
        u2fs_free_auth_res(auth_result);
        free(response);
        response = NULL;
        if (s_rc == U2FS_OK) {
          retval = 1;

          free(buf);
          buf = NULL;
          break;
        }
      } else {
        if (cfg->debug)
          D(cfg->debug_file, "Unable to communicate to the device, %s", u2fh_strerror(h_rc));
      }
    } else {
      if (cfg->debug)
        D(cfg->debug_file, "Device for this keyhandle is not present.");
    }
    free(buf);
    buf = NULL;

    i++;

    if (u2fh_devs_discover(devs, &max_index) != U2FH_OK) {
      if (cfg->debug)
        D(cfg->debug_file, "Unable to discover devices");
      return retval;
    }

    if (max_index > max_index_prev) {
      if (cfg->debug)
        D(cfg->debug_file, "Devices max_index has changed: %u (was %u). Starting over",
           max_index, max_index_prev);
      max_index_prev = max_index;
      i = 0;
    }
  }

  u2fh_devs_done(devs);
  u2fh_global_done();

  u2fs_done(ctx);
  u2fs_global_done();

  return retval;
}
Example #6
0
int
main (int argc, char *argv[])
{
  int exit_code = EXIT_FAILURE;
  struct gengetopt_args_info args_info;
  char challenge[BUFSIZ];
  size_t chal_len;
  char response[2048];
  size_t response_len = sizeof (response);
  u2fh_devs *devs = NULL;
  u2fh_cmdflags flags = 0;
  u2fh_rc rc;

  if (cmdline_parser (argc, argv, &args_info) != 0)
    exit (EXIT_FAILURE);

  if (args_info.help_given)
    {
      cmdline_parser_print_help ();
      printf ("\nReport bugs at <https://github.com/Yubico/libu2f-host>.\n");
      exit (EXIT_SUCCESS);
    }

  chal_len = fread (challenge, 1, sizeof (challenge), stdin);
  if (!feof (stdin) || ferror (stdin))
    {
      perror ("read");
      exit (EXIT_FAILURE);
    }

  rc = u2fh_global_init (args_info.debug_flag ? U2FH_DEBUG : 0);
  if (rc != U2FH_OK)
    {
      fprintf (stderr, "error: u2fh_global_init (%d): %s\n", rc,
	       u2fh_strerror (rc));
      exit (EXIT_FAILURE);
    }

  rc = u2fh_devs_init (&devs);
  if (rc != U2FH_OK)
    {
      fprintf (stderr, "error: u2fh_devs_init (%d): %s\n", rc,
	       u2fh_strerror (rc));
      goto done;
    }

  rc = u2fh_devs_discover (devs, NULL);
  if (rc != U2FH_OK)
    {
      fprintf (stderr, "error: u2fh_devs_discover (%d): %s\n", rc,
	       u2fh_strerror (rc));
      goto done;
    }

  switch (args_info.action_arg)
    {
    case action_arg_register:
    case action_arg_authenticate:
      if (args_info.origin_arg == NULL)
	{
	  fprintf (stderr, "error: origin URL empty, use -o to specify it\n");
	  exit (EXIT_FAILURE);
	}

      if (args_info.action_arg == action_arg_register)
	{
	  rc = u2fh_register2 (devs, challenge, args_info.origin_arg,
			       response, &response_len,
			       args_info.touch_flag ? 0 :
			       U2FH_REQUEST_USER_PRESENCE);
	}
      else
	{
	  rc = u2fh_authenticate2 (devs, challenge, args_info.origin_arg,
				   response, &response_len,
				   args_info.touch_flag ? 0 :
				   U2FH_REQUEST_USER_PRESENCE);
	}
      break;
    case action_arg_sendrecv:
      {
	uint8_t command;
	unsigned char out[2048];
	size_t outlen = sizeof (out);
	if (args_info.command_arg == NULL)
	  {
	    fprintf (stderr, "error: empty sendrecv command.\n");
	    exit (EXIT_FAILURE);
	  }
	sscanf (args_info.command_arg, "%hhx", &command);
	rc =
	  u2fh_sendrecv (devs, 0, command, challenge, chal_len - 1, out,
			 &outlen);
      }
      break;
    case action__NULL:
    default:
      fprintf (stderr, "error: unknown action.\n");
      goto done;
    }
  if (rc != U2FH_OK)
    {
      fprintf (stderr, "error (%d): %s\n", rc, u2fh_strerror (rc));
      goto done;
    }

  if (strlen (response))
    {
      printf ("%s\n", response);
    }

  exit_code = EXIT_SUCCESS;

done:
  u2fh_devs_done (devs);
  u2fh_global_done ();

  exit (exit_code);
}