예제 #1
0
파일: torture_auth.c 프로젝트: Paxxi/libssh
static void torture_auth_kbdint(void **state) {
    struct torture_state *s = *state;
    ssh_session session = s->ssh.session;
    int rc;

    rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_BOB);
    assert_int_equal(rc, SSH_OK);

    rc = ssh_connect(session);
    assert_int_equal(rc, SSH_OK);

    rc = ssh_userauth_none(session,NULL);
    /* This request should return a SSH_REQUEST_DENIED error */
    if (rc == SSH_ERROR) {
        assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
    }
    rc = ssh_userauth_list(session, NULL);
    assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE);

    rc = ssh_userauth_kbdint(session, NULL, NULL);
    assert_int_equal(rc, SSH_AUTH_INFO);
    assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 1);

    rc = ssh_userauth_kbdint_setanswer(session, 0, TORTURE_SSH_USER_BOB_PASSWORD);
    assert_false(rc < 0);

    rc = ssh_userauth_kbdint(session, NULL, NULL);
    /* Sometimes, SSH server send an empty query at the end of exchange */
    if(rc == SSH_AUTH_INFO) {
        assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 0);
        rc = ssh_userauth_kbdint(session, NULL, NULL);
    }
    assert_int_equal(rc, SSH_AUTH_SUCCESS);
}
예제 #2
0
static void torture_auth_kbdint_nonblocking(void **state) {
    ssh_session session = *state;
    char *user = getenv("TORTURE_USER");
    char *password = getenv("TORTURE_PASSWORD");
    int rc;

    if (user == NULL) {
        print_message("*** Please set the environment variable TORTURE_USER"
                      " to enable this test!!\n");
        return;
    }

    if (password == NULL) {
        print_message("*** Please set the environment variable "
                      "TORTURE_PASSWORD to enable this test!!\n");
        return;
    }

    rc = ssh_options_set(session, SSH_OPTIONS_USER, user);
    assert_true(rc == SSH_OK);

    rc = ssh_connect(session);
    assert_true(rc == SSH_OK);

    ssh_set_blocking(session,0);
    do {
      rc = ssh_userauth_none(session, NULL);
    } while (rc == SSH_AUTH_AGAIN);

    /* This request should return a SSH_REQUEST_DENIED error */
    if (rc == SSH_ERROR) {
        assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
    }
    rc = ssh_userauth_list(session, NULL);
    assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE);

    do {
        rc = ssh_userauth_kbdint(session, NULL, NULL);
    } while (rc == SSH_AUTH_AGAIN);
    assert_true(rc == SSH_AUTH_INFO);
    assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 1);
    do {
        rc = ssh_userauth_kbdint_setanswer(session, 0, password);
    } while (rc == SSH_AUTH_AGAIN);
    assert_false(rc < 0);

    do {
        rc = ssh_userauth_kbdint(session, NULL, NULL);
    } while (rc == SSH_AUTH_AGAIN);
    /* Sometimes, SSH server send an empty query at the end of exchange */
    if(rc == SSH_AUTH_INFO) {
        assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 0);
        do {
            rc = ssh_userauth_kbdint(session, NULL, NULL);
        } while (rc == SSH_AUTH_AGAIN);
    }
    assert_true(rc == SSH_AUTH_SUCCESS);
}
예제 #3
0
/**
 * Authenticate in the SSH server with password with interactive mode
 * @param   QString password      the password to use for connect in the SSH server (password or passphrase when you use private key)
 * @return  bool                  true if it's ok, false else
 */
