예제 #1
0
파일: server.c 프로젝트: alejom200/tmate
int ssh_execute_message_callbacks(ssh_session session){
  ssh_message msg=NULL;
  int ret;
  ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
  if(!session->ssh_message_list)
    return SSH_OK;
  if(session->ssh_message_callback){
    while((msg=ssh_message_pop_head(session)) != NULL) {
      ret=session->ssh_message_callback(session,msg,
                                        session->ssh_message_callback_data);
      if(ret==1){
        ret = ssh_message_reply_default(msg);
        ssh_message_free(msg);
        if(ret != SSH_OK)
          return ret;
      } else {
        ssh_message_free(msg);
      }
    }
  } else {
    while((msg=ssh_message_pop_head(session)) != NULL) {
      ret = ssh_message_reply_default(msg);
      ssh_message_free(msg);
      if(ret != SSH_OK)
        return ret;
    }
  }
  return SSH_OK;
}
예제 #2
0
void server_handle_message(ssh_session s, ssh_message m, int type, int subtype, int *state)
{
    int handled = 0;
    if((*state == SERVER_CONNECTED) && (type == SSH_REQUEST_AUTH) && (subtype == SSH_AUTH_METHOD_PUBLICKEY))
    {
        ssh_public_key key = ssh_message_auth_publickey(m);
        ssh_string keystr = publickey_to_string(key);
        char *keyhash = pubkey_hash(keystr);
        int has_sig = ssh_message_auth_publickey_state(m);
        if(has_sig == SSH_PUBLICKEY_STATE_NONE)
        {
            if(authenticate(keyhash, 1))
            {
                //FIXME: type detection
                ssh_string algostr = ssh_string_from_char("ssh-rsa");
                ssh_message_auth_reply_pk_ok(m, algostr, keystr);
                handled = 1;
                ssh_string_free(algostr);
            }
        }
        else if(has_sig == SSH_PUBLICKEY_STATE_VALID)
        {
            if(authenticate(keyhash, 0))
            {
                session_event(s, "authenticated", keyhash);
                ssh_message_auth_reply_success(m, 0);
                handled = 1;
                *state = SERVER_AUTHENTICATED;
            }
            else
            {
                ssh_message_reply_default(m);
                handled = 1;
                *state = SERVER_CLOSED;
            }
        }
        ssh_string_free(keystr);
        free(keyhash);
    }
    else if((*state == SERVER_AUTHENTICATED) && (type == SSH_REQUEST_CHANNEL_OPEN) && (subtype == SSH_CHANNEL_SESSION))
    {
        ssh_channel chan = ssh_message_channel_request_open_reply_accept(m);
        if(!chan)
            session_error(s, "open-channel");
        handled = 1;
        session_event(s, "channel-opened", NULL);
        channel_to_file(chan, 1);
        ssh_channel_free(chan);
        *state = SERVER_CLOSED;
    }
    if(!handled)
        ssh_message_reply_default(m);
}
예제 #3
0
static int authenticate(ssh_session session) {
    ssh_message message;

    do {
        message=ssh_message_get(session);
        if(!message)
            break;
        switch(ssh_message_type(message)){
            case SSH_REQUEST_AUTH:
                switch(ssh_message_subtype(message)){
                    case SSH_AUTH_METHOD_PASSWORD:
                        printf("User %s wants to auth with pass %s\n",
                               ssh_message_auth_user(message),
                               ssh_message_auth_password(message));
                        if(auth_password(ssh_message_auth_user(message),
                           ssh_message_auth_password(message))){
                               ssh_message_auth_reply_success(message,0);
                               ssh_message_free(message);
                               return 1;
                           }
                        ssh_message_auth_set_methods(message,
                                                SSH_AUTH_METHOD_PASSWORD |
                                                SSH_AUTH_METHOD_INTERACTIVE);
                        // not authenticated, send default message
                        ssh_message_reply_default(message);
                        break;

                    case SSH_AUTH_METHOD_NONE:
                    default:
                        printf("User %s wants to auth with unknown auth %d\n",
                               ssh_message_auth_user(message),
                               ssh_message_subtype(message));
                        ssh_message_auth_set_methods(message,
                                                SSH_AUTH_METHOD_PASSWORD |
                                                SSH_AUTH_METHOD_INTERACTIVE);
                        ssh_message_reply_default(message);
                        break;
                }
                break;
            default:
                ssh_message_auth_set_methods(message,
                                                SSH_AUTH_METHOD_PASSWORD |
                                                SSH_AUTH_METHOD_INTERACTIVE);
                ssh_message_reply_default(message);
        }
        ssh_message_free(message);
    } while (1);
    return 0;
}
예제 #4
0
파일: messages.c 프로젝트: magnum/tmate
/**
 * @internal
 *
 * @brief Add a message to the current queue of messages to be parsed and/or call
 * the various callback functions.
 *
 * @param[in]  session  The SSH session to add the message.
 *
 * @param[in]  message  The message to add to the queue.
 */
