/**************************************************************************//**
* Maps a string to a session type value
*
* @param string session type string
* @param[out] value session type value
* @return0for success or != 0ifnot found
*/ static int string_to_session_type(constchar *t, enum scp_session_type *value)
{ unsignedint i; for (i = 0 ; type_map[i].name != NULL; ++i)
{ if (g_strcasecmp(type_map[i].name, t) == 0)
{
*value = type_map[i].type; return0;
}
}
return1;
}
/**************************************************************************//**
* Returns a list of supported session types
*
* Caller supplies a buffer. Buffer handling and buffer overflow detection are
* the same as snprint()
*
* @param buff area for result
* @param bufflen Size of result
* @return number of characters for the output string
*/ static unsignedint get_session_type_list(char *buff, unsignedint bufflen)
{ unsignedint i; unsignedint ret = 0; constchar *sep = "";
for (i = 0 ; type_map[i].name != NULL; ++i)
{ if (ret < bufflen)
{
ret += g_snprintf(buff + ret, bufflen - ret, "%s%s", sep, type_map[i].name);
sep = ", ";
}
}
return ret;
}
/**************************************************************************//**
* Prints a brief summary of options and defaults
*/ staticvoid
usage(void)
{ char sesstype_list[64];
g_printf("xrdp session starter v" PACKAGE_VERSION "\n");
g_printf("\nusage:\n");
g_printf("sesrun --help\n" "\nor\n" "sesrun [options] [username]\n\n");
g_printf("options:\n");
g_printf(" -g <geometry> Default:%dx%d\n",
DEFAULT_WIDTH, DEFAULT_HEIGHT);
g_printf(" -b <bits-per-pixel> Default:%d\n", DEFAULT_BPP);
g_printf(" -t <type> Default:%s\n", DEFAULT_SESSION_TYPE);
g_printf(" -D <directory> Default: $HOME\n" " -S <shell> Default: Defined window manager\n" " -p <password> TESTING ONLY - DO NOT USE IN PRODUCTION\n" " -F <file-descriptor> Read password from this file descriptor\n" " -c <sesman_ini> Alternative sesman.ini file\n");
g_printf("\nSupported types are %s\n",
sesstype_list);
g_printf("\nIf username is omitted, the current user is used.\n" "If username is provided, password is needed.\n" " Password is prompted for if -p or -F are not specified\n");
}
/**************************************************************************//**
* Parses a string <width>x<height>
*
* @param geom_str Input string
* @param sp Session parameter structure for resulting width and height
* @return !=0for success
*/ staticint
parse_geometry_string(constchar *geom_str, struct session_params *sp)
{ int result = 0; unsignedint sep_count = 0; /* Count of 'x' separators */ unsignedint other_count = 0; /* Count of non-digits and non separators */ constchar *sepp = NULL; /* Pointer to the 'x' */ constchar *p = geom_str;
while (*p != '\0')
{ if (!isdigit(*p))
{ if (*p == 'x' || *p == 'X')
{
++sep_count;
sepp = p;
} else
{
++other_count;
}
}
++p;
}
if (sep_count != 1 || other_count > 0 ||
sepp == geom_str || /* Separator at start of string */
sepp == (p - 1) ) /* Separator at end of string */
{
LOG(LOG_LEVEL_ERROR, "Invalid geometry string '%s'", geom_str);
} else
{
sp->width = atoi(geom_str);
sp->height = atoi(sepp + 1);
result = 1;
}
return result;
}
/**************************************************************************//**
* Read a password from a file descriptor
*
* @param fd_str string representing file descriptor
* @param sp Session parameter structure for resulting password
* @return !=0for success
*/ staticint
read_password_from_fd(constchar *fd_str, struct session_params *sp)
{ int result = 0; int s = g_file_read(atoi(fd_str), sp->password, sizeof (sp->password) - 1); if (s < 0)
{
LOG(LOG_LEVEL_ERROR, "Can't read password from fd %s - %s",
fd_str, g_get_strerror());
sp->password[0] = '\0';
} else
{
sp->password[s] = '\0'; if (s > 0 && sp->password[s - 1] == '\n')
{
sp->password[s - 1] = '\0';
}
result = 1;
} return result;
}
/**************************************************************************//**
* Parses the program args
*
* @param argc Passed to main
* @param @argv Passed to main
* @param sp Session parameter structure for resulting values
* @param sesman_ini Pointer to an alternative config file if one is specified
* @return !=0for success
*/ staticint
parse_program_args(int argc, char *argv[], struct session_params *sp, constchar **sesman_ini)
{ int params_ok = 1; int opt;
bool_t password_set = 0;
if (argc == optind)
{ // No username was specified if (password_set)
{
LOG(LOG_LEVEL_WARNING, "No username - ignoring specified password");
sp->password[0] = '\0';
}
sp->username = NULL;
} elseif ((argc - optind) > 1)
{
LOG(LOG_LEVEL_ERROR, "Unexpected arguments after username");
params_ok = 0;
} elseif (params_ok)
{ // A username is specified
sp->username = argv[optind]; if (!password_set)
{ constchar *p = getpass("Password: "); if (p == NULL)
{
params_ok = 0;
} else
{
g_snprintf(sp->password, sizeof(sp->password), "%s", p);
}
}
}
return params_ok;
}
/**************************************************************************//**
* Sends an SCP login request
*
* A sys login request (i.e. username / password) is used if a username
* is specified. Otherwise we use a uds login request for the current user.
*
* @param t SCP connection
* @param sp Data for request
*/ staticint
send_login_request(struct trans *t, conststruct session_params *sp)
{ int rv;
LOG(LOG_LEVEL_DEBUG, "ip_addr:\"%s\"", sp->ip_addr); if (sp->username != NULL)
{ /* Only log the password in development builds */
LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password);
/**************************************************************************//**
* Receives an SCP login response
*
* @param t SCP transport to receive reply on
* @param[out] server_closed != 0if server has gone away
* @return0for successful authentication
*/ staticint
handle_login_response(struct trans *t, int *server_closed)
{ enum scp_login_status login_result;
int rv = scp_sync_wait_specific(t, E_SCP_LOGIN_RESPONSE); if (rv != 0)
{
*server_closed = 1;
} else
{
rv = scp_get_login_response(t, &login_result, server_closed, NULL); if (rv == 0)
{ if (login_result != E_SCP_LOGIN_OK)
{ char msg[256];
scp_login_status_to_str(login_result, msg, sizeof(msg));
g_printf("Login failed; %s\n", msg);
rv = 1;
}
}
scp_msg_in_reset(t); // Done with this message
}
return rv;
}
/**************************************************************************//**
* Sends an SCP create session request
*
* @param t SCP connection
* @param sp Data for request
*/ staticint
send_create_session_request(struct trans *t, conststruct session_params *sp)
{
LOG(LOG_LEVEL_DEBUG, "width:%d height:%d bpp:%d code:%d\n" "directory:\"%s\" shell:\"%s\"",
sp->width, sp->height, sp->bpp, sp->session_type,
sp->directory, sp->shell);
/**************************************************************************//**
* Receives an SCP create session response
*
* @param t SCP transport to receive reply on
* @return0for success
*/ staticint
handle_create_session_response(struct trans *t)
{ enum scp_screate_status status; int display; struct guid guid;
int rv = scp_sync_wait_specific(t, E_SCP_CREATE_SESSION_RESPONSE); if (rv == 0)
{
rv = scp_get_create_session_response(t, &status,
&display, &guid);
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.