mirror of
https://github.com/libssh2/libssh2.git
synced 2025-08-07 08:02:56 +03:00
New function to retrieve pre-auth server banner
This commit is contained in:
25
docs/libssh2_userauth_banner.3
Normal file
25
docs/libssh2_userauth_banner.3
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
.TH libssh2_userauth_banner 3 "27 Nov 2018" "libssh2 0.15" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_userauth_banner - get the server's pre-auth banner message
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.nf
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
libssh2_userauth_banner(LIBSSH2_SESSION *session,
|
||||||
|
size_t *banner_len_out);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init_ex(3)
|
||||||
|
|
||||||
|
\fIbanner_len_out\fP - The length of the server banner returned.
|
||||||
|
|
||||||
|
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 pre-auth banner sent by the server. If no such banner is sent, or if an authentication has not yet been attempted, returns NULL.
|
||||||
|
.SH RETURN VALUE
|
||||||
|
On success a UTF-8 pre-authentication banner message from the server.
|
||||||
|
On failure returns NULL.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init_ex(3),
|
||||||
|
.BR libssh2_userauth_list(3)
|
@@ -611,6 +611,8 @@ LIBSSH2_API const char *libssh2_session_banner_get(LIBSSH2_SESSION *session);
|
|||||||
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session,
|
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session,
|
||||||
const char *username,
|
const char *username,
|
||||||
unsigned int username_len);
|
unsigned int username_len);
|
||||||
|
LIBSSH2_API char *libssh2_userauth_banner(LIBSSH2_SESSION * session,
|
||||||
|
size_t *banner_len_out);
|
||||||
LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
|
LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
LIBSSH2_API int
|
LIBSSH2_API int
|
||||||
|
@@ -709,6 +709,8 @@ struct _LIBSSH2_SESSION
|
|||||||
libssh2_nonblocking_states userauth_list_state;
|
libssh2_nonblocking_states userauth_list_state;
|
||||||
unsigned char *userauth_list_data;
|
unsigned char *userauth_list_data;
|
||||||
size_t userauth_list_data_len;
|
size_t userauth_list_data_len;
|
||||||
|
char *userauth_banner;
|
||||||
|
size_t userauth_banner_len;
|
||||||
packet_requirev_state_t userauth_list_packet_requirev_state;
|
packet_requirev_state_t userauth_list_packet_requirev_state;
|
||||||
|
|
||||||
/* State variables used in libssh2_userauth_password_ex() */
|
/* State variables used in libssh2_userauth_password_ex() */
|
||||||
|
@@ -53,6 +53,7 @@
|
|||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "userauth.h"
|
#include "userauth.h"
|
||||||
|
|
||||||
|
#define LIBSSH2_USERAUTH_MAX_BANNER 2048
|
||||||
/* libssh2_userauth_list
|
/* libssh2_userauth_list
|
||||||
*
|
*
|
||||||
* List authentication methods
|
* List authentication methods
|
||||||
@@ -63,8 +64,8 @@
|
|||||||
static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
|
static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
|
||||||
unsigned int username_len)
|
unsigned int username_len)
|
||||||
{
|
{
|
||||||
static const unsigned char reply_codes[3] =
|
static const unsigned char reply_codes[4] =
|
||||||
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
|
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_BANNER, 0 };
|
||||||
/* packet_type(1) + username_len(4) + service_len(4) +
|
/* packet_type(1) + username_len(4) + service_len(4) +
|
||||||
service(14)"ssh-connection" + method_len(4) = 27 */
|
service(14)"ssh-connection" + method_len(4) = 27 */
|
||||||
unsigned long methods_len;
|
unsigned long methods_len;
|
||||||
@@ -118,21 +119,54 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(session->userauth_list_state == libssh2_NB_state_sent) {
|
if(session->userauth_list_state == libssh2_NB_state_sent) {
|
||||||
rc = _libssh2_packet_requirev(session, reply_codes,
|
do {
|
||||||
&session->userauth_list_data,
|
rc = _libssh2_packet_requirev(session, reply_codes,
|
||||||
&session->userauth_list_data_len, 0,
|
&session->userauth_list_data,
|
||||||
NULL, 0,
|
&session->userauth_list_data_len, 0,
|
||||||
&session->userauth_list_packet_requirev_state);
|
NULL, 0,
|
||||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
&session->userauth_list_packet_requirev_state);
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
"Would block requesting userauth list");
|
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
return NULL;
|
"Would block requesting userauth list");
|
||||||
}
|
return NULL;
|
||||||
else if(rc || (session->userauth_list_data_len < 1)) {
|
}
|
||||||
_libssh2_error(session, rc, "Failed getting response");
|
else if(rc || (session->userauth_list_data_len < 1)) {
|
||||||
session->userauth_list_state = libssh2_NB_state_idle;
|
_libssh2_error(session, rc, "Failed getting response");
|
||||||
return NULL;
|
session->userauth_list_state = libssh2_NB_state_idle;
|
||||||
}
|
return NULL;
|
||||||
|
}
|
||||||
|
if (session->userauth_list_data[0] == SSH_MSG_USERAUTH_BANNER && (session->userauth_list_data_len >= 5)) {
|
||||||
|
methods_len = _libssh2_ntohu32(session->userauth_list_data + 1);
|
||||||
|
/* Cap to 512 bytes. */
|
||||||
|
if (methods_len > LIBSSH2_USERAUTH_MAX_BANNER) {
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
|
||||||
|
"Banner length %u exceeds max allowed (%u)",
|
||||||
|
methods_len, LIBSSH2_USERAUTH_MAX_BANNER);
|
||||||
|
methods_len = LIBSSH2_USERAUTH_MAX_BANNER - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!session->userauth_banner) {
|
||||||
|
session->userauth_banner = LIBSSH2_ALLOC(session, methods_len + 1);
|
||||||
|
}
|
||||||
|
else if (session->userauth_banner_len < methods_len) {
|
||||||
|
session->userauth_banner = LIBSSH2_REALLOC(session, session->userauth_banner, methods_len + 1);
|
||||||
|
}
|
||||||
|
if (!session->userauth_banner) {
|
||||||
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for userauth_banner");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
session->userauth_banner_len = methods_len;
|
||||||
|
|
||||||
|
memmove(session->userauth_banner, session->userauth_list_data + 5, methods_len);
|
||||||
|
session->userauth_banner[methods_len] = '\0';
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
|
||||||
|
"Banner: %s",
|
||||||
|
session->userauth_banner);
|
||||||
|
LIBSSH2_FREE(session, session->userauth_list_data);
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||||
/* Wow, who'dve thought... */
|
/* Wow, who'dve thought... */
|
||||||
@@ -189,6 +223,30 @@ libssh2_userauth_list(LIBSSH2_SESSION * session, const char *user,
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* libssh2_userauth_banner
|
||||||
|
*
|
||||||
|
* Retrieve banner message from server, if available.
|
||||||
|
* If no such message is sent by the server or if no authentication attempt has
|
||||||
|
* been made, this function returns NULL.
|
||||||
|
* libssh2_userauth_list makes a "none" authentication attempt and is
|
||||||
|
* sufficient to collect the pre-auth banner message.
|
||||||
|
*
|
||||||
|
* Banner ought to be UTF-8 encoded, and will be truncated to
|
||||||
|
* LIBSSH2_USERAUTH_MAX_BANNER bytes. Length will be returned in
|
||||||
|
* banner_len_out.
|
||||||
|
*/
|
||||||
|
LIBSSH2_API char *
|
||||||
|
libssh2_userauth_banner(LIBSSH2_SESSION * session,
|
||||||
|
size_t *banner_len_out)
|
||||||
|
{
|
||||||
|
char *ptr = NULL;
|
||||||
|
if (session->userauth_banner) {
|
||||||
|
ptr = session->userauth_banner;
|
||||||
|
*banner_len_out = session->userauth_banner_len;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* libssh2_userauth_authenticated
|
* libssh2_userauth_authenticated
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user