Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/XRDP/sesman/chansrv/   (X11 Server Version 0.10.6.1©)  Datei vom 7.6.2026 mit Größe 15 kB image not shown  

Quelle  chansrv_config.c

  Sprache: C
 

/**
 * xrdp: A Remote Desktop Protocol server.
 *
 * 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.
 *
 * This file implements the interface in chansrv_config.h
 */

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

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#include "arch.h"

#include "list.h"
#include "log.h"
#include "file.h"
#include "os_calls.h"

#include "chansrv_common.h"
#include "chansrv_config.h"
#include "string_calls.h"
#include "sesman_clip_restrict.h"

/* Default settings */
#define DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD 0
#define DEFAULT_RESTRICT_INBOUND_CLIPBOARD  0
#define DEFAULT_ENABLE_FUSE_MOUNT           1
#define DEFAULT_FUSE_MOUNT_NAME             "xrdp-client"
#define DEFAULT_FUSE_MOUNT_NAME_COLON_CHAR_REPLACEMENT ':'
#define DEFAULT_FUSE_DIRECT_IO              0
#define DEFAULT_FILE_UMASK                  077
#define DEFAULT_USE_NAUTILUS3_FLIST_FORMAT  0
#define DEFAULT_FUSE_ROOT_REPORT_MAX_FREE   0
#define DEFAULT_NUM_SILENT_FRAMES_AAC       4
#define DEFAULT_NUM_SILENT_FRAMES_MP3       2
#define DEFAULT_MSEC_DO_NOT_SEND            1000
#define DEFAULT_LOG_FILE_PATH               ""
/**
 * Type used for passing a logging function about
 */

typedef
printflike(23)
enum logReturns (*log_func_t)(const enum logLevels lvl,
                              const char *msg, ...);

/***************************************************************************//**
 * @brief Error logging function to use to log to stdout
 *
 * Has the same signature as the log_message() function
 */
static enum logReturns
log_to_stdout(const enum logLevels lvl, const char *msg, ...)
{
    char buff[256];
    va_list ap;

    va_start(ap, msg);
    vsnprintf(buff, sizeof(buff), msg, ap);
    va_end(ap);
    g_writeln("%s", buff);

    return LOG_STARTUP_OK;
}

/***************************************************************************//**
 * Reads the config values we need from the [Globals] section
 *
 * @param logmsg Function to use to log messages
 * @param names List of definitions in the section
 * @params values List of corresponding values for the names
 * @params cfg Pointer to structure we're filling in
 *
 * @return 0 for success
 */
static int
read_config_globals(log_func_t logmsg,
                    struct list *names, struct list *values,
                    struct config_chansrv *cfg)
{
    int error = 0;
    int index;

    for (index = 0; index < names->count; ++index)
    {
        const char *name = (const char *)list_get_item(names, index);
        const char *value = (const char *)list_get_item(values, index);

        char unrecognised[256];
        if (g_strcasecmp(name, "ListenPort") == 0)
        {
            char *listen_port = strdup(value);
            if (listen_port == NULL)
            {
                LOG(LOG_LEVEL_WARNING,
                    "Can't allocate config memory for ListenPort");
            }
            else
            {
                g_free(cfg->listen_port);
                cfg->listen_port = listen_port;
            }
        }
        if (g_strcasecmp(name, "RestrictInboundClipboard") == 0)
        {
            cfg->restrict_inbound_clipboard =
                sesman_clip_restrict_string_to_bitmask(
                    value, unrecognised, sizeof(unrecognised));
            if (unrecognised[0] != '\0')
            {
                LOG(LOG_LEVEL_WARNING,
                    "Unrecognised tokens parsing 'RestrictInboundClipboard' %s",
                    unrecognised);
            }
        }
    }

    return error;
}

/***************************************************************************//**
 * Reads the config values we need from the [Security] section
 *
 * @param logmsg Function to use to log messages
 * @param names List of definitions in the section
 * @params values List of corresponding values for the names
 * @params cfg Pointer to structure we're filling in
 *
 * @return 0 for success
 */
static int
read_config_security(log_func_t logmsg,
                     struct list *names, struct list *values,
                     struct config_chansrv *cfg)
{
    int error = 0;
    int index;

    for (index = 0; index < names->count; ++index)
    {
        const char *name = (const char *)list_get_item(names, index);
        const char *value = (const char *)list_get_item(values, index);

        char unrecognised[256];
        if (g_strcasecmp(name, "RestrictOutboundClipboard") == 0)
        {
            cfg->restrict_outbound_clipboard =
                sesman_clip_restrict_string_to_bitmask(
                    value, unrecognised, sizeof(unrecognised));
            if (unrecognised[0] != '\0')
            {
                LOG(LOG_LEVEL_WARNING,
                    "Unrecognised tokens parsing 'RestrictOutboundClipboard' %s",
                    unrecognised);
            }
        }
        if (g_strcasecmp(name, "RestrictInboundClipboard") == 0)
        {
            cfg->restrict_inbound_clipboard =
                sesman_clip_restrict_string_to_bitmask(
                    value, unrecognised, sizeof(unrecognised));
            if (unrecognised[0] != '\0')
            {
                LOG(LOG_LEVEL_WARNING,
                    "Unrecognised tokens parsing 'RestrictInboundClipboard' %s",
                    unrecognised);
            }
        }
    }

