Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  scp.c

  Sprache: C
 

/**
 * xrdp: A Remote Desktop Protocol server.
 *
 * Copyright (C) Jay Sorg 2004-2022, all xrdp contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


/**
 *
 * @file libipm/scp.c
 * @brief scp definitions
 * @author Simone Fedele/ Matt Burt
 */


#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif

#include <ctype.h>

#include "scp.h"
#include "libipm.h"
#include "guid.h"
#include "trans.h"
#include "os_calls.h"
#include "string_calls.h"
#include "xrdp_sockets.h"

/*****************************************************************************/
static const char *
msgno_to_str(unsigned short n)
{
    return
        (n == E_SCP_SET_PEERNAME_REQUEST) ? "SCP_SET_PEERNAME_REQUEST" :

        (n == E_SCP_SYS_LOGIN_REQUEST) ? "SCP_SYS_LOGIN_REQUEST" :
        (n == E_SCP_UDS_LOGIN_REQUEST) ? "SCP_UDS_LOGIN_REQUEST" :
        (n == E_SCP_LOGIN_RESPONSE) ? "SCP_LOGIN_RESPONSE" :

        (n == E_SCP_LOGOUT_REQUEST) ? "SCP_LOGOUT_REQUEST" :

        (n == E_SCP_CREATE_SESSION_REQUEST) ? "SCP_CREATE_SESSION_REQUEST" :
        (n == E_SCP_CREATE_SESSION_RESPONSE) ? "SCP_CREATE_SESSION_RESPONSE" :

        (n == E_SCP_LIST_SESSIONS_REQUEST) ? "SCP_LIST_SESSIONS_REQUEST" :
        (n == E_SCP_LIST_SESSIONS_RESPONSE) ? "SCP_LIST_SESSIONS_RESPONSE" :

        (n == E_SCP_CLOSE_CONNECTION_REQUEST) ? "SCP_CLOSE_CONNECTION_REQUEST" :
        NULL;
}

/*****************************************************************************/
const char *
scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size)
{
    const char *str = msgno_to_str((unsigned short)n);

    if (str == NULL)
    {
        g_snprintf(buff, buff_size, "[code #%d]", (int)n);
    }
    else
    {
        g_snprintf(buff, buff_size, "%s", str);
    }

    return buff;
}

/*****************************************************************************/
/**
 * Helper function returning 1 if the passed-in string is an integer >= 0
 */

static int is_positive_int(const char *s)
{
    for ( ; *s != '\0' ; ++s)
    {
        if (!isdigit(*s))
        {
            return 0;
        }
    }

    return 1;
}

/*****************************************************************************/
int
scp_port_to_unix_domain_path(const char *port, char *buff,
                             unsigned int bufflen)
{
    /* GOTCHA: Changes to this logic should be mirrored in
     * scp_port_to_display_string() */


    int result;

    /* Make sure we can safely de-reference 'port' */
    if (port == NULL)
    {
        port = "";
    }

    if (port[0] == '/')
    {
        result = g_snprintf(buff, bufflen, "%s", port);
    }
    else
    {
        const char *sep;
        if ((sep = g_strrchr(port, '/')) != NULL && sep != port)
        {
            /* We allow the user to specify an absolute path, but not
             * a relative one with embedded '/' characters */

            LOG(LOG_LEVEL_WARNING, "Ignoring path elements of '%s'", port);
            port = sep + 1;
        }

        if (port[0] == '\0')
        {
            port = SCP_LISTEN_PORT_BASE_STR;
        }
        else if (is_positive_int(port))
        {
            /* Version v0.9.x and earlier of xrdp used a TCP port
             * number. If we come across this, we'll ignore it for
             * compatibility with old config files */

            LOG(LOG_LEVEL_WARNING,
                "Ignoring obsolete SCP port value '%s'", port);
            port = SCP_LISTEN_PORT_BASE_STR;
        }

        result = g_snprintf(buff, bufflen, XRDP_SOCKET_ROOT_PATH "/%s", port);
    }

    return result;
}

