@@ -27,14 +27,21 @@ CAuthSession::~CAuthSession()
2727}
2828
2929CAuthentication::CAuthentication ()
30- : CDispatchImplT(theApp.GetTypeInfo(IID_IEasySFTPAuthentication ))
30+ : CDispatchImplT(theApp.GetTypeInfo(IID_IEasySFTPAuthentication2 ))
3131 , m_Mode(EasySFTPAuthenticationMode::None)
32- , m_pSession(NULL )
32+ , m_pPrivateKeyData(nullptr )
33+ , m_nPrivateKeyData(0 )
34+ , m_pSession(nullptr )
3335{
3436}
3537
3638CAuthentication::~CAuthentication ()
3739{
40+ if (m_pPrivateKeyData != nullptr )
41+ {
42+ _SecureStringW::SecureEmptyBuffer (m_pPrivateKeyData, m_nPrivateKeyData);
43+ free (m_pPrivateKeyData);
44+ }
3845 if (m_pSession != NULL )
3946 {
4047 auto * p = static_cast <CAuthSession*>(m_pSession);
@@ -49,11 +56,12 @@ STDMETHODIMP CAuthentication::QueryInterface(REFIID riid, void** ppv)
4956 return E_POINTER;
5057 *ppv = NULL ;
5158 if (!IsEqualIID (riid, IID_IUnknown) && !IsEqualIID (riid, IID_IDispatch) &&
52- !IsEqualIID (riid, IID_IEasySFTPAuthentication))
59+ !IsEqualIID (riid, IID_IEasySFTPAuthentication) &&
60+ !IsEqualIID (riid, IID_IEasySFTPAuthentication2))
5361 {
5462 return E_NOINTERFACE;
5563 }
56- *ppv = static_cast <IEasySFTPAuthentication *>(this );
64+ *ppv = static_cast <IEasySFTPAuthentication2 *>(this );
5765 AddRef ();
5866 return S_OK;
5967}
@@ -92,17 +100,17 @@ STDMETHODIMP CAuthentication::put_Password(BSTR p)
92100 return S_OK;
93101}
94102
95- STDMETHODIMP CAuthentication::get_PublicKeyFileName (BSTR* p)
103+ STDMETHODIMP CAuthentication::get_PrivateKeyFileName (BSTR* p)
96104{
97105 if (!p)
98106 return E_POINTER;
99- *p = MyStringToBSTR (m_strPublicKeyFileName );
107+ *p = MyStringToBSTR (m_strPrivateKeyFileName );
100108 return *p ? S_OK : E_OUTOFMEMORY;
101109}
102110
103- STDMETHODIMP CAuthentication::put_PublicKeyFileName (BSTR p)
111+ STDMETHODIMP CAuthentication::put_PrivateKeyFileName (BSTR p)
104112{
105- MyBSTRToString (p, m_strPublicKeyFileName );
113+ MyBSTRToString (p, m_strPrivateKeyFileName );
106114 return S_OK;
107115}
108116
@@ -136,7 +144,39 @@ STDMETHODIMP CAuthentication::put_AuthSession(LONG_PTR session)
136144 return S_OK;
137145}
138146
139- AuthReturnType CAuthentication::SSHAuthenticate (IEasySFTPAuthentication* pAuth, LIBSSH2_SESSION* pSession, LPCSTR lpszService, char ** ppAuthList)
147+ STDMETHODIMP CAuthentication::SetPrivateKeyBinary (const void * buffer, long length)
148+ {
149+ if (length < 0 )
150+ return E_INVALIDARG;
151+ if (length != 0 && !buffer)
152+ return E_POINTER;
153+ if (m_pPrivateKeyData != nullptr )
154+ {
155+ _SecureStringW::SecureEmptyBuffer (m_pPrivateKeyData, m_nPrivateKeyData);
156+ free (m_pPrivateKeyData);
157+ m_pPrivateKeyData = nullptr ;
158+ }
159+ m_nPrivateKeyData = length;
160+ if (length > 0 )
161+ {
162+ m_pPrivateKeyData = malloc (static_cast <size_t >(length));
163+ if (!m_pPrivateKeyData)
164+ return E_OUTOFMEMORY;
165+ memcpy (m_pPrivateKeyData, buffer, static_cast <size_t >(length));
166+ }
167+ return S_OK;
168+ }
169+
170+ STDMETHODIMP CAuthentication::GetPrivateKeyBinary (const void ** buffer, long * pLength)
171+ {
172+ if (!buffer || !pLength)
173+ return E_POINTER;
174+ *buffer = m_pPrivateKeyData;
175+ *pLength = m_nPrivateKeyData;
176+ return m_nPrivateKeyData > 0 ? S_OK : S_FALSE;
177+ }
178+
179+ AuthReturnType CAuthentication::SSHAuthenticate (IEasySFTPAuthentication2* pAuth, LIBSSH2_SESSION* pSession, LPCSTR lpszService, char ** ppAuthList)
140180{
141181 EasySFTPAuthenticationMode mode;
142182 if (FAILED (pAuth->get_Type (&mode)))
@@ -213,34 +253,66 @@ AuthReturnType CAuthentication::SSHAuthenticate(IEasySFTPAuthentication* pAuth,
213253 return AuthReturnType::Success;
214254 }
215255 break ;
216- case EasySFTPAuthenticationMode::PublicKey :
256+ case EasySFTPAuthenticationMode::PrivateKey :
217257 {
218- if (FAILED (pAuth->get_PublicKeyFileName (&bstr)))
219- return AuthReturnType::Error;
220- CMyStringW strPublicKeyFileName;
221- MyBSTRToString (bstr, strPublicKeyFileName);
222- ::SysFreeString (bstr);
223- auto * lpszPKeyFileName = reinterpret_cast <LPCSTR>(strPublicKeyFileName.AllocUTF8String ());
224- if (FAILED (pAuth->get_Password (&bstr)))
225- return AuthReturnType::Error;
226- CMyStringW str;
227- MyBSTRToString (bstr, str);
228- _SecureStringW::SecureEmptyBStr (bstr);
229- ::SysFreeString (bstr);
230- size_t nPasswordLen = 0 ;
231- auto * lpszPassword = reinterpret_cast <LPSTR>(str.AllocUTF8StringC (&nPasswordLen));
232- _SecureStringW::SecureEmptyString (str);
233- if (!lpszPassword)
258+ const void * pKeyBuffer = nullptr ;
259+ long nKeyLength = 0 ;
260+ auto hr = pAuth->GetPrivateKeyBinary (&pKeyBuffer, &nKeyLength);
261+ if (FAILED (hr))
234262 return AuthReturnType::Error;
263+ if (hr == S_OK && nKeyLength > 0 && pKeyBuffer != nullptr )
264+ {
265+ if (FAILED (pAuth->get_Password (&bstr)))
266+ return AuthReturnType::Error;
267+ CMyStringW str;
268+ MyBSTRToString (bstr, str);
269+ _SecureStringW::SecureEmptyBStr (bstr);
270+ ::SysFreeString (bstr);
271+ size_t nPasswordLen = 0 ;
272+ auto * lpszPassword = reinterpret_cast <LPSTR>(str.AllocUTF8StringC (&nPasswordLen));
273+ _SecureStringW::SecureEmptyString (str);
274+ if (!lpszPassword)
275+ return AuthReturnType::Error;
276+
277+ auto ret = libssh2_userauth_publickey_frommemory (pSession, pUser, static_cast <UINT>(nUserLen), NULL , 0 ,
278+ static_cast <const char *>(pKeyBuffer), static_cast <size_t >(nKeyLength), lpszPassword);
279+ _SecureStringW::SecureEmptyBuffer (lpszPassword, sizeof (char ) * nPasswordLen);
280+ free (lpszPassword);
281+ if (ret == LIBSSH2_ERROR_EAGAIN)
282+ return AuthReturnType::Again;
235283
236- auto ret = libssh2_userauth_publickey_fromfile_ex (pSession, pUser, static_cast <UINT>(nUserLen), NULL , lpszPKeyFileName, lpszPassword);
237- _SecureStringW::SecureEmptyBuffer (lpszPassword, sizeof (char ) * nPasswordLen);
238- free (lpszPassword);
239- if (ret == LIBSSH2_ERROR_EAGAIN)
240- return AuthReturnType::Again;
284+ if (ret != 0 )
285+ return AuthReturnType::Error;
286+ }
287+ else
288+ {
289+ if (FAILED (pAuth->get_PrivateKeyFileName (&bstr)))
290+ return AuthReturnType::Error;
291+ CMyStringW strPrivateKeyFileName;
292+ MyBSTRToString (bstr, strPrivateKeyFileName);
293+ ::SysFreeString (bstr);
294+ auto * lpszPKeyFileName = reinterpret_cast <LPCSTR>(strPrivateKeyFileName.AllocUTF8String ());
295+ if (FAILED (pAuth->get_Password (&bstr)))
296+ return AuthReturnType::Error;
297+ CMyStringW str;
298+ MyBSTRToString (bstr, str);
299+ _SecureStringW::SecureEmptyBStr (bstr);
300+ ::SysFreeString (bstr);
301+ size_t nPasswordLen = 0 ;
302+ auto * lpszPassword = reinterpret_cast <LPSTR>(str.AllocUTF8StringC (&nPasswordLen));
303+ _SecureStringW::SecureEmptyString (str);
304+ if (!lpszPassword)
305+ return AuthReturnType::Error;
306+
307+ auto ret = libssh2_userauth_publickey_fromfile_ex (pSession, pUser, static_cast <UINT>(nUserLen), NULL , lpszPKeyFileName, lpszPassword);
308+ _SecureStringW::SecureEmptyBuffer (lpszPassword, sizeof (char ) * nPasswordLen);
309+ free (lpszPassword);
310+ if (ret == LIBSSH2_ERROR_EAGAIN)
311+ return AuthReturnType::Again;
241312
242- if (ret != 0 )
243- return AuthReturnType::Error;
313+ if (ret != 0 )
314+ return AuthReturnType::Error;
315+ }
244316 return AuthReturnType::Success;
245317 }
246318 break ;
0 commit comments