    return error;
}

/***************************************************************************//**
 * Reads the config values we need from the [Chansrv] section
 *
 * @param logmsg Function to use to log messages
 * @param names List of definitions in the section
 * @params values List of corresponding values for the names
 * @params cfg Pointer to structure we're filling in
 *
 * @return 0 for success
 */
static int
read_config_chansrv(log_func_t logmsg,
                    struct list *names, struct list *values,
                    struct config_chansrv *cfg)
{
    int error = 0;
    int index;

    for (index = 0; index < names->count; ++index)
    {
        const char *name = (const char *)list_get_item(names, index);
        const char *value = (const char *)list_get_item(values, index);

        if (g_strcasecmp(name, "EnableFuseMount") == 0)
        {
            cfg->enable_fuse_mount = g_text2bool(value);
        }
        else if (g_strcasecmp(name, "FuseMountName") == 0)
        {
            g_free(cfg->fuse_mount_name);
            cfg->fuse_mount_name = g_strdup(value);
            if (cfg->fuse_mount_name == NULL)
            {
                logmsg(LOG_LEVEL_ERROR, "Can't alloc FuseMountName");
                error = 1;
                break;
            }
        }
        else if (g_strcasecmp(name, "FuseMountNameColonCharReplacement") == 0)
        {
            size_t vallen = g_strlen(value);
            if (vallen < 1)
            {
                cfg->fuse_mount_name_colon_char_replacement = '\0';
            }
            else
            {
                if (vallen > 1)
                {
                    logmsg(LOG_LEVEL_WARNING, "FuseMountNameColonCharReplacement "
                           "must be 1 character length, now it is '%s'."
                           "Only first char will be used!",
                           value);
                }
                cfg->fuse_mount_name_colon_char_replacement = value[0];
            }
        }
        else if (g_strcasecmp(name, "FuseDirectIO") == 0)
        {
            cfg->fuse_direct_io = g_text2bool(value);
        }
        else if (g_strcasecmp(name, "FileUmask") == 0)
        {
            cfg->file_umask = strtol(value, NULL, 0);
        }
        else if (g_strcasecmp(name, "UseNautilus3FlistFormat") == 0)
        {
            cfg->use_nautilus3_flist_format = g_text2bool(value);
        }
        else if (g_strcasecmp(name, "FuseRootReportMaxFree") == 0)
        {
            cfg->fuse_root_report_max_free = g_text2bool(value);
        }
        else if (g_strcasecmp(name, "SoundNumSilentFramesAAC") == 0)
        {
            cfg->num_silent_frames_aac = strtoul(value, NULL, 0);
        }
        else if (g_strcasecmp(name, "SoundNumSilentFramesMP3") == 0)
        {
            cfg->num_silent_frames_mp3 = strtoul(value, NULL, 0);
        }
        else if (g_strcasecmp(name, "SoundMsecDoNotSend") == 0)
        {
            cfg->msec_do_not_send = strtoul(value, NULL, 0);
        }
    }

    return error;
}

/***************************************************************************//**
 * Reads the config values we need from the [ChansrvLogging] section
 *
 * @param logmsg Function to use to log messages
 * @param names List of definitions in the section
 * @params values List of corresponding values for the names
 * @params cfg Pointer to structure we're filling in
 *
 * @return 0 for success
 */
static int
read_config_chansrv_logging(log_func_t logmsg,
                            struct list *names, struct list *values,
                            struct config_chansrv *cfg)
{
    int error = 0;
    int index;

    for (index = 0; index < names->count; ++index)
    {
        const char *name = (const char *)list_get_item(names, index);
        const char *value = (const char *)list_get_item(values, index);

        if (g_strcasecmp(name, "LogFilePath") == 0)
        {
            g_free(cfg->log_file_path);
            cfg->log_file_path = g_strdup(value);
            if (cfg->log_file_path == NULL)
            {
                logmsg(LOG_LEVEL_ERROR, "Can't alloc LogFilePath");
                error = 1;
                break;
            }
        }
    }

    return error;
}

/***************************************************************************//**
 * @brief returns a config block with default values
 *
 * @return Block, or NULL for no memory
 */