/*****************************************************************************/
int
scp_port_to_display_string(const char *port, char *buff, unsigned int bufflen)
{
    /* Make sure we can safely de-reference 'port' */
    if (port == NULL)
    {
        port = "";
    }

    /* Ignore any directories for the display */
    const char *sep;
    if ((sep = g_strrchr(port, '/')) != NULL)
    {
        port = sep + 1;
    }

    /* Check for a default */
    if (port[0] == '\0' || g_strcmp(port, "3350") == 0)
    {
        port = SCP_LISTEN_PORT_BASE_STR;
    }

    return g_snprintf(buff, bufflen, "%s", port);
}

/*****************************************************************************/
struct trans *
scp_connect(const  char *port,
            const char *peername,
            int (*term_func)(void))
{
    char sock_path[256];
    struct trans *t;

    (void)scp_port_to_unix_domain_path(port, sock_path, sizeof(sock_path));
    if ((t = trans_create(TRANS_MODE_UNIX, 128128)) != NULL)
    {
        t->is_term = term_func;

        if (trans_connect(t, NULL, sock_path, 3000) != 0)
        {
            trans_delete(t);
            t = NULL;
        }
        else if (scp_init_trans(t) != 0)
        {
            trans_delete(t);
            t = NULL;
        }
        else if (scp_send_set_peername_request(t, peername) != 0)
        {
            trans_delete(t);
            t = NULL;
        }
    }

    return t;
}

/*****************************************************************************/
int
scp_init_trans(struct trans *trans)
{
    return libipm_init_trans(trans, LIBIPM_FAC_SCP, msgno_to_str);
}

/*****************************************************************************/
struct trans *
scp_init_trans_from_fd(int fd, int trans_type, int (*term_func)(void))
{
    struct trans *result;
    if ((result = trans_create(TRANS_MODE_UNIX, 128128)) == NULL)
    {
        LOG(LOG_LEVEL_ERROR, "Can't create SCP transport [%s]",
            g_get_strerror());
    }
    else
    {
        result->sck = fd;
        result->type1 = trans_type;
        result->status = TRANS_STATUS_UP;
        result->is_term = term_func;

        // Make sure child processes don't inherit our FD
        (void)g_file_set_cloexec(result->sck, 1);

        if (scp_init_trans(result) != 0)
        {
            LOG(LOG_LEVEL_ERROR, "scp_init_trans() call failed");
            trans_delete(result);
            result = NULL;
        }
    }

    return result;
}


/*****************************************************************************/
int
scp_msg_in_check_available(struct trans *trans, int *available)
{
    return libipm_msg_in_check_available(trans, available);
}

/*****************************************************************************/

int
scp_msg_in_wait_available(struct trans *trans)
{
    return libipm_msg_in_wait_available(trans);
}

/*****************************************************************************/

enum scp_msg_code
scp_msg_in_get_msgno(const struct trans *trans)
{
    return (enum scp_msg_code)libipm_msg_in_get_msgno(trans);
}

/*****************************************************************************/

void
scp_msg_in_reset(struct trans *trans)
{
    libipm_msg_in_reset(trans);
}

/*****************************************************************************/
int
scp_send_set_peername_request(struct trans *trans,
                              const char *peername)
{
    return libipm_msg_out_simple_send(
               trans,
               (int)E_SCP_SET_PEERNAME_REQUEST,
               "s",
               peername);
}

/*****************************************************************************/

int
scp_get_set_peername_request(struct trans *trans,
                             const char **peername)
{
    return libipm_msg_in_parse( trans, "s", peername);
}


/*****************************************************************************/
int
scp_send_uds_login_request(struct trans *trans)
{
    return libipm_msg_out_simple_send(trans,
                                      (int)E_SCP_UDS_LOGIN_REQUEST,
                                      NULL);
}


/*****************************************************************************/
int
scp_send_sys_login_request(struct trans *trans,
                           const char *username,
                           const char *password,
                           const char *ip_addr)
{
    int rv;

    rv = libipm_msg_out_simple_send(
             trans,
             (int)E_SCP_SYS_LOGIN_REQUEST,
             "sss",
             username,
             password,
             ip_addr);

    /* Wipe the output buffer to remove the password */
    libipm_msg_out_erase(trans);

    return rv;
}

/*****************************************************************************/

int
scp_get_sys_login_request(struct trans *trans,
                          const char **username,
                          const char **password,
                          const char **ip_addr)
{
    /* Make sure the buffer is cleared after processing this message */
    libipm_set_flags(trans, LIBIPM_E_MSG_IN_ERASE_AFTER_USE);

    return libipm_msg_in_parse( trans, "sss",
                                username, password, ip_addr);
}

