/// <exception cref="System.Exception"></exception>
		public override bool Start(Session session)
		{
			base.Start(session);
			ArrayList identities = session.jsch.GetIdentityRepository().GetIdentities();
			byte[] passphrase = null;
			byte[] _username = null;
			int command;
			lock (identities)
			{
				if (identities.Count <= 0)
				{
					return false;
				}
				_username = Util.Str2byte(username);
				for (int i = 0; i < identities.Count; i++)
				{
					if (session.auth_failures >= session.max_auth_tries)
					{
						return false;
					}
					Identity identity = (Identity)(identities[i]);
					byte[] pubkeyblob = identity.GetPublicKeyBlob();
					//System.err.println("UserAuthPublicKey: "+identity+" "+pubkeyblob);
					if (pubkeyblob != null)
					{
						// send
						// byte      SSH_MSG_USERAUTH_REQUEST(50)
						// string    user name
						// string    service name ("ssh-connection")
						// string    "publickey"
						// boolen    FALSE
						// string    plaintext password (ISO-10646 UTF-8)
						packet.Reset();
						buf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_REQUEST));
						buf.PutString(_username);
						buf.PutString(Util.Str2byte("ssh-connection"));
						buf.PutString(Util.Str2byte("publickey"));
						buf.PutByte(unchecked((byte)0));
						buf.PutString(Util.Str2byte(identity.GetAlgName()));
						buf.PutString(pubkeyblob);
						session.Write(packet);
						while (true)
						{
							buf = session.Read(buf);
							command = buf.GetCommand() & unchecked((int)(0xff));
							if (command == SSH_MSG_USERAUTH_PK_OK)
							{
								break;
							}
							else
							{
								if (command == SSH_MSG_USERAUTH_FAILURE)
								{
									break;
								}
								else
								{
									if (command == SSH_MSG_USERAUTH_BANNER)
									{
										buf.GetInt();
										buf.GetByte();
										buf.GetByte();
										byte[] _message = buf.GetString();
										byte[] lang = buf.GetString();
										string message = Util.Byte2str(_message);
										if (userinfo != null)
										{
											userinfo.ShowMessage(message);
										}
										goto loop1_continue;
									}
									else
									{
										//System.err.println("USERAUTH fail ("+command+")");
										//throw new JSchException("USERAUTH fail ("+command+")");
										break;
									}
								}
							}
loop1_continue: ;
						}
loop1_break: ;
						if (command != SSH_MSG_USERAUTH_PK_OK)
						{
							continue;
						}
					}
					//System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted());
					int count = 5;
					while (true)
					{
						if ((identity.IsEncrypted() && passphrase == null))
						{
							if (userinfo == null)
							{
								throw new JSchException("USERAUTH fail");
							}
							if (identity.IsEncrypted() && !userinfo.PromptPassphrase("Passphrase for " + identity
								.GetName()))
							{
								throw new JSchAuthCancelException("publickey");
							}
							//throw new JSchException("USERAUTH cancel");
							//break;
							string _passphrase = userinfo.GetPassphrase();
							if (_passphrase != null)
							{
								passphrase = Util.Str2byte(_passphrase);
							}
						}
						if (!identity.IsEncrypted() || passphrase != null)
						{
							if (identity.SetPassphrase(passphrase))
							{
								break;
							}
							else
							{
								throw new System.Exception ("Invalid passphrase supplied for the ssh key");
							}
						}
						Util.Bzero(passphrase);
						passphrase = null;
						count--;
						if (count == 0)
						{
							break;
						}
					}
					Util.Bzero(passphrase);
					passphrase = null;
					//System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted());
					if (identity.IsEncrypted())
					{
						continue;
					}
					if (pubkeyblob == null)
					{
						pubkeyblob = identity.GetPublicKeyBlob();
					}
					//System.err.println("UserAuthPublicKey: pubkeyblob="+pubkeyblob);
					if (pubkeyblob == null)
					{
						continue;
					}
					// send
					// byte      SSH_MSG_USERAUTH_REQUEST(50)
					// string    user name
					// string    service name ("ssh-connection")
					// string    "publickey"
					// boolen    TRUE
					// string    plaintext password (ISO-10646 UTF-8)
					packet.Reset();
					buf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_REQUEST));
					buf.PutString(_username);
					buf.PutString(Util.Str2byte("ssh-connection"));
					buf.PutString(Util.Str2byte("publickey"));
					buf.PutByte(unchecked((byte)1));
					buf.PutString(Util.Str2byte(identity.GetAlgName()));
					buf.PutString(pubkeyblob);
					//      byte[] tmp=new byte[buf.index-5];
					//      System.arraycopy(buf.buffer, 5, tmp, 0, tmp.length);
					//      buf.putString(signature);
					byte[] sid = session.GetSessionId();
					int sidlen = sid.Length;
					byte[] tmp = new byte[4 + sidlen + buf.index - 5];
					tmp[0] = unchecked((byte)((int)(((uint)sidlen) >> 24)));
					tmp[1] = unchecked((byte)((int)(((uint)sidlen) >> 16)));
					tmp[2] = unchecked((byte)((int)(((uint)sidlen) >> 8)));
					tmp[3] = unchecked((byte)(sidlen));
					System.Array.Copy(sid, 0, tmp, 4, sidlen);
					System.Array.Copy(buf.buffer, 5, tmp, 4 + sidlen, buf.index - 5);
					byte[] signature = identity.GetSignature(tmp);
					if (signature == null)
					{
						// for example, too long key length.
						break;
					}
					buf.PutString(signature);
					session.Write(packet);
					while (true)
					{
						buf = session.Read(buf);
						command = buf.GetCommand() & unchecked((int)(0xff));
						if (command == SSH_MSG_USERAUTH_SUCCESS)
						{
							return true;
						}
						else
						{
							if (command == SSH_MSG_USERAUTH_BANNER)
							{
								buf.GetInt();
								buf.GetByte();
								buf.GetByte();
								byte[] _message = buf.GetString();
								byte[] lang = buf.GetString();
								string message = Util.Byte2str(_message);
								if (userinfo != null)
								{
									userinfo.ShowMessage(message);
								}
								goto loop2_continue;
							}
							else
							{
								if (command == SSH_MSG_USERAUTH_FAILURE)
								{
									buf.GetInt();
									buf.GetByte();
									buf.GetByte();
									byte[] foo = buf.GetString();
									int partial_success = buf.GetByte();
									//System.err.println(new String(foo)+
									//                   " partial_success:"+(partial_success!=0));
									if (partial_success != 0)
									{
										throw new JSchPartialAuthException(Util.Byte2str(foo));
									}
									session.auth_failures++;
									break;
								}
							}
						}
						//System.err.println("USERAUTH fail ("+command+")");
						//throw new JSchException("USERAUTH fail ("+command+")");
						break;
loop2_continue: ;
					}