void ssh_message_queue(ssh_session session, ssh_message message){
    if (message != NULL) {
#ifdef WITH_SERVER
	int ret;
        /* probably not the best place to execute server callbacks, but still better
         * than nothing.
         */
        ret = ssh_execute_server_callbacks(session, message);
        if (ret == SSH_OK){
            ssh_message_free(message);
            return;
        }
#endif /* WITH_SERVER */
        if(session->ssh_message_callback != NULL) {
            ssh_execute_message_callback(session, message);
            return;
        }
        if (session->server_callbacks != NULL){
            /* if we have server callbacks, but nothing was executed, it means we are
             * in non-synchronous mode, and we just don't care about the message we
             * received. Just send a default response. Do not queue it.
             */
            ssh_message_reply_default(message);
            ssh_message_free(message);
            return;
        }
        if(session->ssh_message_list == NULL) {
            session->ssh_message_list = ssh_list_new();
        }
        if (session->ssh_message_list != NULL) {
            ssh_list_append(session->ssh_message_list, message);
        }
    }
}
예제 #5
0
파일: messages.c 프로젝트: magnum/tmate
static int ssh_execute_client_request(ssh_session session, ssh_message msg)
{
    ssh_channel channel = NULL;
    int rc = SSH_AGAIN;

    if (msg->type == SSH_REQUEST_CHANNEL_OPEN
        && msg->channel_request_open.type == SSH_CHANNEL_X11
        && ssh_callbacks_exists(session->common.callbacks, channel_open_request_x11_function)) {
        channel = session->common.callbacks->channel_open_request_x11_function (session,
                msg->channel_request_open.originator,
                msg->channel_request_open.originator_port,
                session->common.callbacks->userdata);
        if (channel != NULL) {
            rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel);

            return rc;
        } else {
            ssh_message_reply_default(msg);
        }

        return SSH_OK;
    }

    return rc;
}
예제 #6
0
파일: auth.c 프로젝트: gregtampa/sshpot
/* Logs password auth attempts. Always replies with SSH_MESSAGE_USERAUTH_FAILURE. */
int handle_auth(ssh_session session) {
    struct connection con;
    con.session = session;

    /* Perform key exchange. */
    if (ssh_handle_key_exchange(con.session)) {
        fprintf(stderr, "Error exchanging keys: `%s'.\n", ssh_get_error(con.session));
        return -1;
    }
    if (DEBUG) { printf("Successful key exchange.\n"); }

    /* Wait for a message, which should be an authentication attempt. Send the default
     * reply if it isn't. Log the attempt and quit. */
    while (1) {
        if ((con.message = ssh_message_get(con.session)) == NULL) {
            break;
        }

        /* Log the authentication request and disconnect. */
        if (ssh_message_subtype(con.message) == SSH_AUTH_METHOD_PASSWORD) {
                log_attempt(&con);
        }
        else {
            if (DEBUG) { fprintf(stderr, "Not a password authentication attempt.\n"); }
        }

        /* Send the default message regardless of the request type. */
        ssh_message_reply_default(con.message);
        ssh_message_free(con.message);
    }

    if (DEBUG) { printf("Exiting child.\n"); }
    return 0;
}
예제 #7
0
CHANNEL *recv_channel(SSH_SESSION *session){
    CHANNEL *chan=NULL;
    SSH_MESSAGE *message;
    int sftp=0;
    do {
        message=ssh_message_get(session);
        if(message){
            switch(ssh_message_type(message)){
                case SSH_CHANNEL_REQUEST_OPEN:
                    if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
                        chan=ssh_message_channel_request_open_reply_accept(message);
                        break;
                    }
                default:
                    ssh_message_reply_default(message);
            }
            ssh_message_free(message);
        }
    } while(message && !chan);
    if(!chan)
        return NULL;
    do {
        message=ssh_message_get(session);
        if(message && ssh_message_type(message)==SSH_CHANNEL_REQUEST && 
           ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SUBSYSTEM){
            if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
                sftp=1;
                ssh_message_channel_request_reply_success(message);
                break;
            }
           }
           if(!sftp){
               ssh_message_reply_default(message);
           }
           ssh_message_free(message);
    } while (message && !sftp);
    if(!message)
        return NULL;
    return chan;
}
예제 #8
0
파일: messages.c 프로젝트: magnum/tmate
static int ssh_execute_message_callback(ssh_session session, ssh_message msg) {
	int ret;
    if(session->ssh_message_callback != NULL) {
        ret = session->ssh_message_callback(session, msg,
                session->ssh_message_callback_data);
        if(ret == 1) {
            ret = ssh_message_reply_default(msg);
            ssh_message_free(msg);
            if(ret != SSH_OK) {
                return ret;
            }
        } else {
            ssh_message_free(msg);
        }
    } else {
        ret = ssh_message_reply_default(msg);
        ssh_message_free(msg);
        if(ret != SSH_OK) {
            return ret;
        }
    }
    return SSH_OK;
}
예제 #9
0
int main(int argc, char **argv){
    ssh_session session;
    ssh_bind sshbind;
    ssh_message message;
    ssh_channel chan=0;
    char buf[2048];
    int auth=0;
    int sftp=0;
    int i;
    int r;

    sshbind=ssh_bind_new();
    session=ssh_new();

    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");

#ifdef HAVE_ARGP_H
    /*
     * Parse our arguments; every option seen by parse_opt will
     * be reflected in arguments.
     */
    argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
    (void) argc;
    (void) argv;
#endif
#ifdef WITH_PCAP
    set_pcap(session);
#endif

    if(ssh_bind_listen(sshbind)<0){
        printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
        return 1;
    }
    r=ssh_bind_accept(sshbind,session);
    if(r==SSH_ERROR){
      printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
      return 1;
    }
    if (ssh_handle_key_exchange(session)) {
        printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
        return 1;
    }
    do {
        message=ssh_message_get(session);
        if(!message)
            break;
        switch(ssh_message_type(message)){
            case SSH_REQUEST_AUTH:
                switch(ssh_message_subtype(message)){
                    case SSH_AUTH_METHOD_PASSWORD:
                        printf("User %s wants to auth with pass %s\n",
                               ssh_message_auth_user(message),
                               ssh_message_auth_password(message));
                        if(auth_password(ssh_message_auth_user(message),
                           ssh_message_auth_password(message))){
                               auth=1;
                               ssh_message_auth_reply_success(message,0);
                               break;
                           }
                        // not authenticated, send default message
                    case SSH_AUTH_METHOD_NONE:
                    default:
                        ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
                        ssh_message_reply_default(message);
                        break;
                }
                break;
            default:
                ssh_message_reply_default(message);
        }
        ssh_message_free(message);
    } while (!auth);
    if(!auth){
        printf("auth error: %s\n",ssh_get_error(session));
        ssh_disconnect(session);
        return 1;
    }
    do {
        message=ssh_message_get(session);
        if(message){
            switch(ssh_message_type(message)){
                case SSH_REQUEST_CHANNEL_OPEN:
                    if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
                        chan=ssh_message_channel_request_open_reply_accept(message);
                        break;
                    }
                default:
                ssh_message_reply_default(message);
            }
            ssh_message_free(message);
        }
    } while(message && !chan);
    if(!chan){
        printf("error : %s\n",ssh_get_error(session));
        ssh_finalize();
        return 1;
    }
    do {
        message=ssh_message_get(session);
        if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL &&
           ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){
//            if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
                sftp=1;
                ssh_message_channel_request_reply_success(message);
                break;
 //           }
           }
        if(!sftp){
            ssh_message_reply_default(message);
        }
        ssh_message_free(message);
    } while (message && !sftp);
    if(!sftp){
        printf("error : %s\n",ssh_get_error(session));
        return 1;
    }
    printf("it works !\n");
    do{
        i=ssh_channel_read(chan,buf, 2048, 0);
        if(i>0) {
            ssh_channel_write(chan, buf, i);
            if (write(1,buf,i) < 0) {
                printf("error writing to buffer\n");
                return 1;
            }
        }
    } while (i>0);
    ssh_disconnect(session);
    ssh_bind_free(sshbind);