/*****************************************************************************/

int
scp_send_login_response(struct trans *trans,
                        enum scp_login_status login_result,
                        int server_closed,
                        int uid)
{
    return libipm_msg_out_simple_send(
               trans,
               (int)E_SCP_LOGIN_RESPONSE,
               "ibi",
               login_result,
               (server_closed != 0), /* Convert to 0/1 */
               uid);
}

/*****************************************************************************/

int
scp_get_login_response(struct trans *trans,
                       enum scp_login_status *login_result,
                       int *server_closed,
                       int *uid)
{
    int32_t i_login_result = 0;
    int32_t i_uid = 0;
    int dummy;

    /* User can pass in NULL for server_closed if they're trying an
     * login method like UDS for which all fails are fatal. Likewise
     * they may be uninterested in the uid */

    if (server_closed == NULL)
    {
        server_closed = &dummy;
    }
    if (uid == NULL)
    {
        uid = &dummy;
    }

    int rv = libipm_msg_in_parse(trans, "ibi",
                                 &i_login_result, server_closed, &i_uid);
    if (rv == 0)
    {
        *login_result = (enum scp_login_status)i_login_result;
        *uid = i_uid;
    }

    return rv;
}

/*****************************************************************************/

int
scp_send_logout_request(struct trans *trans)
{
    return libipm_msg_out_simple_send( trans, (int)E_SCP_LOGOUT_REQUEST, NULL);
}


/*****************************************************************************/

int
scp_send_create_session_request(struct trans *trans,
                                enum scp_session_type type,
                                unsigned short width,
                                unsigned short height,
                                unsigned char bpp,
                                const char *shell,
                                const char *directory)
{
    return libipm_msg_out_simple_send(
               trans,
               (int)E_SCP_CREATE_SESSION_REQUEST,
               "yqqyss",
               type,
               width,
               height,
               bpp,
               shell,
               directory);
}

/*****************************************************************************/

int
scp_get_create_session_request(struct trans *trans,
                               enum scp_session_type *type,
                               unsigned short *width,
                               unsigned short *height,
                               unsigned char *bpp,
                               const char **shell,
                               const char **directory)
{
    /* Intermediate values */
    uint8_t i_type;
    uint16_t i_width;
    uint16_t i_height;
    uint8_t i_bpp;

    int rv = libipm_msg_in_parse(
                 trans,
                 "yqqyss",
                 &i_type,
                 &i_width,
                 &i_height,
                 &i_bpp,
                 shell,
                 directory);

    if (rv == 0)
    {
        *type = (enum scp_session_type)i_type;
        *width = i_width;
        *height = i_height;
        /* bpp is fixed for Xorg session types */
        *bpp = (*type == SCP_SESSION_TYPE_XORG) ? 24 : i_bpp;
    }

    return rv;
}

/*****************************************************************************/

int
scp_send_create_session_response(struct trans *trans,
                                 enum scp_screate_status status,
                                 int display,
                                 const struct guid *guid)
{
    struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) };

    return libipm_msg_out_simple_send(
               trans,
               (int)E_SCP_CREATE_SESSION_RESPONSE,
               "iiB",
               status,
               display,
               &guid_descriptor);
}

/*****************************************************************************/

int
scp_get_create_session_response(struct trans *trans,
                                enum scp_screate_status *status,
                                int *display,
                                struct guid *guid)
{
    /* Intermediate values */
    int32_t i_status;
    int32_t i_display;

    const struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) };

    int rv = libipm_msg_in_parse(
                 trans,
                 "iiB",
                 &i_status,
                 &i_display,
                 &guid_descriptor);
    if (rv == 0)
    {
        *status = (enum scp_screate_status)i_status;
        *display = i_display;
    }

    return rv;
}

/*****************************************************************************/

int
scp_send_list_sessions_request(struct trans *trans)
{
    return libipm_msg_out_simple_send(
               trans,
               (int)E_SCP_LIST_SESSIONS_REQUEST,
               NULL);
}

/*****************************************************************************/