static struct config_chansrv *
new_config(void)
{
    /* Do all the allocations at the beginning, then check them together */
    struct config_chansrv *cfg = g_new0(struct config_chansrv, 1);
    char *fuse_mount_name = g_strdup(DEFAULT_FUSE_MOUNT_NAME);
    char *log_file_path = g_strdup(DEFAULT_LOG_FILE_PATH);
    if (cfg == NULL || fuse_mount_name == NULL || log_file_path == NULL)
    {
        /* At least one memory allocation failed */
        g_free(log_file_path);
        g_free(fuse_mount_name);
        g_free(cfg);
        cfg = NULL;
    }
    else
    {
        cfg->listen_port = NULL;
        cfg->enable_fuse_mount = DEFAULT_ENABLE_FUSE_MOUNT;
        cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD;
        cfg->restrict_inbound_clipboard = DEFAULT_RESTRICT_INBOUND_CLIPBOARD;
        cfg->fuse_mount_name = fuse_mount_name;
        cfg->fuse_mount_name_colon_char_replacement = DEFAULT_FUSE_MOUNT_NAME_COLON_CHAR_REPLACEMENT;
        cfg->fuse_direct_io = DEFAULT_FUSE_DIRECT_IO;
        cfg->file_umask = DEFAULT_FILE_UMASK;
        cfg->use_nautilus3_flist_format = DEFAULT_USE_NAUTILUS3_FLIST_FORMAT;
        cfg->fuse_root_report_max_free = DEFAULT_FUSE_ROOT_REPORT_MAX_FREE;
        cfg->num_silent_frames_aac = DEFAULT_NUM_SILENT_FRAMES_AAC;
        cfg->num_silent_frames_mp3 = DEFAULT_NUM_SILENT_FRAMES_MP3;
        cfg->msec_do_not_send = DEFAULT_MSEC_DO_NOT_SEND;
        cfg->log_file_path = log_file_path;
    }

    return cfg;
}

/******************************************************************************/
struct config_chansrv *
config_read(int use_logger, const char *sesman_ini)
{
    int error = 0;
    struct config_chansrv *cfg = NULL;
    log_func_t logmsg = (use_logger) ? log_message : log_to_stdout;
    int fd;

    fd = g_file_open_ro(sesman_ini);
    if (fd < 0)
    {
        logmsg(LOG_LEVEL_ERROR, "Can't open config file %s", sesman_ini);
        error = 1;
    }
    else
    {
        if ((cfg = new_config()) == NULL)
        {
            logmsg(LOG_LEVEL_ERROR, "Can't alloc config block");
            error = 1;
        }
        else
        {
            struct list *names = list_create();
            struct list *values = list_create();

            names->auto_free = 1;
            values->auto_free = 1;

            if (!error && file_read_section(fd, "Globals", names, values) == 0)
            {
                error = read_config_globals(logmsg, names, values, cfg);
            }

            if (!error && file_read_section(fd, "Security", names, values) == 0)
            {
                error = read_config_security(logmsg, names, values, cfg);
            }

            if (!error && file_read_section(fd, "Chansrv", names, values) == 0)
            {
                error = read_config_chansrv(logmsg, names, values, cfg);
            }

            if (!error &&
                    file_read_section(fd, "ChansrvLogging", names, values) == 0)
            {
                error = read_config_chansrv_logging(logmsg, names, values, cfg);
            }

            list_delete(names);
            list_delete(values);
        }

        g_file_close(fd);
    }

    if (error)
    {
        config_free(cfg);
        cfg = NULL;
    }

    return cfg;
}

/******************************************************************************/
void
config_dump(struct config_chansrv *config)
{
    char buf[256];

    g_writeln("Global configuration:");
    g_writeln("    xrdp-sesman ListenPort:    %s",
              (config->listen_port) ? config->listen_port : "<default>");

    g_writeln("\nSecurity configuration:");
    sesman_clip_restrict_mask_to_string(
        config->restrict_outbound_clipboard,
        buf, sizeof(buf));
    g_writeln("    RestrictOutboundClipboard: %s", buf);

    sesman_clip_restrict_mask_to_string(
        config->restrict_inbound_clipboard,
        buf, sizeof(buf));
    g_writeln("    RestrictInboundClipboard:  %s", buf);

    g_writeln("\nChansrv configuration:");
    g_writeln("    EnableFuseMount            %s",
              g_bool2text(config->enable_fuse_mount));
    g_writeln("    FuseMountName:             %s", config->fuse_mount_name);
    g_writeln("    FuseMountNameColonCharReplacement:             %c", config->fuse_mount_name_colon_char_replacement);
    g_writeln("    FuseDirectIO:              %s",
              g_bool2text(config->fuse_direct_io));
    g_writeln("    FileMask:                  0%o", config->file_umask);
    g_writeln("    Nautilus 3 Flist Format:   %s",
              g_bool2text(config->use_nautilus3_flist_format));
    g_writeln("    FuseRootReportMaxFree:     %s",
              g_bool2text(config->fuse_root_report_max_free));
    g_writeln("    LogFilePath            :   %s",
              (config->log_file_path[0]) ? config->log_file_path : "<default>");
}

/******************************************************************************/
void
config_free(struct config_chansrv *cc)
{
    if (cc != NULL)
    {
        g_free(cc->listen_port);
        g_free(cc->fuse_mount_name);
        g_free(cc->log_file_path);
        g_free(cc);
    }
}

Messung V0.5 in Prozent
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.13 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.