示例#1
0
/* the heart of the whole keyboard interactive login */
int ssh_userauth_kbdint(SSH_SESSION *session, const char *user, const char *submethods){
    int err;
    if(session->version==1)
        return SSH_AUTH_DENIED; // no keyb-interactive for ssh1
    enter_function();
    if( !session->kbdint){
        /* first time we call. we must ask for a challenge */
        if(!user)
            if(!(user=session->options->username)){
                if(ssh_options_default_username(session->options)){
                    leave_function();
                	return SSH_AUTH_ERROR;
                } else
                    user=session->options->username;
            }
        if(ask_userauth(session)){
            leave_function();
        	return SSH_AUTH_ERROR;
        }
        err=kbdauth_init(session,user,submethods);
        if(err!=SSH_AUTH_INFO){
            leave_function();
        	return err; /* error or first try success */
        }
        err=kbdauth_info_get(session);
        if(err==SSH_AUTH_ERROR){
            kbdint_free(session->kbdint);
            session->kbdint=NULL;
        }
        leave_function();
        return err;
    }
    /* if we are at this point, it's because session->kbdint exists */
    /* it means the user has set some informations there we need to send *
     * the server. and then we need to ack the status (new questions or ok *
     * pass in */
    err=kbdauth_send(session);
    kbdint_free(session->kbdint);
    session->kbdint=NULL;
    if(err!=SSH_AUTH_INFO){
        leave_function();
    	return err;
    }
    err=kbdauth_info_get(session);
    if(err==SSH_AUTH_ERROR){
        kbdint_free(session->kbdint);
        session->kbdint=NULL;
    }
    leave_function();
    return err;
}
示例#2
0
/* unregister kbd-int callbacks and context */
void
auth2_challenge_stop(Authctxt *authctxt)
{
	/* unregister callback */
	dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
	if (authctxt->kbdintctxt != NULL) {
		kbdint_free(authctxt->kbdintctxt);
		authctxt->kbdintctxt = NULL;
	}
}
示例#3
0
/* unregister kbd-int callbacks and context */
static void
auth2_challenge_stop(Authctxt *authctxt)
{
	/* unregister callback */
	dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
	if (authctxt->method->method_data != NULL)  {
		kbdint_free((KbdintAuthctxt *) authctxt->method->method_data);
		authctxt->method->method_data = NULL;
	}
}
示例#4
0
/* unregister kbd-int callbacks and context */
void
auth2_challenge_stop(struct ssh *ssh)
{
	struct authctxt *authctxt = ssh->authctxt;
	/* unregister callback */
	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
	if (authctxt->kbdintctxt != NULL) {
		kbdint_free(authctxt->kbdintctxt);
		authctxt->kbdintctxt = NULL;
	}
}
示例#5
0
/**
 * @brief Try to authenticate through the "keyboard-interactive" method.
 *
 * @param session       The ssh session to use.
 *
 * @param user          The username to authenticate. You can specify NULL if
 *                      ssh_option_set_username() has been used. You cannot try
 *                      two different logins in a row.
 *
 * @param submethods    Undocumented. Set it to NULL.
 *
 * @returns SSH_AUTH_ERROR:   A serious error happened\n
 *          SSH_AUTH_DENIED:  Authentication failed : use another method\n
 *          SSH_AUTH_PARTIAL: You've been partially authenticated, you still
 *                            have to use another method\n
 *          SSH_AUTH_SUCCESS: Authentication success\n
 *          SSH_AUTH_INFO:    The server asked some questions. Use
 *                            ssh_userauth_kbdint_getnprompts() and such.
 *
 * @see ssh_userauth_kbdint_getnprompts()
 * @see ssh_userauth_kbdint_getname()
 * @see ssh_userauth_kbdint_getinstruction()
 * @see ssh_userauth_kbdint_getprompt()
 * @see ssh_userauth_kbdint_setanswer()
 */
