mirror of
https://github.com/libssh2/libssh2.git
synced 2026-01-06 14:21:57 +03:00
ssh: Add support for userauth banner.
The new libssh2_userauth_banner API allows to get an optional userauth banner sent with SSH_MSG_USERAUTH_BANNER packet by the server. Closes #610
This commit is contained in:
committed by
Daniel Stenberg
parent
13ad7b2f5c
commit
d5ed0e6536
@@ -194,6 +194,7 @@ set(MAN_PAGES
|
||||
libssh2_trace.3
|
||||
libssh2_trace_sethandler.3
|
||||
libssh2_userauth_authenticated.3
|
||||
libssh2_userauth_banner.3
|
||||
libssh2_userauth_hostbased_fromfile.3
|
||||
libssh2_userauth_hostbased_fromfile_ex.3
|
||||
libssh2_userauth_keyboard_interactive.3
|
||||
|
||||
@@ -164,6 +164,7 @@ dist_man_MANS = \
|
||||
libssh2_trace.3 \
|
||||
libssh2_trace_sethandler.3 \
|
||||
libssh2_userauth_authenticated.3 \
|
||||
libssh2_userauth_banner.3 \
|
||||
libssh2_userauth_hostbased_fromfile.3 \
|
||||
libssh2_userauth_hostbased_fromfile_ex.3 \
|
||||
libssh2_userauth_keyboard_interactive.3 \
|
||||
|
||||
30
docs/libssh2_userauth_banner.3
Normal file
30
docs/libssh2_userauth_banner.3
Normal file
@@ -0,0 +1,30 @@
|
||||
.TH libssh2_userauth_banner 3 "1 Jun 2021" "libssh2 1.9.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_userauth_banner - get the server's userauth banner message
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
int
|
||||
libssh2_userauth_banner(LIBSSH2_SESSION *session, char **banner);
|
||||
.SH DESCRIPTION
|
||||
\fIsession\fP - Session instance as returned by
|
||||
.BR libssh2_session_init_ex(3)
|
||||
|
||||
\fIbanner\fP - Should point to a pointer that gets filled with banner message.
|
||||
|
||||
After an authentication has been attempted, such as a
|
||||
\fBSSH_USERAUTH_NONE\fP request sent by
|
||||
.BR libssh2_userauth_list(3) ,
|
||||
this function can be called to retrieve the userauth banner sent by
|
||||
the server. If no such banner is sent, or if an authentication has not
|
||||
yet been attempted, returns LIBSSH2_ERROR_MISSING_USERAUTH_BANNER.
|
||||
.SH RETURN VALUE
|
||||
On success returns 0 and an UTF-8 NUL-terminated string is stored in the
|
||||
\fIbanner\fP. This string is internally managed by libssh2 and will be
|
||||
deallocated upon session termination.
|
||||
On failure returns
|
||||
LIBSSH2_ERROR_MISSING_USERAUTH_BANNER.
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_session_init_ex(3),
|
||||
.BR libssh2_userauth_list(3)
|
||||
@@ -507,6 +507,7 @@ typedef struct _LIBSSH2_POLLFD {
|
||||
#define LIBSSH2_ERROR_CHANNEL_WINDOW_FULL -47
|
||||
#define LIBSSH2_ERROR_KEYFILE_AUTH_FAILED -48
|
||||
#define LIBSSH2_ERROR_RANDGEN -49
|
||||
#define LIBSSH2_ERROR_MISSING_USERAUTH_BANNER -50
|
||||
|
||||
/* this is a define to provide the old (<= 1.2.7) name */
|
||||
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV
|
||||
@@ -615,6 +616,8 @@ LIBSSH2_API const char *libssh2_session_banner_get(LIBSSH2_SESSION *session);
|
||||
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session,
|
||||
const char *username,
|
||||
unsigned int username_len);
|
||||
LIBSSH2_API int libssh2_userauth_banner(LIBSSH2_SESSION *session,
|
||||
char **banner);
|
||||
LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
|
||||
|
||||
LIBSSH2_API int
|
||||
|
||||
@@ -720,6 +720,7 @@ struct _LIBSSH2_SESSION
|
||||
libssh2_nonblocking_states userauth_list_state;
|
||||
unsigned char *userauth_list_data;
|
||||
size_t userauth_list_data_len;
|
||||
char *userauth_banner;
|
||||
packet_requirev_state_t userauth_list_packet_requirev_state;
|
||||
|
||||
/* State variables used in libssh2_userauth_password_ex() */
|
||||
|
||||
@@ -994,6 +994,9 @@ session_free(LIBSSH2_SESSION *session)
|
||||
if(session->userauth_list_data) {
|
||||
LIBSSH2_FREE(session, session->userauth_list_data);
|
||||
}
|
||||
if(session->userauth_banner) {
|
||||
LIBSSH2_FREE(session, session->userauth_banner);
|
||||
}
|
||||
if(session->userauth_pswd_data) {
|
||||
LIBSSH2_FREE(session, session->userauth_pswd_data);
|
||||
}
|
||||
|
||||
@@ -63,11 +63,13 @@
|
||||
static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
|
||||
unsigned int username_len)
|
||||
{
|
||||
static const unsigned char reply_codes[3] =
|
||||
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
|
||||
unsigned char reply_codes[4] =
|
||||
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
|
||||
SSH_MSG_USERAUTH_BANNER, 0 };
|
||||
/* packet_type(1) + username_len(4) + service_len(4) +
|
||||
service(14)"ssh-connection" + method_len(4) = 27 */
|
||||
unsigned long methods_len;
|
||||
unsigned int banner_len;
|
||||
unsigned char *s;
|
||||
int rc;
|
||||
|
||||
@@ -134,6 +136,57 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_BANNER) {
|
||||
if(session->userauth_list_data_len < 5) {
|
||||
LIBSSH2_FREE(session, session->userauth_list_data);
|
||||
session->userauth_list_data = NULL;
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Unexpected packet size");
|
||||
return NULL;
|
||||
}
|
||||
banner_len = _libssh2_ntohu32(session->userauth_list_data + 1);
|
||||
if(banner_len >= session->userauth_list_data_len - 5) {
|
||||
LIBSSH2_FREE(session, session->userauth_list_data);
|
||||
session->userauth_list_data = NULL;
|
||||
_libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
|
||||
"Unexpected userauth banner size");
|
||||
return NULL;
|
||||
}
|
||||
session->userauth_banner = LIBSSH2_ALLOC(session, banner_len);
|
||||
if(!session->userauth_banner) {
|
||||
LIBSSH2_FREE(session, session->userauth_list_data);
|
||||
session->userauth_list_data = NULL;
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for userauth_banner");
|
||||
return NULL;
|
||||
}
|
||||
memmove(session->userauth_banner, session->userauth_list_data + 5,
|
||||
banner_len);
|
||||
session->userauth_banner[banner_len] = '\0';
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
|
||||
"Banner: %s",
|
||||
session->userauth_banner);
|
||||
LIBSSH2_FREE(session, session->userauth_list_data);
|
||||
session->userauth_list_data = NULL;
|
||||
/* SSH_MSG_USERAUTH_BANNER has been handled */
|
||||
reply_codes[2] = 0;
|
||||
rc = _libssh2_packet_requirev(session, reply_codes,
|
||||
&session->userauth_list_data,
|
||||
&session->userauth_list_data_len, 0,
|
||||
NULL, 0,
|
||||
&session->userauth_list_packet_requirev_state);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block requesting userauth list");
|
||||
return NULL;
|
||||
}
|
||||
else if(rc || (session->userauth_list_data_len < 1)) {
|
||||
_libssh2_error(session, rc, "Failed getting response");
|
||||
session->userauth_list_state = libssh2_NB_state_idle;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
/* Wow, who'dve thought... */
|
||||
_libssh2_error(session, LIBSSH2_ERROR_NONE, "No error");
|
||||
@@ -189,6 +242,30 @@ libssh2_userauth_list(LIBSSH2_SESSION * session, const char *user,
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* libssh2_userauth_banner
|
||||
*
|
||||
* Retrieve banner message from server, if available.
|
||||
* When no such message is sent by server or if no authentication attempt has
|
||||
* been made, this function returns LIBSSH2_ERROR_MISSING_AUTH_BANNER.
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_userauth_banner(LIBSSH2_SESSION *session, char **banner)
|
||||
{
|
||||
if(NULL == session)
|
||||
return LIBSSH2_ERROR_MISSING_USERAUTH_BANNER;
|
||||
|
||||
if(!session->userauth_banner) {
|
||||
return _libssh2_error(session,
|
||||
LIBSSH2_ERROR_MISSING_USERAUTH_BANNER,
|
||||
"Missing userauth banner");
|
||||
}
|
||||
|
||||
if(banner != NULL)
|
||||
*banner = session->userauth_banner;
|
||||
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_userauth_authenticated
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user