3 ** Copyright (C) 2004-2016 Victor Kirhenshtein
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "ssh_subagent.h"
25 * SSH session constructor
27 SSHSession::SSHSession(const InetAddress
& addr
, UINT16 port
, INT32 id
)
36 _sntprintf(m_name
, MAX_SSH_SESSION_NAME_LEN
, _T("nobody@%s:%d/%d"), (const TCHAR
*)m_addr
.toString(), m_port
, m_id
);
40 * SSH session destructor
42 SSHSession::~SSHSession()
48 * Check if session match for given target
50 bool SSHSession::match(const InetAddress
& addr
, UINT16 port
, const TCHAR
*user
) const
52 return addr
.equals(m_addr
) && ((unsigned int)port
== m_port
) && !_tcscmp(m_user
, user
);
58 bool SSHSession::acquire()
60 if (m_busy
|| !isConnected())
69 void SSHSession::release()
77 bool SSHSession::connect(const TCHAR
*user
, const TCHAR
*password
)
79 if (m_session
!= NULL
)
80 return false; // already connected
82 m_session
= ssh_new();
83 if (m_session
== NULL
)
84 return false; // cannot create session
89 ssh_options_set(m_session
, SSH_OPTIONS_HOST
, m_addr
.toStringA(hostname
));
90 ssh_options_set(m_session
, SSH_OPTIONS_PORT
, &m_port
);
91 long timeout
= (long)g_sshConnectTimeout
* (long)1000; // convert milliseconds to microseconds
92 ssh_options_set(m_session
, SSH_OPTIONS_TIMEOUT_USEC
, &timeout
);
95 WideCharToMultiByte(CP_UTF8
, 0, user
, -1, mbuser
, 256, NULL
, NULL
);
96 ssh_options_set(m_session
, SSH_OPTIONS_USER
, mbuser
);
98 ssh_options_set(m_session
, SSH_OPTIONS_USER
, user
);
101 if (ssh_connect(m_session
) == SSH_OK
)
104 char mbpassword
[256];
105 WideCharToMultiByte(CP_UTF8
, 0, password
, -1, mbpassword
, 256, NULL
, NULL
);
106 if (ssh_userauth_password(m_session
, NULL
, mbpassword
) == SSH_AUTH_SUCCESS
)
108 if (ssh_userauth_password(m_session
, NULL
, password
) == SSH_AUTH_SUCCESS
)
115 nxlog_debug(6, _T("SSH: login as %s on %s:%d failed"), user
, (const TCHAR
*)m_addr
.toString(), m_port
);
120 nxlog_debug(6, _T("SSH: connect to %s:%d failed"), (const TCHAR
*)m_addr
.toString(), m_port
);
125 nx_strncpy(m_user
, user
, MAX_SSH_LOGIN_LEN
);
126 _sntprintf(m_name
, MAX_SSH_SESSION_NAME_LEN
, _T("%s@%s:%d/%d"), m_user
, (const TCHAR
*)m_addr
.toString(), m_port
, m_id
);
127 m_lastAccess
= time(NULL
);
131 if (ssh_is_connected(m_session
))
132 ssh_disconnect(m_session
);
140 * Disconnect from server
142 void SSHSession::disconnect()
144 if (m_session
== NULL
)
147 if (ssh_is_connected(m_session
))
148 ssh_disconnect(m_session
);
154 * Execute command and capture output
156 StringList
*SSHSession::execute(const TCHAR
*command
)
158 if ((m_session
== NULL
) || !ssh_is_connected(m_session
))
161 ssh_channel channel
= ssh_channel_new(m_session
);
165 StringList
*output
= NULL
;
166 if (ssh_channel_open_session(channel
) == SSH_OK
)
169 char *mbcmd
= UTF8StringFromWideString(command
);
170 if (ssh_channel_request_exec(channel
, mbcmd
) == SSH_OK
)
172 if (ssh_channel_request_exec(channel
, command
) == SSH_OK
)
175 output
= new StringList();
177 int nbytes
= ssh_channel_read(channel
, buffer
, sizeof(buffer
) - 1, 0);
181 buffer
[nbytes
+ offset
] = 0;
183 char *eol
= strchr(curr
, '\n');
187 char *cr
= strchr(curr
, '\r');
190 output
->addMBString(curr
);
192 eol
= strchr(curr
, '\n');
194 offset
= (int)strlen(curr
);
196 memmove(buffer
, curr
, offset
);
197 nbytes
= ssh_channel_read(channel
, &buffer
[offset
], sizeof(buffer
) - offset
- 1, 0);
204 char *cr
= strchr(buffer
, '\r');
207 output
->addMBString(buffer
);
209 ssh_channel_send_eof(channel
);
213 delete_and_null(output
);
218 nxlog_debug(6, _T("SSH: command \"%s\" execution on %s:%d failed"), command
, (const TCHAR
*)m_addr
.toString(), m_port
);
220 ssh_channel_close(channel
);
224 nxlog_debug(6, _T("SSH: cannot open channel on %s:%d"), (const TCHAR
*)m_addr
.toString(), m_port
);
226 ssh_channel_free(channel
);
227 m_lastAccess
= time(NULL
);