/*

  authc-passwd.c

  Authors:
        Tatu Ylonen <ylo@ssh.com>
        Markku-Juhani Saarinen <mjos@ssh.com>
        Timo J. Rinne <tri@ssh.com>
        Sami Lehtinen <sjl@ssh.com>

  Copyright (C) 1997-2000 SSH Communications Security Corp, Helsinki, Finland
  All rights reserved.

  Password authentication, client side.
  
*/

#include "ssh2includes.h"
#include "sshencode.h"
#include "sshauth.h"
#include "readpass.h"
#include "sshclient.h"
#include "sshconfig.h"

#define SSH_DEBUG_MODULE "Ssh2AuthPasswdClient"

#ifdef SSH_NEW_READPASS_ELOOP
typedef struct AuthPasswdCompletionCtxRec
{
  
} *AuthPasswdCompletionCtx;
#endif /* SSH_NEW_READPASS_ELOOP */

/* Password authentication, client-side. */

void ssh_client_auth_passwd(SshAuthClientOperation op,
                            const char *user,
                            unsigned int packet_type,
                            SshBuffer packet_in,
                            const unsigned char *session_id,
                            size_t session_id_len,
                            void **state_placeholder,
                            SshAuthClientCompletionProc completion,
                            void *completion_context,
                            void *method_context)
{
  char *password;
  SshBuffer b;
#ifndef SSH_WIN_CLIENT
  char buf[100];
#endif /* SSH_WIN_CLIENT */
  SshConfig clientconf = ((SshClient)method_context)->config;
#ifdef SSH_NEW_READPASS_ELOOP
  AuthPasswdCompletionCtx auth_completion_ctx;
#endif /* SSH_NEW_READPASS_ELOOP */
  
  SSH_DEBUG(6, ("auth_password op = %d  user = %s", op, user));
  
  switch (op)
    {
    case SSH_AUTH_CLIENT_OP_START:
#ifdef SSH_NEW_READPASS_ELOOP
      auth_completion_ctx = ;
#endif /* SSH_NEW_READPASS_ELOOP */
      
      if (!clientconf->try_empty_password)
        {
          if (clientconf->password)
            {
              password = clientconf->password;
              clientconf->password = NULL;
            }
          else
            password = NULL;
#ifndef SSH_WIN_CLIENT
          if (clientconf->password_prompt == NULL)
            snprintf(buf, sizeof(buf), "%s's password: ", user);
          else
            snprintf(buf, sizeof(buf), "%s", clientconf->password_prompt);
          if (!clientconf->batch_mode)
            {
              SSH_TRACE(2, ("Starting password query..."));          
#ifndef SSH_NEW_READPASS_ELOOP
              password = ssh_read_passphrase(buf, FALSE);
#else /* SSH_NEW_READPASS_ELOOP */
              ssh_readpass_eloop();
              return;
#endif /* SSH_NEW_READPASS_ELOOP */
            }
          else
            {
              SSH_TRACE(2, ("In Batchmode, so we're not asking the "        \
                            "user for password."));
              password = NULL;
            }
      
#endif /* !SSH_WIN_CLIENT */
          if (password == NULL)
            {
              (*completion)(SSH_AUTH_CLIENT_CANCEL, user, NULL,
                            completion_context);
              break;
            }
        }
      else
        {
          password = "";
          clientconf->try_empty_password = FALSE;
        }
      
      b = ssh_buffer_allocate();
      ssh_encode_buffer(b,
                        SSH_FORMAT_BOOLEAN, FALSE,
                        SSH_FORMAT_UINT32_STR, password, strlen(password),
                        SSH_FORMAT_END);
      ssh_xfree(password);
      (*completion)(SSH_AUTH_CLIENT_SEND, user, b, completion_context);
      ssh_buffer_free(b);
      break;
      
    case SSH_AUTH_CLIENT_OP_START_NONINTERACTIVE:
      (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
      break;
      
    case SSH_AUTH_CLIENT_OP_CONTINUE:
      /* XXX add support for changing passwords here. */
      (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
      break;
      
    case SSH_AUTH_CLIENT_OP_ABORT:
      *state_placeholder = NULL;
      
      break;
      
    default:
      ssh_debug("ssh_client_auth_password: unknown op %d", (int)op);
      (*completion)(SSH_AUTH_CLIENT_FAIL, user, NULL, completion_context);
      break;
    }
}