bool Kssh::authenticatePasswordInteractive(QString password)
{
    int auth, nb_prompt;
    QString name;

    auth = ssh_userauth_kbdint(this->m_session, NULL, NULL);

    while (auth == SSH_AUTH_INFO) {
        // enter in the interactive mode
        nb_prompt = ssh_userauth_kbdint_getnprompts(this->m_session);
        for (int i = 0; i < nb_prompt; i++) {
            name = QString(ssh_userauth_kbdint_getprompt(this->m_session, i, NULL));
            if (name == "Password: "******"Authenticated denied with this method : ") + QString(ssh_get_error(this->m_session)));
        return false;
    } else if (auth == SSH_AUTH_ERROR) {
        Klog::error(QString("Fatal error in authenticated with password interactive : ") + QString(ssh_get_error(this->m_session)));
        return false;
    }

    return false;
}
예제 #4
0
int auth_kbdint(SSH_SESSION *session){
    int err=ssh_userauth_kbdint(session,NULL,NULL);
    char *name,*instruction,*prompt,*ptr;
    char buffer[128];
    int i,n;
    char echo;
    while (err==SSH_AUTH_INFO){
        name=ssh_userauth_kbdint_getname(session);
        instruction=ssh_userauth_kbdint_getinstruction(session);
        n=ssh_userauth_kbdint_getnprompts(session);
        if(strlen(name)>0)
            printf("%s\n",name);
        if(strlen(instruction)>0)
            printf("%s\n",instruction);
        for(i=0;i<n;++i){
            prompt=ssh_userauth_kbdint_getprompt(session,i,&echo);
            if(echo){
                printf("%s",prompt);
                fgets(buffer,sizeof(buffer),stdin);
                buffer[sizeof(buffer)-1]=0;
                if((ptr=strchr(buffer,'\n')))
                    *ptr=0;
                ssh_userauth_kbdint_setanswer(session,i,buffer);
                memset(buffer,0,strlen(buffer));
            } else {
                ptr=getpass(prompt);
                ssh_userauth_kbdint_setanswer(session,i,ptr);
            }
        }
        err=ssh_userauth_kbdint(session,NULL,NULL);
    }
    return err;
}
예제 #5
0
int authenticate_kbdint(ssh_session session, const char *password) {
    int err;
    err = ssh_userauth_kbdint(session, NULL, NULL);
    while (err == SSH_AUTH_INFO) {
        const char *instruction;
        const char *name;
        char buffer[128];
        int i, n;
        name = ssh_userauth_kbdint_getname(session);
        instruction = ssh_userauth_kbdint_getinstruction(session);
        n = ssh_userauth_kbdint_getnprompts(session);
        if (name && strlen(name) > 0) {
            printf("%s\n", name);
        }
        if (instruction && strlen(instruction) > 0) {
            printf("%s\n", instruction);
        }
        for (i = 0; i < n; i++) {
            const char *answer;
            const char *prompt;
            char echo;
            prompt = ssh_userauth_kbdint_getprompt(session, i, &echo);
            if (prompt == NULL) {
                break;
            }
            if (echo) {
                char *p;
                printf("%s", prompt);
                if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
                    return SSH_AUTH_ERROR;
                }
                buffer[sizeof(buffer) - 1] = '\0';
                if ((p = strchr(buffer, '\n'))) {
                    *p = '\0';
                }
                if (ssh_userauth_kbdint_setanswer(session, i, buffer) < 0) {
                    return SSH_AUTH_ERROR;
                }
                memset(buffer, 0, strlen(buffer));
            } else {
                if (password && strstr(prompt, "Password:")) {
                    answer = password;
                } else {
                    buffer[0] = '\0';
                    if (ssh_getpass(prompt, buffer, sizeof(buffer), 0, 0) < 0) {
                        return SSH_AUTH_ERROR;
                    }
                    answer = buffer;
                }
                if (ssh_userauth_kbdint_setanswer(session, i, answer) < 0) {
                    return SSH_AUTH_ERROR;
                }
            }
        }
        err=ssh_userauth_kbdint(session,NULL,NULL);
    }
    return err;
}
예제 #6
0
static int auth_kbdint(ssh_session session, const char *user,
    const char *passwd) {
  const char *name = NULL;
  const char *instruction = NULL;
  const char *prompt = NULL;
  char buffer[256] = {0};
  int err = SSH_AUTH_ERROR;
  int rc;

  err = ssh_userauth_kbdint(session, user, NULL);
  while (err == SSH_AUTH_INFO) {
    int n = 0;
    int i = 0;

    name = ssh_userauth_kbdint_getname(session);
    instruction = ssh_userauth_kbdint_getinstruction(session);
    n = ssh_userauth_kbdint_getnprompts(session);

    if (strlen(name) > 0) {
      printf("%s\n", name);
    }

    if (strlen(instruction) > 0) {
      printf("%s\n", instruction);
    }

    for (i = 0; i < n; ++i) {
      char echo;

      prompt = ssh_userauth_kbdint_getprompt(session, i, &echo);
      if (echo) {
        (*_authcb) (prompt, buffer, sizeof(buffer), 1, 0, NULL);
        rc = ssh_userauth_kbdint_setanswer(session, i, buffer);
        if (rc < 0) {
          return SSH_AUTH_ERROR;
        }
        ZERO_STRUCT(buffer);
      } else {
        if (passwd != NULL) {
          rc = ssh_userauth_kbdint_setanswer(session, i, passwd);
          if (rc < 0) {
            return SSH_AUTH_ERROR;
          }
        } else {
          (*_authcb) ("Password:", buffer, sizeof(buffer), 0, 0, NULL);
          rc = ssh_userauth_kbdint_setanswer(session, i, buffer);
          if (rc < 0) {
            return SSH_AUTH_ERROR;
          }
          ZERO_STRUCT(buffer);
        }
      }
    }
    err = ssh_userauth_kbdint(session, user, NULL);
  }

  return err;
}
예제 #7
0
파일: ssh_cmd.c 프로젝트: casualuser/yafc
static int authenticate_kbdint(ssh_session session)
{
  int rc = ssh_userauth_kbdint(session, NULL, NULL);
  while (rc == SSH_AUTH_INFO)
  {
    const char* name = ssh_userauth_kbdint_getname(session);
    const char* instruction = ssh_userauth_kbdint_getinstruction(session);
    int nprompts = ssh_userauth_kbdint_getnprompts(session);

    if (strlen(name) > 0)
      printf("%s\n", name);
    if (strlen(instruction) > 0)
      printf("%s\n", instruction);
    for (int iprompt = 0; iprompt < nprompts; iprompt++)
    {
      const char* prompt = NULL;
      char echo;

      prompt = ssh_userauth_kbdint_getprompt(session, iprompt, &echo);
      if (echo)
      {
        char buffer[128], *ptr;

        printf("%s", prompt);
        if (fgets(buffer, sizeof(buffer), stdin) == NULL)
          return SSH_AUTH_ERROR;
        buffer[sizeof(buffer) - 1] = '\0';
        if ((ptr = strchr(buffer, '\n')) != NULL)
          *ptr = '\0';
        if (ssh_userauth_kbdint_setanswer(session, iprompt, buffer) < 0)
          return SSH_AUTH_ERROR;
        memset(buffer, 0, strlen(buffer));
      }
      else
      {
        if (!ftp->getpass_hook)
          return SSH_AUTH_ERROR;

        char* pw = ftp->getpass_hook(prompt);
        if (!pw)
          return SSH_AUTH_ERROR;

        rc = ssh_userauth_kbdint_setanswer(session, iprompt, pw);
        memset(pw, 0, strlen(pw));
        free(pw);
        if (rc < 0)
          return SSH_AUTH_ERROR;
      }
    }
    rc = ssh_userauth_kbdint(session, NULL, NULL);
  }
  return rc;
}
예제 #8
0
파일: torture.c 프로젝트: MachalkA/libssh
static int _torture_auth_kbdint(ssh_session session,
                               const char *password) {
    const char *prompt;
    char echo;
    int err;

    if (session == NULL || password == NULL) {
        return SSH_AUTH_ERROR;
    }

    err = ssh_userauth_kbdint(session, NULL, NULL);
    if (err == SSH_AUTH_ERROR) {
        return err;
    }

    if (ssh_userauth_kbdint_getnprompts(session) != 1) {
        return SSH_AUTH_ERROR;
    }

    prompt = ssh_userauth_kbdint_getprompt(session, 0, &echo);
    if (prompt == NULL) {
        return SSH_AUTH_ERROR;
    }

    if (ssh_userauth_kbdint_setanswer(session, 0, password) < 0) {
        return SSH_AUTH_ERROR;
    }
    err = ssh_userauth_kbdint(session, NULL, NULL);
    if (err == SSH_AUTH_INFO) {
        if (ssh_userauth_kbdint_getnprompts(session) != 0) {
            return SSH_AUTH_ERROR;
        }
        err = ssh_userauth_kbdint(session, NULL, NULL);
    }

    return err;
}
예제 #9
0
int KBIntDialog::Create(HWND hParent, ssh_session session) {
	m_session = NULL;
	m_nrPrompt = 0;
	if (!session)
		return -1;

	m_session = session;
	m_nrPrompt = ssh_userauth_kbdint_getnprompts(m_session);
	if (m_nrPrompt == 0)	//nothing to answer, don't show dialog
		return 0;
	if (m_nrPrompt > MAXPROMPT)
		return -1;		//unable to show that many prompts

	return Dialog::Create(hParent, true, NULL);
}
예제 #10
0
bool clSSH::LoginInteractiveKBD(bool throwExc) throw(clException)
{
    if(!m_session) {
        THROW_OR_FALSE("NULL SSH session");
    }

    int rc;
    rc = ssh_userauth_kbdint(m_session, NULL, NULL);
    if(rc == SSH_AUTH_INFO) {
        while(rc == SSH_AUTH_INFO) {
            const char* name, *instruction;
            int nprompts, iprompt;
            name = ssh_userauth_kbdint_getname(m_session);
            instruction = ssh_userauth_kbdint_getinstruction(m_session);
            nprompts = ssh_userauth_kbdint_getnprompts(m_session);
            wxUnusedVar(name);
            wxUnusedVar(instruction);
            for(iprompt = 0; iprompt < nprompts; iprompt++) {
                const char* prompt;
                char echo;
                prompt = ssh_userauth_kbdint_getprompt(m_session, iprompt, &echo);
                if(echo) {
                    wxString answer = ::wxGetTextFromUser(prompt, "SSH");
                    if(answer.IsEmpty()) {
                        THROW_OR_FALSE(wxString() << "Login error: " << ssh_get_error(m_session));
                    }
                    if(ssh_userauth_kbdint_setanswer(m_session, iprompt, answer.mb_str(wxConvUTF8).data()) < 0) {
                        THROW_OR_FALSE(wxString() << "Login error: " << ssh_get_error(m_session));
                    }
                } else {
                    if(ssh_userauth_kbdint_setanswer(m_session, iprompt, GetPassword().mb_str(wxConvUTF8).data()) < 0) {
                        THROW_OR_FALSE(wxString() << "Login error: " << ssh_get_error(m_session));
                    }
                }
            }
            rc = ssh_userauth_kbdint(m_session, NULL, NULL);
        }
        return true; // success
    }
    THROW_OR_FALSE("Interactive Keyboard is not enabled for this server");
    return false;
}
예제 #11
0
파일: sshclient.cpp 프로젝트: aopui/gnash
int
SSHClient::authKbdint(ssh_session session)
{
//    GNASH_REPORT_FUNCTION;
    int err = ssh_userauth_kbdint(session, NULL, NULL);
    char *name,*instruction,*prompt,*ptr;
    char buffer[128];
    int i,n;
    char echo;
    while (err == SSH_AUTH_INFO){
        name = const_cast<char *>(ssh_userauth_kbdint_getname(session));
        instruction = const_cast<char *>(ssh_userauth_kbdint_getinstruction(session));
        n=ssh_userauth_kbdint_getnprompts(session);
        if(strlen(name)>0)
            log_debug(name);
        if(strlen(instruction)>0)
            log_debug(instruction);
        for(i=0; i<n; ++i){
            prompt = const_cast<char *>(ssh_userauth_kbdint_getprompt(session, i, &echo));
            if(echo){
                log_debug(prompt);
                fgets(buffer,sizeof(buffer),stdin);
                buffer[sizeof(buffer)-1]=0;
                if((ptr=strchr(buffer,'\n')))
                    *ptr=0;
                if (ssh_userauth_kbdint_setanswer(session, i, buffer) < 0) {
                  return SSH_AUTH_ERROR;
                }
                memset(buffer,0,strlen(buffer));
            } else {
                ptr=getpass(prompt);
                if (ssh_userauth_kbdint_setanswer(session, i, ptr) < 0) {
                  return SSH_AUTH_ERROR;
                }
            }
        }
        err=ssh_userauth_kbdint(session, NULL, NULL);
    }

    return err;
}
예제 #12
0
static gint
remmina_ssh_auth_password (RemminaSSH *ssh)
{
	gint ret;
	gint authlist;
	gint n;
	gint i;

	ret = SSH_AUTH_ERROR;
	if (ssh->authenticated) return 1;
	if (ssh->password == NULL) return -1;

	authlist = ssh_userauth_list (ssh->session, NULL);
	if (authlist & SSH_AUTH_METHOD_INTERACTIVE)
	{
		while ((ret = ssh_userauth_kbdint (ssh->session, NULL, NULL)) == SSH_AUTH_INFO)
		{
			n = ssh_userauth_kbdint_getnprompts (ssh->session);
			for (i = 0; i < n; i++)
			{
				ssh_userauth_kbdint_setanswer(ssh->session, i, ssh->password);
			}
		}
	}
	if (ret != SSH_AUTH_SUCCESS && authlist & SSH_AUTH_METHOD_PASSWORD)
	{
		ret = ssh_userauth_password (ssh->session, NULL, ssh->password);
	}
	if (ret != SSH_AUTH_SUCCESS)
	{
		remmina_ssh_set_error (ssh, _("SSH password authentication failed: %s"));
		return 0;
	}

	ssh->authenticated = TRUE;
	return 1;
}
예제 #13
0
int authenticate_kbdint(ssh_session session, const char *password) 
{
	int err;
	const char *instruction;
        const char *name; 
        int i, n;
	const char *answer;
	const char *prompt;
	char echo;

	err = ssh_userauth_kbdint(session, NULL, NULL);
	while (err == SSH_AUTH_INFO) 
	{

		name = ssh_userauth_kbdint_getname(session);
		instruction = ssh_userauth_kbdint_getinstruction(session);
		n = ssh_userauth_kbdint_getnprompts(session);

		for (i = 0; i < n; i++) 
		{
			prompt=ssh_userauth_kbdint_getprompt(session,i,&echo);
			if(prompt==NULL) break;
			if (password && strstr(prompt, "Password:")) 
			{
				answer = password;
				err = ssh_userauth_kbdint_setanswer(session, i, answer);
			}
			if (err < 0) 
			{
				return SSH_AUTH_ERROR;
			}
		}
		err=ssh_userauth_kbdint(session,NULL,NULL);
	}
	return err;
}
예제 #14
0
파일: hydra-ssh.c 프로젝트: dummy3k/c-hydra
int start_ssh(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp) {
  char *empty = "";
  char *login, *pass, keep_login[300];
  int auth_state = 0, rc = 0, i = 0;

  if (strlen(login = hydra_get_next_login()) == 0)
    login = empty;
  if (strlen(pass = hydra_get_next_password()) == 0)
    pass = empty;

  if (new_session) {
    if (session) {
      ssh_disconnect(session);
      ssh_finalize();
      ssh_free(session);
    }

    session = ssh_new();
    ssh_options_set(session, SSH_OPTIONS_PORT, &port);
    ssh_options_set(session, SSH_OPTIONS_HOST, hydra_address2string(ip));
    ssh_options_set(session, SSH_OPTIONS_USER, login);
    ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none");
    ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none");
    if (ssh_connect(session) != 0) {
      //if the connection was drop, trying to reconnect
      if (verbose)
        hydra_report(stderr, "Error: could not connect to target port %d\n", port);
      return 1;
    }

    if ((rc = ssh_userauth_none(session, NULL)) == SSH_AUTH_ERROR) {
      return 3;
    } else if (rc == SSH_AUTH_SUCCESS) {
      hydra_report_found_host(port, ip, "ssh", fp);
      hydra_completed_pair_found();
      if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
        return 2;
      else
        return 1;
    }
  } else
    new_session = 1;

  auth_state = ssh_auth_list(session);
  if ((auth_state & SSH_AUTH_METHOD_PASSWORD) > 0) {
    auth_state = ssh_userauth_password(session, NULL, pass);
  } else if ((auth_state & SSH_AUTH_METHOD_INTERACTIVE) > 0) {
    auth_state = ssh_userauth_kbdint(session, NULL, NULL);
    while (auth_state == SSH_AUTH_INFO) {
      rc = ssh_userauth_kbdint_getnprompts(session);
      for (i = 0; i < rc; i++)
        ssh_userauth_kbdint_setanswer(session, i, pass);
      auth_state = ssh_userauth_kbdint(session, NULL, NULL);
    }
  } else {
    return 4;
  }

  if (auth_state == SSH_AUTH_ERROR) {
    new_session = 1;
    return 1;
  }

  if (auth_state == SSH_AUTH_SUCCESS || auth_state == SSH_AUTH_PARTIAL) {
    hydra_report_found_host(port, ip, "ssh", fp);
    hydra_completed_pair_found();
    if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
      return 2;
    return 1;
  } else {
    strncpy(keep_login, login, sizeof(keep_login) - 1);
    keep_login[sizeof(keep_login) - 1] = '\0';
    hydra_completed_pair();
    if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
      return 2;
    login = hydra_get_next_login();
    if (strcmp(login, keep_login) == 0)
      new_session = 0;
    return 1;
  }

  /* not reached */
  return 1;
}
예제 #15
0
int FSSftp::CheckSession( int* err, FSCInfo* info )
{
	if ( sshSession ) { return 0; }

	try
	{
		sshSession = ssh_new();

		if ( !sshSession ) { throw int( SSH_INTERROR_X3 ); }

		if ( ssh_options_set( sshSession, SSH_OPTIONS_HOST, unicode_to_utf8( _operParam.server.Data() ).ptr() ) )
		{
			throw int( SSH_INTERROR_X3 );
		}

		int port = _operParam.port;

		if ( ssh_options_set( sshSession, SSH_OPTIONS_PORT, &port ) )
		{
			throw int( SSH_INTERROR_X3 );
		}


		FSString userName = "";

		if ( _operParam.user.Data()[0] )
		{
			userName = _operParam.user.Data();
		}
		else
		{
			char* ret = getenv( "LOGNAME" );

			if ( ret )
			{
				userName = FSString( sys_charset_id, ret );
				_operParam.user = userName.GetUnicode();

				MutexLock infoLock( &infoMutex );
				_infoParam.user = userName.GetUnicode();
			}
		};

		if ( ssh_options_set( sshSession, SSH_OPTIONS_USER, ( char* )userName.Get( _operParam.charset ) ) ) //есть сомнения, что надо все таки в utf8
		{
			throw int( SSH_INTERROR_X3 );
		}

		if ( ssh_connect( sshSession ) != SSH_OK )
		{
			throw int( SSH_INTERROR_CONNECT );
		}


		int method = ssh_userauth_list( sshSession, 0 );

		int ret;


		static unicode_t userSymbol = '@';

		if ( method & SSH_AUTH_METHOD_PASSWORD )
		{
			FSPromptData data;
			data.visible = false;
			data.prompt = utf8_to_unicode( "Password:"******"SFTP_" ).ptr(),
			        carray_cat<unicode_t>( userName.GetUnicode(), &userSymbol, _operParam.server.Data() ).ptr(),
			        &data, 1 ) ) { throw int( SSH_INTERROR_STOPPED ); }

			ret = ssh_userauth_password( sshSession,
			                             ( char* )FSString( _operParam.user.Data() ).Get( _operParam.charset ),
			                             ( char* )FSString( data.prompt.Data() ).Get( _operParam.charset ) );
		}

		if ( ret != SSH_AUTH_SUCCESS &&
		     ( method & SSH_AUTH_METHOD_INTERACTIVE ) != 0 )
		{
			while ( true )
			{
				ret = ssh_userauth_kbdint( sshSession, 0, 0 );

				if ( ret != SSH_AUTH_INFO ) { break; }

				const char* instruction = ssh_userauth_kbdint_getinstruction( sshSession );

				if ( !instruction ) { instruction = ""; }

				int n = ssh_userauth_kbdint_getnprompts( sshSession );

				if ( n <= 0 ) { continue; }

				std::vector<FSPromptData> pData( n );
				int i;

				for ( i = 0; i < n; i++ )
				{
					char echo;
					const char* prompt = ssh_userauth_kbdint_getprompt( sshSession, i, &echo );

					if ( !prompt ) { break; }

					pData[i].visible = echo != 0;
					pData[i].prompt = utf8_to_unicode( prompt ).ptr();
				}

				if ( !info ) { throw int( SSH_INTERROR_AUTH ); }

				if ( !info->Prompt(
				        utf8_to_unicode( "SFTP" ).ptr(),
				        carray_cat<unicode_t>( userName.GetUnicode(), &userSymbol, _operParam.server.Data() ).ptr(),
				        pData.ptr(), n ) ) { throw int( SSH_INTERROR_STOPPED ); }

				for ( i = 0; i < n; i++ )
				{
					if ( ssh_userauth_kbdint_setanswer( sshSession, i, ( char* )FSString( pData[i].prompt.Data() ).Get( _operParam.charset ) ) < 0 )
					{
						throw int( SSH_INTERROR_AUTH );
					}
				}
			}
		}

		if ( ret != SSH_AUTH_SUCCESS )
		{
			if ( ret == SSH_AUTH_PARTIAL )
			{
				throw int( SSH_INTERROR_UNSUPPORTED_AUTH );
			}
			else
			{
				throw int( SSH_INTERROR_AUTH );
			}
		}

		sftpSession = sftp_new( sshSession );

		if ( !sftpSession ) { throw int( SSH_INTERROR_FATAL ); }

		if ( sftp_init( sftpSession ) != SSH_OK ) { throw int( SSH_INTERROR_FATAL ); }

	}
	catch ( int e )
	{
		if ( err ) { *err = e; }

		if ( sftpSession ) { sftp_free( sftpSession ); }

		if ( sshSession ) { ssh_free( sshSession ); }

		sshSession = 0;
		sftpSession = 0;
		return ( e == SSH_INTERROR_STOPPED ) ? -2 : -1;
	}

	return 0;
}