int ssh_userauth_kbdint(ssh_session session, const char *user,
    const char *submethods) {
  int rc = SSH_AUTH_ERROR;

  if (session->version == 1) {
    /* No keyb-interactive for ssh1 */
    return SSH_AUTH_DENIED;
  }

  enter_function();

  if (session->kbdint == NULL) {
    /* first time we call. we must ask for a challenge */
    if (user == NULL) {
      if ((user = session->username) == NULL) {
        if (ssh_options_apply(session) < 0) {
          leave_function();
          return SSH_AUTH_ERROR;
        } else {
          user = session->username;
        }
      }
    }

    if (ask_userauth(session)) {
      leave_function();
      return SSH_AUTH_ERROR;
    }

    rc = kbdauth_init(session, user, submethods);
    if (rc != SSH_AUTH_INFO) {
      leave_function();
      return rc; /* error or first try success */
    }

    rc = kbdauth_info_get(session);
    if (rc == SSH_AUTH_ERROR) {
      kbdint_free(session->kbdint);
      session->kbdint = NULL;
    }

    leave_function();
    return rc;
  }

  /*
   * If we are at this point, it ss because session->kbdint exists.
   * It means the user has set some information there we need to send
   * the server and then we need to ack the status (new questions or ok
   * pass in).
   */
  rc = kbdauth_send(session);
  kbdint_free(session->kbdint);
  session->kbdint = NULL;

  if(rc != SSH_AUTH_INFO) {
    leave_function();
    return rc;
  }

  rc = kbdauth_info_get(session);
  if (rc == SSH_AUTH_ERROR) {
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
  }

  leave_function();
  return rc;
}
示例#6
0
static int kbdauth_info_get(ssh_session session) {
  ssh_string name; /* name of the "asking" window showed to client */
  ssh_string instruction;
  ssh_string tmp;
  uint32_t nprompts;
  uint32_t i;

  enter_function();

  name = buffer_get_ssh_string(session->in_buffer);
  instruction = buffer_get_ssh_string(session->in_buffer);
  tmp = buffer_get_ssh_string(session->in_buffer);
  buffer_get_u32(session->in_buffer, &nprompts);

  if (name == NULL || instruction == NULL || tmp == NULL) {
    string_free(name);
    string_free(instruction);
    /* tmp if empty if we got here */
    ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg");
    leave_function();
    return SSH_AUTH_ERROR;
  }
  string_free(tmp);

  if (session->kbdint == NULL) {
    session->kbdint = kbdint_new();
    if (session->kbdint == NULL) {
      ssh_set_error(session, SSH_FATAL, "Not enough space");
      string_free(name);
      string_free(instruction);

      leave_function();
      return SSH_AUTH_ERROR;
    }
  } else {
    kbdint_clean(session->kbdint);
  }

  session->kbdint->name = string_to_char(name);
  string_free(name);
  if (session->kbdint->name == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    kbdint_free(session->kbdint);
    leave_function();
    return SSH_AUTH_ERROR;
  }

  session->kbdint->instruction = string_to_char(instruction);
  string_free(instruction);
  if (session->kbdint->instruction == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
    leave_function();
    return SSH_AUTH_ERROR;
  }

  nprompts = ntohl(nprompts);
  if (nprompts > KBDINT_MAX_PROMPT) {
    ssh_set_error(session, SSH_FATAL,
        "Too much prompt asked from server: %u (0x%.4x)",
        nprompts, nprompts);
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
    leave_function();
    return SSH_AUTH_ERROR;
  }

  session->kbdint->nprompts = nprompts;
  session->kbdint->prompts = malloc(nprompts * sizeof(char *));
  if (session->kbdint->prompts == NULL) {
    session->kbdint->nprompts = 0;
    ssh_set_error(session, SSH_FATAL, "No space left");
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
    leave_function();
    return SSH_AUTH_ERROR;
  }
  memset(session->kbdint->prompts, 0, nprompts * sizeof(char *));

  session->kbdint->echo = malloc(nprompts);
  if (session->kbdint->echo == NULL) {
    session->kbdint->nprompts = 0;
    ssh_set_error(session, SSH_FATAL, "No space left");
    kbdint_free(session->kbdint);
    session->kbdint = NULL;
    leave_function();
    return SSH_AUTH_ERROR;
  }
  memset(session->kbdint->echo, 0, nprompts);

  for (i = 0; i < nprompts; i++) {
    tmp = buffer_get_ssh_string(session->in_buffer);
    buffer_get_u8(session->in_buffer, &session->kbdint->echo[i]);
    if (tmp == NULL) {
      ssh_set_error(session, SSH_FATAL, "Short INFO_REQUEST packet");
      kbdint_free(session->kbdint);
      session->kbdint = NULL;
      leave_function();
      return SSH_AUTH_ERROR;
    }
    session->kbdint->prompts[i] = string_to_char(tmp);
    string_free(tmp);
    if (session->kbdint->prompts[i] == NULL) {
      ssh_set_error(session, SSH_FATAL, "Not enough space");
      kbdint_free(session->kbdint);
      session->kbdint = NULL;
      leave_function();
      return SSH_AUTH_ERROR;
    }
  }

  leave_function();
  return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */
}