Exemple #1
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);
}
Exemple #2
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);
}