summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libssh/priv.h1
-rw-r--r--include/libssh/session.h17
-rw-r--r--libssh/auth.c22
-rw-r--r--libssh/client.c98
-rw-r--r--libssh/packet.c2
5 files changed, 90 insertions, 50 deletions
diff --git a/include/libssh/priv.h b/include/libssh/priv.h
index 1b751842..1f2a1216 100644
--- a/include/libssh/priv.h
+++ b/include/libssh/priv.h
@@ -123,6 +123,7 @@ int ssh_send_banner(ssh_session session, int is_server);
void ssh_connection_callback(ssh_session session);
SSH_PACKET_CALLBACK(ssh_packet_dh_reply);
SSH_PACKET_CALLBACK(ssh_packet_newkeys);
+SSH_PACKET_CALLBACK(ssh_packet_service_accept);
/* config.c */
int ssh_config_parse_file(ssh_session session, const char *filename);
diff --git a/include/libssh/session.h b/include/libssh/session.h
index c7584994..5cf5af5a 100644
--- a/include/libssh/session.h
+++ b/include/libssh/session.h
@@ -41,6 +41,20 @@ enum ssh_session_state_e {
SSH_SESSION_STATE_ERROR
};
+/** @internal
+ * @brief states of the authentication service request
+ */
+enum ssh_auth_service_state_e {
+ /** initial state */
+ SSH_AUTH_SERVICE_NONE=0,
+ /** Authentication service request packet sent */
+ SSH_AUTH_SERVICE_SENT,
+ /** Service accepted */
+ SSH_AUTH_SERVICE_ACCEPTED,
+ /** Access to service denied (fatal) */
+ SSH_AUTH_SERVICE_DENIED
+};
+
struct ssh_session_struct {
struct error_struct error;
struct ssh_socket_struct *socket;
@@ -60,7 +74,7 @@ struct ssh_session_struct {
/* !=0 when the user got a session handle */
int alive;
/* two previous are deprecated */
- int auth_service_asked;
+// int auth_service_asked;
/* socket status */
int blocking; // functions should block
@@ -78,6 +92,7 @@ struct ssh_session_struct {
enum ssh_session_state_e session_state;
int packet_state;
int dh_handshake_state;
+ enum ssh_auth_service_state_e auth_service_state;
ssh_string dh_server_signature; //information used by dh_handshake.
KEX server_kex;
diff --git a/libssh/auth.c b/libssh/auth.c
index 9349cc72..409917fa 100644
--- a/libssh/auth.c
+++ b/libssh/auth.c
@@ -45,19 +45,23 @@
/** \addtogroup ssh_auth
* @{ */
+/**
+ * @internal
+ * @brief ask access to the ssh-userauth service
+ * @param session SSH session handle
+ * @returns SSH_OK on success
+ * @returns SSH_ERROR on error
+ * @bug current implementation is blocking
+ */
static int ask_userauth(ssh_session session) {
int rc = 0;
enter_function();
-
- if (session->auth_service_asked) {
- rc = 0;
- } else if (ssh_service_request(session,"ssh-userauth")) {
- rc = -1;
- } else {
- session->auth_service_asked++;
- }
-
+ do {
+ rc=ssh_service_request(session,"ssh-userauth");
+ if(rc==SSH_AGAIN)
+ ssh_handle_packets(session);
+ } while(rc==SSH_AGAIN);
leave_function();
return rc;
}
diff --git a/libssh/client.c b/libssh/client.c
index 9af62e2c..5ced48e2 100644
--- a/libssh/client.c
+++ b/libssh/client.c
@@ -468,6 +468,23 @@ error:
/**
* @internal
+ * @brief handles a SSH_SERVICE_ACCEPT packet
+ *
+ */
+SSH_PACKET_CALLBACK(ssh_packet_service_accept){
+ (void)packet;
+ (void)type;
+ (void)user;
+ enter_function();
+ session->auth_service_state=SSH_AUTH_SERVICE_ACCEPTED;
+ ssh_log(session, SSH_LOG_PACKET,
+ "Received SSH_MSG_SERVICE_ACCEPT");
+ leave_function();
+ return SSH_PACKET_USED;
+}
+
+/**
+ * @internal
*
* @brief Request a service from the SSH server.
*
@@ -476,52 +493,55 @@ error:
* @param session The session to use to ask for a service request.
* @param service The service request.
*
- * @return 0 on success, < 0 on error.
+ * @return SSH_OK on success
+ * @return SSH_ERROR on error
+ * @return SSH_AGAIN No response received yet
+ * @bug actually only works with ssh-userauth
*/
int ssh_service_request(ssh_session session, const char *service) {
ssh_string service_s = NULL;
-
+ int rc=SSH_ERROR;
enter_function();
-
- if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_REQUEST) < 0) {
- leave_function();
- return -1;
- }
-
- service_s = string_from_char(service);
- if (service_s == NULL) {
- leave_function();
- return -1;
- }
-
- if (buffer_add_ssh_string(session->out_buffer,service_s) < 0) {
- string_free(service_s);
- leave_function();
- return -1;
- }
- string_free(service_s);
-
- if (packet_send(session) != SSH_OK) {
- ssh_set_error(session, SSH_FATAL,
- "Sending SSH2_MSG_SERVICE_REQUEST failed.");
- leave_function();
- return -1;
+ switch(session->auth_service_state){
+ case SSH_AUTH_SERVICE_NONE:
+ if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_REQUEST) < 0) {
+ break;
+ }
+ service_s = string_from_char(service);
+ if (service_s == NULL) {
+ break;
+ }
+
+ if (buffer_add_ssh_string(session->out_buffer,service_s) < 0) {
+ string_free(service_s);
+ break;
+ }
+ string_free(service_s);
+
+ if (packet_send(session) != SSH_OK) {
+ ssh_set_error(session, SSH_FATAL,
+ "Sending SSH2_MSG_SERVICE_REQUEST failed.");
+ break;
+ }
+
+ ssh_log(session, SSH_LOG_PACKET,
+ "Sent SSH_MSG_SERVICE_REQUEST (service %s)", service);
+ session->auth_service_state=SSH_AUTH_SERVICE_SENT;
+ rc=SSH_AGAIN;
+ break;
+ case SSH_AUTH_SERVICE_DENIED:
+ ssh_set_error(session,SSH_FATAL,"ssh_auth_service request denied");
+ break;
+ case SSH_AUTH_SERVICE_ACCEPTED:
+ rc=SSH_OK;
+ break;
+ case SSH_AUTH_SERVICE_SENT:
+ rc=SSH_AGAIN;
+ break;
}
- ssh_log(session, SSH_LOG_PACKET,
- "Sent SSH_MSG_SERVICE_REQUEST (service %s)", service);
-
- if (packet_wait(session,SSH2_MSG_SERVICE_ACCEPT,1) != SSH_OK) {
- ssh_set_error(session, SSH_FATAL, "Did not receive SERVICE_ACCEPT");
- leave_function();
- return -1;
- }
-
- ssh_log(session, SSH_LOG_PACKET,
- "Received SSH_MSG_SERVICE_ACCEPT (service %s)", service);
-
leave_function();
- return 0;
+ return rc;
}
/** \addtogroup ssh_session
diff --git a/libssh/packet.c b/libssh/packet.c
index dba00772..fb2e5636 100644
--- a/libssh/packet.c
+++ b/libssh/packet.c
@@ -53,7 +53,7 @@ ssh_packet_callback default_packet_handlers[]= {
NULL, //#define SSH2_MSG_UNIMPLEMENTED 3
ssh_packet_ignore_callback, //#define SSH2_MSG_DEBUG 4
NULL, //#define SSH2_MSG_SERVICE_REQUEST 5
- NULL, //#define SSH2_MSG_SERVICE_ACCEPT 6
+ ssh_packet_service_accept, //#define SSH2_MSG_SERVICE_ACCEPT 6
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, // 7-19
ssh_packet_kexinit, //#define SSH2_MSG_KEXINIT 20