サンプルプログラムの実装


https://github.com/haruyama/ssh_client_sample/blob...

  private def userauthPassword(transportManager: TransportManager, user: String, pass: String) {

    // SSH_MSG_SERVICE_REQUEST で "ssh-userauth" サービスをクライアントからサーバに要求する
    transportManager.sendMessage(TransportMessageBuilder.buildServiceRequest("ssh-userauth"))

    // SSH_MSG_SERVICE_ACCEPT を受信する
    val serviceRequestResult = transportManager.recvMessage().asInstanceOf[ServiceAccept]

    // SSH_MSG_USERAUTH_REQUEST で "password" 認証を要求する
    transportManager.sendMessage(UserauthMessageBuilder.buildUserauthRequestPassword(user, pass))

    // SSH_MSG_USERAUTH_SUCCESS か SSH_MSG_USERAUTH_FAILURE を受信する
    val userauthResult = transportManager.recvMessage()

    userauthResult match {
      case success: UserauthSuccess =>
      case UserauthFailure(id, authentications, partialSuccess) =>
        println("Userauth failed")
        println(authentications)
        throw new RuntimeException("Uearauth failed")
    }
  }

解説

ユーザ認証の要求


クライアントはサーバに SSH_MSG_SERVICE_REQUEST メッセージで, ユーザ認証サービスを要求します.

SSH_MSG_SERVICE_REQUEST メッセージは以下の形式です.

byte      SSH_MSG_SERVICE_REQUEST
string    service name

service name の値として以下が定義されています.
  • ssh-userauth: ユーザ認証サービス
  • ssh-connection: コネクションサービス

ここではユーザ認証を要求するので, service name として ssh-userauth を指定します.

ユーザ認証要求への応答


サーバは, SSH_MSG_SERVICE_ACCEPT でサービス要求に応答します.

byte      SSH_MSG_SERVICE_ACCEPT
string    service name

パスワード認証の要求


サンプルプログラムでは, パスワード認証を要求しています. SSH_MSG_USERAUTH_REQUEST メッセージをクライアントがサーバに送ります.

パスワード認証の場合の SSH_MSG_USERAUTH_REQUEST メッセージの形式は以下です.

byte      SSH_MSG_USERAUTH_REQUEST
string    user name
string    service name
string    "password"
boolean   FALSE
string    plaintext password in ISO-10646 UTF-8 encoding [RFC3629]
  • user name : ユーザ名
  • service name: 認証成功時に次に要求するサービス名. ssh-connection を指定します.
  • plaintext password : パスワード. このメッセージの表現では暗号化しません. サーバへの送信の前にSSHのパケットに格納される際, メッセージは暗号化されます.

認証の成功/失敗の通知


サーバはクライアントに, 認証が成功したか失敗したかを通知します.

これ以上の認証が必要ない場合, サーバは SSH_MSG_USERAUTH_SUCCESS を返します.

byte      SSH_MSG_USERAUTH_SUCCESS


認証が失敗した場合や認証は成功したがさらに追加の認証が必要な場合は, SSH_MSG_USERAUTH_FAILURE を返します.

byte         SSH_MSG_USERAUTH_FAILURE
name-list    authentications that can continue
boolean      partial success
  • authentications ... : 認証を続行できる認証法のリスト
  • partial success : 対応する認証が成功したかどうか. 複数の認証法での認証が必要な場合に利用します.

サンプルプログラムの実行例


間違ったパスワードを入力すると, SSH_MSG_USERAUTH_FAILURE の authentications that can continue を表示します.

> run localhost 22 test wrong_password ls
...
Userauth failed
SSHNameList(WrappedArray(publickey, password))
...

補足


サンプルプログラムでは, ssh-userauth サービスの要求とその応答後すぐにパスワード認証を要求しています.

OpenSSH のクライアントは, SSH_MSG_USERAUTH_REQUEST で "none" 認証法を要求し,SSH_MSG_USERAUTH_FAILURE の authentications can continue で返される認証法を取得しています. そして, クライアントとサーバの設定に応じて認証法を試します.

メンバーのみ編集できます