#ifdef WITH_PCAP
    cleanup_pcap();
#endif
    ssh_finalize();
    return 0;
}
예제 #10
0
int main(int argc, char **argv){
    ssh_session session;
    ssh_bind sshbind;
    ssh_message message;
    ssh_channel chan=0;
    char buf[2048];
    int auth=0;
    int shell=0;
    int i;
    int r;

    sshbind=ssh_bind_new();
    session=ssh_new();

    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
                                            KEYS_FOLDER "ssh_host_dsa_key");
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
                                            KEYS_FOLDER "ssh_host_rsa_key");

#ifdef HAVE_ARGP_H
    /*
     * Parse our arguments; every option seen by parse_opt will
     * be reflected in arguments.
     */
    argp_parse (&argp, argc, argv, 0, 0, sshbind);
#else
    (void) argc;
    (void) argv;
#endif
#ifdef WITH_PCAP
    set_pcap(session);
#endif

    if(ssh_bind_listen(sshbind)<0){
        printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
        return 1;
    }
    printf("Started sample libssh sshd on port %d\n", port);
    printf("You can login as the user %s with the password %s\n", SSHD_USER,
                                                            SSHD_PASSWORD);
    r = ssh_bind_accept(sshbind, session);
    if(r==SSH_ERROR){
      printf("Error accepting a connection: %s\n", ssh_get_error(sshbind));
      return 1;
    }
    if (ssh_handle_key_exchange(session)) {
        printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
        return 1;
    }

    /* proceed to authentication */
    auth = authenticate(session);
    if (!auth || !authenticated) {
        printf("Authentication error: %s\n", ssh_get_error(session));
        ssh_disconnect(session);
        return 1;
    }


    /* wait for a channel session */
    do {
        message = ssh_message_get(session);
        if(message){
            if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN &&
                    ssh_message_subtype(message) == SSH_CHANNEL_SESSION) {
                chan = ssh_message_channel_request_open_reply_accept(message);
                ssh_message_free(message);
                break;
            } else {
                ssh_message_reply_default(message);
                ssh_message_free(message);
            }
        } else {
            break;
        }
    } while(!chan);

    if(!chan) {
        printf("Error: cleint did not ask for a channel session (%s)\n",
                                                    ssh_get_error(session));
        ssh_finalize();
        return 1;
    }


    /* wait for a shell */
    do {
        message = ssh_message_get(session);
        if(message != NULL) {
            if(ssh_message_type(message) == SSH_REQUEST_CHANNEL &&
                    ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) {
                shell = 1;
                ssh_message_channel_request_reply_success(message);
                ssh_message_free(message);
                break;
            }
            ssh_message_reply_default(message);
            ssh_message_free(message);
        } else {
            break;
        }
    } while(!shell);

    if(!shell) {
        printf("Error: No shell requested (%s)\n", ssh_get_error(session));
        return 1;
    }


    printf("it works !\n");
    do{
        i=ssh_channel_read(chan,buf, 2048, 0);
        if(i>0) {
            if(*buf == '' || *buf == '')
                    break;
            if(i == 1 && *buf == '\r')
                ssh_channel_write(chan, "\r\n", 2);
            else
                ssh_channel_write(chan, buf, i);
            if (write(1,buf,i) < 0) {
                printf("error writing to buffer\n");
                return 1;
            }
        }
    } while (i>0);
    ssh_channel_close(chan);
    ssh_disconnect(session);
    ssh_bind_free(sshbind);
