001: /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
002: /*
003: Copyright (c) 2002-2008 ymnk, JCraft,Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: 1. Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010:
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in
013: the documentation and/or other materials provided with the distribution.
014:
015: 3. The names of the authors may not be used to endorse or promote products
016: derived from this software without specific prior written permission.
017:
018: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
019: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
020: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
021: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
022: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
024: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
027: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jcraft.jsch;
031:
032: class UserAuthPassword extends UserAuth {
033: private final int SSH_MSG_USERAUTH_PASSWD_CHANGEREQ = 60;
034:
035: public boolean start(Session session) throws Exception {
036: super .start(session);
037:
038: byte[] password = session.password;
039: String dest = username + "@" + session.host;
040: if (session.port != 22) {
041: dest += (":" + session.port);
042: }
043:
044: try {
045:
046: while (true) {
047: if (password == null) {
048: if (userinfo == null) {
049: //throw new JSchException("USERAUTH fail");
050: return false;
051: }
052: if (!userinfo
053: .promptPassword("Password for " + dest)) {
054: throw new JSchAuthCancelException("password");
055: //break;
056: }
057:
058: String _password = userinfo.getPassword();
059: if (_password == null) {
060: throw new JSchAuthCancelException("password");
061: //break;
062: }
063: password = Util.str2byte(_password);
064: }
065:
066: byte[] _username = null;
067: _username = Util.str2byte(username);
068:
069: // send
070: // byte SSH_MSG_USERAUTH_REQUEST(50)
071: // string user name
072: // string service name ("ssh-connection")
073: // string "password"
074: // boolen FALSE
075: // string plaintext password (ISO-10646 UTF-8)
076: packet.reset();
077: buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST);
078: buf.putString(_username);
079: buf.putString("ssh-connection".getBytes());
080: buf.putString("password".getBytes());
081: buf.putByte((byte) 0);
082: buf.putString(password);
083: session.write(packet);
084:
085: loop: while (true) {
086: buf = session.read(buf);
087: int command = buf.getCommand() & 0xff;
088:
089: if (command == SSH_MSG_USERAUTH_SUCCESS) {
090: return true;
091: }
092: if (command == SSH_MSG_USERAUTH_BANNER) {
093: buf.getInt();
094: buf.getByte();
095: buf.getByte();
096: byte[] _message = buf.getString();
097: byte[] lang = buf.getString();
098: String message = Util.byte2str(_message);
099: if (userinfo != null) {
100: userinfo.showMessage(message);
101: }
102: continue loop;
103: }
104: if (command == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) {
105: buf.getInt();
106: buf.getByte();
107: buf.getByte();
108: byte[] instruction = buf.getString();
109: byte[] tag = buf.getString();
110: if (userinfo == null
111: || !(userinfo instanceof UIKeyboardInteractive)) {
112: if (userinfo != null) {
113: userinfo
114: .showMessage("Password must be changed.");
115: }
116: return false;
117: }
118:
119: UIKeyboardInteractive kbi = (UIKeyboardInteractive) userinfo;
120: String[] response;
121: String name = "Password Change Required";
122: String[] prompt = { "New Password: " };
123: boolean[] echo = { false };
124: response = kbi.promptKeyboardInteractive(dest,
125: name, new String(instruction), prompt,
126: echo);
127: if (response == null) {
128: throw new JSchAuthCancelException(
129: "password");
130: }
131:
132: byte[] newpassword = response[0].getBytes();
133:
134: // send
135: // byte SSH_MSG_USERAUTH_REQUEST(50)
136: // string user name
137: // string service name ("ssh-connection")
138: // string "password"
139: // boolen TRUE
140: // string plaintext old password (ISO-10646 UTF-8)
141: // string plaintext new password (ISO-10646 UTF-8)
142: packet.reset();
143: buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST);
144: buf.putString(_username);
145: buf.putString("ssh-connection".getBytes());
146: buf.putString("password".getBytes());
147: buf.putByte((byte) 1);
148: buf.putString(password);
149: buf.putString(newpassword);
150: Util.bzero(newpassword);
151: response = null;
152: session.write(packet);
153: continue loop;
154: }
155: if (command == SSH_MSG_USERAUTH_FAILURE) {
156: buf.getInt();
157: buf.getByte();
158: buf.getByte();
159: byte[] foo = buf.getString();
160: int partial_success = buf.getByte();
161: //System.err.println(new String(foo)+
162: // " partial_success:"+(partial_success!=0));
163: if (partial_success != 0) {
164: throw new JSchPartialAuthException(
165: new String(foo));
166: }
167: break;
168: } else {
169: //System.err.println("USERAUTH fail ("+buf.getCommand()+")");
170: // throw new JSchException("USERAUTH fail ("+buf.getCommand()+")");
171: return false;
172: }
173: }
174:
175: if (password != null) {
176: Util.bzero(password);
177: password = null;
178: }
179:
180: }
181:
182: } finally {
183: if (password != null) {
184: Util.bzero(password);
185: password = null;
186: }
187: }
188:
189: //throw new JSchException("USERAUTH fail");
190: //return false;
191: }
192: }
|