/// <summary> /// Attempts an authentication using the public/private key pair. /// </summary> /// <param name="authentication"></param> /// <param name="serviceName"></param> public void Authenticate(AuthenticationProtocol authentication, String serviceName) { ByteBuffer baw = new ByteBuffer(); baw.WriteBinaryString(authentication.SessionIdentifier); baw.Write(AuthenticationProtocol.SSH_MSG_USERAUTH_REQUEST); baw.WriteString(Username); baw.WriteString(serviceName); baw.WriteString("publickey"); baw.WriteBool(!VerifyOnly); byte[] encoded; String algorithm; baw.WriteString(algorithm = KeyPair.PublicKey.Algorithm); baw.WriteBinaryString(encoded = KeyPair.PublicKey.GetEncoded()); ByteBuffer baw2 = new ByteBuffer(); // Generate the authentication request baw2.WriteBool(!VerifyOnly); baw2.WriteString(algorithm); baw2.WriteBinaryString(encoded); if (!VerifyOnly) { byte[] signature = KeyPair.PrivateKey.Sign(baw.ToByteArray()); // Format the signature correctly ByteBuffer sig = new ByteBuffer(); sig.WriteString(algorithm); sig.WriteBinaryString(signature); baw2.WriteBinaryString(sig.ToByteArray()); } authentication.SendRequest(Username, serviceName, "publickey", baw2.ToByteArray()); SSHPacket packet = authentication.ReadMessage(); if (packet.MessageID == SSH_MSG_USERAUTH_PK_OK) { throw new SSH2AuthenticationResult(AuthenticationResult.PUBLIC_KEY_ACCEPTABLE, ""); } else { authentication.connection.transport.Disconnect("Unexpected message " + packet.MessageID + " received", DisconnectionReason.PROTOCOL_ERROR); throw new SSHException("Unexpected message " + packet.MessageID + " received", SSHException.PROTOCOL_VIOLATION); } }
/// <summary> /// Attempts to authenticate the user using their password. /// </summary> /// <param name="authentication"></param> /// <param name="servicename"></param> public void Authenticate(AuthenticationProtocol authentication, String servicename) { try { if (Username == null || Password == null) { throw new SSHException("Username or password not set!", SSHException.BAD_API_USAGE); } if (passwordChangeRequired && newpassword == null) { throw new SSHException("You must set a new password!", SSHException.BAD_API_USAGE); } ByteBuffer buf = new ByteBuffer(); buf.WriteBool(passwordChangeRequired); buf.WriteString(Password); if (passwordChangeRequired) { buf.WriteString(newpassword); } authentication.SendRequest(Username, servicename, "password", buf.ToByteArray()); // We need to read the response since we may have password change. SSHPacket packet = authentication.ReadMessage(); if (packet.MessageID != SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) { authentication.transport.Disconnect( "Unexpected message received", DisconnectionReason.PROTOCOL_ERROR); throw new SSHException( "Unexpected response from Authentication Protocol", SSHException.PROTOCOL_VIOLATION); } passwordChangeRequired = true; throw new SSH2AuthenticationResult(AuthenticationResult.FAILED, ""); } catch (IOException ex) { throw new SSHException(ex.Message, SSHException.INTERNAL_ERROR); } }
/// <summary> /// Start the authentication request. /// </summary> /// <param name="authentication">The authentication protocol instance.</param> /// <param name="serviceName">The name of the service to start upon a successful authentication.</param> public void Authenticate(AuthenticationProtocol authentication, String serviceName) { if (InteractivePrompt == null) { throw new SSHException("An interactive prompt event must be set!", SSHException.BAD_API_USAGE); } ByteBuffer baw = new ByteBuffer(); baw.WriteString(""); baw.WriteString(""); authentication.SendRequest(username, serviceName, "keyboard-interactive", baw.ToByteArray()); while (true) { SSHPacket msg = authentication.ReadMessage(); if (msg.MessageID != SSH_MSG_USERAUTH_INFO_REQUEST) { authentication.transport.Disconnect("Unexpected authentication message received!", DisconnectionReason.PROTOCOL_ERROR); throw new SSHException("Unexpected authentication message received!", SSHException.PROTOCOL_VIOLATION); } String name = msg.ReadString(); String instruction = msg.ReadString(); String langtag = msg.ReadString(); int num = (int)msg.ReadInt(); String prompt; bool echo; KBIPrompt[] prompts = new KBIPrompt[num]; for (int i = 0; i < num; i++) { prompt = msg.ReadString(); echo = (msg.ReadBool()); prompts[i] = new KBIPrompt(prompt, echo); } if (InteractivePrompt(name, instruction, prompts)) { msg = authentication.transport.GetSSHPacket(true); msg.WriteByte(SSH_MSG_USERAUTH_INFO_RESPONSE); msg.WriteInt(prompts.Length); for (int i = 0; i < prompts.Length; i++) { msg.WriteString(prompts[i].Response); } authentication.transport.SendMessage(msg); } else { throw new SSHException("User cancelled during authentication", SSHException.USER_CANCELATION); } } }