#ifdef WITH_PCAP
    cleanup_pcap();
#endif
    ssh_finalize();
    return 0;
}
예제 #11
0
static int authenticate(ssh_session session) {
    ssh_message message;

    name = "\n\nKeyboard-Interactive Fancy Authentication\n";
    instruction = "Please enter your real name and your password";
    prompts[0] = "Real name: ";
    prompts[1] = "Password: "******"User %s wants to auth with pass %s\n",
                               ssh_message_auth_user(message),
                               ssh_message_auth_password(message));
                        if(auth_password(ssh_message_auth_user(message),
                           ssh_message_auth_password(message))){
                               ssh_message_auth_reply_success(message,0);
                               ssh_message_free(message);
                               return 1;
                           }
                        ssh_message_auth_set_methods(message,
                                                SSH_AUTH_METHOD_PASSWORD |
                                                SSH_AUTH_METHOD_INTERACTIVE);
                        // not authenticated, send default message
                        ssh_message_reply_default(message);
                        break;

                    case SSH_AUTH_METHOD_INTERACTIVE:
                        if(!ssh_message_auth_kbdint_is_response(message)) {
                            printf("User %s wants to auth with kbdint\n",
                                   ssh_message_auth_user(message));
                            ssh_message_auth_interactive_request(message, name,
                                                    instruction, 2, prompts, echo);
                        } else {
                            if(kbdint_check_response(session)) {
                                ssh_message_auth_reply_success(message,0);
                                ssh_message_free(message);
                                return 1;
                            }
                            ssh_message_auth_set_methods(message,
                                                    SSH_AUTH_METHOD_PASSWORD |
                                                    SSH_AUTH_METHOD_INTERACTIVE);
                            ssh_message_reply_default(message);
                        }
                        break;
                    case SSH_AUTH_METHOD_NONE:
                    default:
                        printf("User %s wants to auth with unknown auth %d\n",
                               ssh_message_auth_user(message),
                               ssh_message_subtype(message));
                        ssh_message_auth_set_methods(message,
                                                SSH_AUTH_METHOD_PASSWORD |
                                                SSH_AUTH_METHOD_INTERACTIVE);
                        ssh_message_reply_default(message);
                        break;
                }
                break;
            default:
                ssh_message_auth_set_methods(message,
                                                SSH_AUTH_METHOD_PASSWORD |
                                                SSH_AUTH_METHOD_INTERACTIVE);
                ssh_message_reply_default(message);
        }
        ssh_message_free(message);
    } while (1);
    return 0;
}
예제 #12
0
// Parse an SSH command message and do something
bool
SSHServer::processSSHMessage(ssh_message message)
{
    if (!message) {
	return false;
    }
    switch(ssh_message_type(message)){
    case SSH_REQUEST_AUTH:
	switch(ssh_message_subtype(message)) {
	    // not authenticated, send default message
 	case SSH_AUTH_METHOD_NONE:
 	    break;
	case SSH_AUTH_METHOD_PASSWORD:
	    {
		log_debug(_("User %s wants to auth with pass %s\n"),
			  ssh_message_auth_user(message),
			  ssh_message_auth_password(message));
		string user = ssh_message_auth_user(message);
		string passwd = ssh_message_auth_password(message);
		if (authPassword(user, passwd)){
		    // 		auth=1;
		    ssh_message_auth_reply_success(message,0);
		    break;
		}
		break;
	    }
	case SSH_AUTH_METHOD_HOSTBASED:
	    break;
	case SSH_AUTH_METHOD_PUBLICKEY:
	    break;
	case SSH_AUTH_METHOD_INTERACTIVE:
	    break;
	case SSH_AUTH_METHOD_UNKNOWN:
	    break;
	default:
	    ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
	    ssh_message_reply_default(message);
	    break;
	}
    case SSH_REQUEST_CHANNEL_OPEN:
	if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
	    _channel = ssh_message_channel_request_open_reply_accept(message);
	    break;
	}
	break;
//     case SSH_CHANNEL_REQUEST_EXEC:
// 	break;
    case SSH_CHANNEL_REQUEST_ENV:
	break;
    case SSH_CHANNEL_REQUEST_SUBSYSTEM:
	break;
    case SSH_CHANNEL_REQUEST_WINDOW_CHANGE:
	break;
    case SSH_CHANNEL_REQUEST_UNKNOWN:
	break;
    default:
	ssh_message_reply_default(message);
    }
    ssh_message_free(message);

    return false;
}
예제 #13
0
파일: messages.c 프로젝트: magnum/tmate
static int ssh_execute_server_request(ssh_session session, ssh_message msg)
{
    ssh_channel channel = NULL;
    int rc;

    switch(msg->type) {
        case SSH_REQUEST_AUTH:
            if (msg->auth_request.method == SSH_AUTH_METHOD_PASSWORD &&
                ssh_callbacks_exists(session->server_callbacks, auth_password_function)) {
                rc = session->server_callbacks->auth_password_function(session,
                        msg->auth_request.username, msg->auth_request.password,
                        session->server_callbacks->userdata);
                if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL) {
                    ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if(msg->auth_request.method == SSH_AUTH_METHOD_PUBLICKEY &&
                      ssh_callbacks_exists(session->server_callbacks, auth_pubkey_function)) {
               rc = session->server_callbacks->auth_pubkey_function(session,
                       msg->auth_request.username, msg->auth_request.pubkey,
                       msg->auth_request.signature_state,
                       session->server_callbacks->userdata);
               if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL){
                   ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL);
               } else {
                   ssh_message_reply_default(msg);
               }

               return SSH_OK;
            }
            break;
        case SSH_REQUEST_CHANNEL_OPEN:
            if (msg->channel_request_open.type == SSH_CHANNEL_SESSION &&
                ssh_callbacks_exists(session->server_callbacks, channel_open_request_session_function)) {
                channel = session->server_callbacks->channel_open_request_session_function(session,
                        session->server_callbacks->userdata);
                if (channel != NULL) {
                    rc = ssh_message_channel_request_open_reply_accept_channel(msg, channel);
                    return SSH_OK;
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            }
            break;
        case SSH_REQUEST_CHANNEL:
            channel = msg->channel_request.channel;

            if (msg->channel_request.type == SSH_CHANNEL_REQUEST_PTY &&
                ssh_callbacks_exists(channel->callbacks, channel_pty_request_function)) {
                rc = channel->callbacks->channel_pty_request_function(session, channel,
                        msg->channel_request.TERM,
                        msg->channel_request.width, msg->channel_request.height,
                        msg->channel_request.pxwidth, msg->channel_request.pxheight,
                        channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_SHELL &&
                      ssh_callbacks_exists(channel->callbacks, channel_shell_request_function)) {
                rc = channel->callbacks->channel_shell_request_function(session,
                                                                        channel,
                                                                        channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_X11 &&
                      ssh_callbacks_exists(channel->callbacks, channel_x11_req_function)) {
                channel->callbacks->channel_x11_req_function(session,
                                                             channel,
                                                             msg->channel_request.x11_single_connection,
                                                             msg->channel_request.x11_auth_protocol,
                                                             msg->channel_request.x11_auth_cookie,
                                                             msg->channel_request.x11_screen_number,
                                                             channel->callbacks->userdata);
                ssh_message_channel_request_reply_success(msg);

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_WINDOW_CHANGE &&
                       ssh_callbacks_exists(channel->callbacks, channel_pty_window_change_function)) {
                rc = channel->callbacks->channel_pty_window_change_function(session,
                                                                            channel,
                                                                            msg->channel_request.height, msg->channel_request.width,
                                                                            msg->channel_request.pxheight, msg->channel_request.pxwidth,
                                                                            channel->callbacks->userdata);
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_EXEC &&
                       ssh_callbacks_exists(channel->callbacks, channel_exec_request_function)) {
                rc = channel->callbacks->channel_exec_request_function(session,
                                                                       channel,
                                                                       msg->channel_request.command,
                                                                       channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_ENV &&
                       ssh_callbacks_exists(channel->callbacks, channel_env_request_function)) {
                rc = channel->callbacks->channel_env_request_function(session,
                                                                      channel,
                                                                      msg->channel_request.var_name, msg->channel_request.var_value,
                                                                      channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            } else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_SUBSYSTEM &&
                       ssh_callbacks_exists(channel->callbacks, channel_subsystem_request_function)) {
                rc = channel->callbacks->channel_subsystem_request_function(session,
                                                                            channel,
                                                                            msg->channel_request.subsystem,
                                                                            channel->callbacks->userdata);
                if (rc == 0) {
                    ssh_message_channel_request_reply_success(msg);
                } else {
                    ssh_message_reply_default(msg);
                }

                return SSH_OK;
            }
            break;
        case SSH_REQUEST_SERVICE:
            if (ssh_callbacks_exists(session->server_callbacks, service_request_function)) {
                rc = session->server_callbacks->service_request_function(session,
                        msg->service_request.service, session->server_callbacks->userdata);
                if (rc == 0) {
                    ssh_message_reply_default(msg);
                } else {
                    ssh_disconnect(session);
                }

                return SSH_OK;
            }

            return SSH_AGAIN;
        case SSH_REQUEST_GLOBAL:
            break;
    }

    return SSH_AGAIN;
}