loop2_break: ;
				}
			}
			return false;
		}
		// OID 1.2.840.113554.1.2.2 in DER
		/// <exception cref="System.Exception"></exception>
		public override bool Start(Session session)
		{
			base.Start(session);
			byte[] _username = Util.Str2byte(username);
			packet.Reset();
			// byte            SSH_MSG_USERAUTH_REQUEST(50)
			// string          user name(in ISO-10646 UTF-8 encoding)
			// string          service name(in US-ASCII)
			// string          "gssapi"(US-ASCII)
			// uint32          n, the number of OIDs client supports
			// string[n]       mechanism OIDS
			buf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_REQUEST));
			buf.PutString(_username);
			buf.PutString(Util.Str2byte("ssh-connection"));
			buf.PutString(Util.Str2byte("gssapi-with-mic"));
			buf.PutInt(supported_oid.Length);
			for (int i = 0; i < supported_oid.Length; i++)
			{
				buf.PutString(supported_oid[i]);
			}
			session.Write(packet);
			string method = null;
			int command;
			while (true)
			{
				buf = session.Read(buf);
				command = buf.GetCommand() & unchecked((int)(0xff));
				if (command == SSH_MSG_USERAUTH_FAILURE)
				{
					return false;
				}
				if (command == SSH_MSG_USERAUTH_GSSAPI_RESPONSE)
				{
					buf.GetInt();
					buf.GetByte();
					buf.GetByte();
					byte[] message = buf.GetString();
					for (int i_1 = 0; i_1 < supported_oid.Length; i_1++)
					{
						if (Util.Array_equals(message, supported_oid[i_1]))
						{
							method = supported_method[i_1];
							break;
						}
					}
					if (method == null)
					{
						return false;
					}
					break;
				}
				// success
				if (command == SSH_MSG_USERAUTH_BANNER)
				{
					buf.GetInt();
					buf.GetByte();
					buf.GetByte();
					byte[] _message = buf.GetString();
					byte[] lang = buf.GetString();
					string message = Util.Byte2str(_message);
					if (userinfo != null)
					{
						userinfo.ShowMessage(message);
					}
					continue;
				}
				return false;
			}
			NSch.GSSContext context = null;
			try
			{
				Type c = Sharpen.Runtime.GetType(session.GetConfig(method));
				context = (NSch.GSSContext)(System.Activator.CreateInstance(c));
			}
			catch (Exception)
			{
				return false;
			}
			try
			{
				context.Create(username, session.host);
			}
			catch (JSchException)
			{
				return false;
			}
			byte[] token = new byte[0];
			while (!context.IsEstablished())
			{
				try
				{
					token = context.Init(token, 0, token.Length);
				}
				catch (JSchException)
				{
					// TODO
					// ERRTOK should be sent?
					// byte        SSH_MSG_USERAUTH_GSSAPI_ERRTOK
					// string      error token
					return false;
				}
				if (token != null)
				{
					packet.Reset();
					buf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_GSSAPI_TOKEN));
					buf.PutString(token);
					session.Write(packet);
				}
				if (!context.IsEstablished())
				{
					buf = session.Read(buf);
					command = buf.GetCommand() & unchecked((int)(0xff));
					if (command == SSH_MSG_USERAUTH_GSSAPI_ERROR)
					{
						// uint32    major_status
						// uint32    minor_status
						// string    message
						// string    language tag
						buf = session.Read(buf);
						command = buf.GetCommand() & unchecked((int)(0xff));
					}
					else
					{
						//return false;
						if (command == SSH_MSG_USERAUTH_GSSAPI_ERRTOK)
						{
							// string error token
							buf = session.Read(buf);
							command = buf.GetCommand() & unchecked((int)(0xff));
						}
					}
					//return false;
					if (command == SSH_MSG_USERAUTH_FAILURE)
					{
						return false;
					}
					buf.GetInt();
					buf.GetByte();
					buf.GetByte();
					token = buf.GetString();
				}
			}
			Buffer mbuf = new Buffer();
			// string    session identifier
			// byte      SSH_MSG_USERAUTH_REQUEST
			// string    user name
			// string    service
			// string    "gssapi-with-mic"
			mbuf.PutString(session.GetSessionId());
			mbuf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_REQUEST));
			mbuf.PutString(_username);
			mbuf.PutString(Util.Str2byte("ssh-connection"));
			mbuf.PutString(Util.Str2byte("gssapi-with-mic"));
			byte[] mic = context.GetMIC(mbuf.buffer, 0, mbuf.GetLength());
			if (mic == null)
			{
				return false;
			}
			packet.Reset();
			buf.PutByte(unchecked((byte)SSH_MSG_USERAUTH_GSSAPI_MIC));
			buf.PutString(mic);
			session.Write(packet);
			context.Dispose();
			buf = session.Read(buf);
			command = buf.GetCommand() & unchecked((int)(0xff));
			if (command == SSH_MSG_USERAUTH_SUCCESS)
			{
				return true;
			}
			else
			{
				if (command == SSH_MSG_USERAUTH_FAILURE)
				{
					buf.GetInt();
					buf.GetByte();
					buf.GetByte();
					byte[] foo = buf.GetString();
					int partial_success = buf.GetByte();
					//System.err.println(new String(foo)+
					//		 " partial_success:"+(partial_success!=0));
					if (partial_success != 0)
					{
						throw new JSchPartialAuthException(Util.Byte2str(foo));
					}
				}
			}
			return false;
		}