staticint
process_set_peername_request(struct pre_session_item *psi)
{ int rv; constchar *peername;
rv = scp_get_set_peername_request(psi->client_trans, &peername); if (rv == 0)
{ if (pre_session_list_set_peername(psi, peername) != 0)
{
LOG(LOG_LEVEL_WARNING, "Failed to set connection peername from %s to %s",
psi->peername, peername);
}
}
return rv;
}
/******************************************************************************/ staticint
process_sys_login_request(struct pre_session_item *psi)
{ int rv; constchar *username; constchar *password; constchar *ip_addr; int send_client_reply = 1;
LOG(LOG_LEVEL_INFO, "Received system login request from %s for user: %s IP: %s",
psi->peername, username, ip_addr);
if (psi->login_state != E_PS_LOGIN_NOT_LOGGED_IN)
{
errorcode = E_SCP_LOGIN_ALREADY_LOGGED_IN;
LOG(LOG_LEVEL_ERROR, "Connection is already logged in for %s",
psi->username);
} elseif ((psi->username = g_strdup(username)) == NULL)
{
errorcode = E_SCP_LOGIN_NO_MEMORY;
LOG(LOG_LEVEL_ERROR, "Memory allocation failure logging in %s",
username);
} else
{ /* *CopytheIPaddressoftherequestinguser,anticipatinga *successfullogin.Weneedthissowecansearchforasession *withamatchingIPaddressifrequired.
*/
g_snprintf(psi->start_ip_addr, sizeof(psi->start_ip_addr), "%s", ip_addr);
/* Create a sesexec process to handle the login * *Wewon'tcheckfortheuserbeingvalidhere,asthismight
* lead to information leakage */ if (sesexec_start(psi) != 0)
{
LOG(LOG_LEVEL_ERROR, "Can't start sesexec to authenticate user");
errorcode = E_SCP_LOGIN_GENERAL_ERROR;
} else
{ int eicp_stat;
eicp_stat = eicp_send_sys_login_request(psi->sesexec_trans,
username,
password,
ip_addr,
psi->client_trans->sck); if (eicp_stat != 0)
{
LOG(LOG_LEVEL_ERROR, "Can't ask sesexec to authenticate user");
errorcode = E_SCP_LOGIN_GENERAL_ERROR;
} else
{ /* We've handed over responsibility for the
* SCP communication */
send_client_reply = 0;
psi->dispatcher_action = E_PSD_REMOVE_CLIENT_TRANS;
}
}
}
if (send_client_reply)
{ /* We only get here if something has gone
* wrong with the handover to sesexec */
rv = scp_send_login_response(psi->client_trans, errorcode, 1, -1);
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION;
}
}
/** *AuthenticateandauthorizeaUDSconnection * *@parampsiConnectiontosesman *@paramuidUIDforuser *@paramusernameNameforuser *@returnStatusfortheoperation * *@postIfE_SCP_LOGIN_OKisreturned,psi->usernameisnon-NULL
*/ staticenum scp_login_status
authenticate_and_authorize_uds_connection(struct pre_session_item *psi, int uid, constchar *username)
{ enum scp_login_status status = E_SCP_LOGIN_GENERAL_ERROR; struct auth_info *auth_info = auth_uds(username, &status); if (auth_info != NULL)
{ if (status != E_SCP_LOGIN_OK)
{ /* This shouldn't happen */
LOG(LOG_LEVEL_ERROR, "Unexpected status return %d from auth_uds call",
(int)status);
} elseif (!access_login_allowed(&g_cfg->sec, username))
{
status = E_SCP_LOGIN_NOT_AUTHORIZED;
LOG(LOG_LEVEL_INFO, "Username okay but group problem for " "user: %s", username);
}
/* If all is well, add info to the sesman connection for later use */ if (status == E_SCP_LOGIN_OK)
{ if ((psi->username = g_strdup(username)) == NULL)
{
LOG(LOG_LEVEL_ERROR, "%s : Memory allocation failed",
__func__);
g_free(psi->username);
psi->username = NULL;
status = E_SCP_LOGIN_NO_MEMORY;
} else
{
LOG(LOG_LEVEL_INFO, "Access permitted for user: %s",
username);
psi->login_state = E_PS_LOGIN_UDS;
psi->uid = uid;
psi->start_ip_addr[0] = '\0';
}
}
staticint
process_uds_login_request(struct pre_session_item *psi)
{ enum scp_login_status errorcode; int rv; int uid; int pid; char *username = NULL; int server_closed;
rv = g_sck_get_peer_cred(psi->client_trans->sck, &pid, &uid, NULL); if (rv != 0)
{
errorcode = E_SCP_LOGIN_GENERAL_ERROR;
LOG(LOG_LEVEL_INFO, "Unable to get peer credentials for socket %d",
(int)psi->client_trans->sck);
} else
{
LOG(LOG_LEVEL_INFO, "Received UDS login request from %s for UID: %d from PID: %d",
psi->peername, uid, pid);
if (rv == 0)
{ if (psi->login_state == E_PS_LOGIN_NOT_LOGGED_IN)
{
status = E_SCP_SCREATE_NOT_LOGGED_IN;
} else
{
LOG(LOG_LEVEL_INFO, "Received request from %s to create a session for user %s",
psi->peername, psi->username);
s_item = session_list_get_bydata(psi->uid, type, width, height,
bpp, psi->start_ip_addr); if (s_item != NULL)
{ // Found an existing session
display = s_item->display;
guid = s_item->guid;
// Tell the existing session to run the reconnect script. // We ignore errors at this level, as any comms errors // will be picked up in the main loop
(void)ercp_send_session_reconnect_event(s_item->sesexec_trans);
// If we created an authentication process for this SCP // connection, close it gracefully
logout_pre_session(psi);
} // Need to create a new session elseif (g_cfg->sess.max_sessions > 0 &&
session_list_get_count() >= g_cfg->sess.max_sessions)
{
status = E_SCP_SCREATE_MAX_REACHED;
} elseif ((display = session_list_get_available_display()) < 0)
{
status = E_SCP_SCREATE_NO_DISPLAY;
} // Create an entry on the session list for the new session elseif ((s_item = session_list_new()) == NULL)
{
status = E_SCP_SCREATE_NO_MEMORY;
} // Create a socket dir for this user elseif (create_xrdp_socket_path(psi->uid) != 0)
{
status = E_SCP_SCREATE_GENERAL_ERROR;
} // Create a sesexec process if we don't have one (UDS login) elseif (psi->sesexec_trans == NULL && sesexec_start(psi) != 0)
{
LOG(LOG_LEVEL_ERROR, "Can't start sesexec to manage session");
status = E_SCP_SCREATE_GENERAL_ERROR;
} else
{ // Pass the session create request to sesexec int eicp_stat;
eicp_stat = eicp_send_create_session_request(
psi->sesexec_trans,
psi->client_trans->sck,
display,
type, width, height,
bpp, shell, directory);
if (eicp_stat != 0)
{
LOG(LOG_LEVEL_ERROR, "Can't ask sesexec to authenticate user");
status = E_SCP_SCREATE_GENERAL_ERROR;
} else
{ // We've handed over responsibility for the // SCP communication
send_client_reply = 0;
// Further comms from sesexec comes over the ERCP // protocol
ercp_trans_from_eicp_trans(psi->sesexec_trans,
sesman_ercp_data_in,
(void *)s_item);
// Move the transport over to the session list item
s_item->sesexec_trans = psi->sesexec_trans;
s_item->sesexec_pid = psi->sesexec_pid;
psi->sesexec_trans = NULL;
psi->sesexec_pid = 0;
// Add the display to the session item so we don't try // to allocate it to another session
s_item->display = display;
}
}
}
// Currently a create session request is the last thing on a // connection, and results in automatic closure // // We may have passed the client_trans over to sesexec. If so, // we can't send a reply here.
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION; if (send_client_reply)
{
rv = scp_send_create_session_response(psi->client_trans,
status, display, &guid);
}
}
if (psi->login_state == E_PS_LOGIN_NOT_LOGGED_IN)
{
rv = scp_send_list_sessions_response(psi->client_trans,
E_SCP_LS_NOT_LOGGED_IN,
NULL);
} else
{
LOG(LOG_LEVEL_INFO, "Received request from %s to list sessions for user %s",
psi->peername, psi->username);
info = session_list_get_byuid(psi->uid, &cnt, 0);
for (i = 0; rv == 0 && i < cnt; ++i)
{
rv = scp_send_list_sessions_response(psi->client_trans,
E_SCP_LS_SESSION_INFO,
&info[i]);
}
free_session_info_list(info, cnt);
staticint
process_create_sockdir_request(struct pre_session_item *psi)
{ enum scp_create_sockdir_status status = E_SCP_CS_OTHER_ERROR;
if (psi->login_state == E_PS_LOGIN_NOT_LOGGED_IN)
{
status = E_SCP_CS_NOT_LOGGED_IN;
} else
{
LOG(LOG_LEVEL_INFO, "Received request from %s to create sockdir for user %s",
psi->peername, psi->username);
if (create_xrdp_socket_path(psi->uid) == 0)
{
status = E_SCP_CS_OK;
}
}
staticint
process_close_connection_request(struct pre_session_item *psi)
{ int rv = 0;
LOG(LOG_LEVEL_INFO, "Received request to close connection from %s",
psi->peername);
/* Expecting no more client messages. Close the connection
* after returning from this callback */
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION; return rv;
}
/******************************************************************************/ int
scp_process(struct pre_session_item *psi)
{ enum scp_msg_code msgno; int rv = 0;
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.