int
scp_send_list_sessions_response(
    struct trans *trans,
    enum scp_list_sessions_status status,
    const struct scp_session_info *info)
{
    int rv;

    if (status != E_SCP_LS_SESSION_INFO)
    {
        rv = libipm_msg_out_simple_send(
                 trans,
                 (int)E_SCP_LIST_SESSIONS_RESPONSE,
                 "i", status);
    }
    else
    {
        rv = libipm_msg_out_simple_send(
                 trans,
                 (int)E_SCP_LIST_SESSIONS_RESPONSE,
                 "iiuyqqyxis",
                 status,
                 info->sid,
                 info->display,
                 info->type,
                 info->width,
                 info->height,
                 info->bpp,
                 info->start_time,
                 info->uid,
                 info->start_ip_addr);
    }

    return rv;
}

/*****************************************************************************/

int
scp_get_list_sessions_response(
    struct trans *trans,
    enum scp_list_sessions_status *status,
    struct scp_session_info **info)
{
    int32_t i_status;
    int rv;

    if (info == NULL)
    {
        LOG_DEVEL(LOG_LEVEL_ERROR, "Bad pointer in %s", __func__);
        rv = 1;
    }
    else if ((rv = libipm_msg_in_parse(trans, "i", &i_status)) == 0)
    {
        *status = (enum scp_list_sessions_status)i_status;
        struct scp_session_info *p = NULL;

        if (*status == E_SCP_LS_SESSION_INFO)
        {
            int32_t i_sid;
            uint32_t i_display;
            uint8_t i_type;
            uint16_t i_width;
            uint16_t i_height;
            uint8_t i_bpp;
            int64_t i_start_time;
            int32_t i_uid;
            char *i_start_ip_addr;

            rv = libipm_msg_in_parse(
                     trans,
                     "iuyqqyxis",
                     &i_sid,
                     &i_display,
                     &i_type,
                     &i_width,
                     &i_height,
                     &i_bpp,
                     &i_start_time,
                     &i_uid,
                     &i_start_ip_addr);

            if (rv == 0)
            {
                /* Allocate a block of memory large enough for the
                 * structure result, and the strings it contains */

                unsigned int len = sizeof(struct scp_session_info) +
                                   g_strlen(i_start_ip_addr) + 1;
                if ((p = (struct scp_session_info *)g_malloc(len, 1)) == NULL)
                {
                    *status = E_SCP_LS_NO_MEMORY;
                }
                else
                {
                    /* Set up the string pointers in the block to point
                     * into the memory allocated after the block */

                    p->start_ip_addr =
                        (char *)p + sizeof(struct scp_session_info);

                    /* Copy the data over */
                    p->sid = i_sid;
                    p->display = i_display;
                    p->type = (enum scp_session_type)i_type;
                    p->width = i_width;
                    p->height = i_height;
                    p->bpp = i_bpp;
                    p->start_time = i_start_time;
                    p->uid = i_uid;
                    g_strcpy(p->start_ip_addr, i_start_ip_addr);
                }
            }
        }
        *info = p;
    }
    return rv;
}

/*****************************************************************************/

int
scp_send_create_sockdir_request(struct trans *trans)
{
    return libipm_msg_out_simple_send(
               trans,
               (int)E_SCP_CREATE_SOCKDIR_REQUEST,
               NULL);
}


/*****************************************************************************/

int
scp_send_create_sockdir_response(struct trans *trans,
                                 enum scp_create_sockdir_status status)
{
    return libipm_msg_out_simple_send(
               trans,
               (int)E_SCP_CREATE_SOCKDIR_RESPONSE,
               "i", status);
}

/*****************************************************************************/

int
scp_get_create_sockdir_response(struct trans *trans,
                                enum scp_create_sockdir_status *status)
{
    int32_t i_status = 0;
    int rv = libipm_msg_in_parse(trans, "i", &i_status);
    if (rv == 0)
    {
        *status = (enum scp_create_sockdir_status)i_status;
    }

    return rv;
}

/*****************************************************************************/

int
scp_send_close_connection_request(struct trans *trans)
{
    return libipm_msg_out_simple_send(
               trans,
               (int)E_SCP_CLOSE_CONNECTION_REQUEST,
               NULL);
}

Messung V0.5 in Prozent
C=94 H=93 G=93

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-07-10) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik