From 4c4bdc9782c0b20f4b1a16b614b0711f6042206b Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Thu, 19 May 2022 16:27:30 +0100 Subject: [PATCH] SCP: separate authentication from session creation Messaging changes:- - Implement sys_login request message with username, password and IP address - Implement UDS login message for current user connected to sesman - Implement common login response message for login requests - Implement logout message so gateway authentications can be handled - with login/logout messages - Remove login info from the create session request - Existing gateway request/response messages removed - Add close connection message so that sesman can close terminated connections without displaying ERROR messages in the log. - Add a set_peername message so clients can send a name to sesman for improved logging. Other changes:- - Add status types for logging in and session creation, so that the front-end can supply the user with more informative errors in the event of an error occurring. - Users identities are now carried by UID rather than username, as xrdp and sesman are guaranteed to be on the same machine. --- libipm/Makefile.am | 3 +- libipm/scp.c | 237 +++++++++++++++++++-------------- libipm/scp.h | 222 +++++++++++++++++------------- libipm/scp_application_types.c | 84 ++++++++++++ libipm/scp_application_types.h | 80 ++++++++++- 5 files changed, 427 insertions(+), 199 deletions(-) create mode 100644 libipm/scp_application_types.c diff --git a/libipm/Makefile.am b/libipm/Makefile.am index 2957182b..d4d30987 100644 --- a/libipm/Makefile.am +++ b/libipm/Makefile.am @@ -15,7 +15,8 @@ libipm_la_SOURCES = \ libipm_private.h \ scp.h \ scp.c \ - scp_application_types.h + scp_application_types.h \ + scp_application_types.c libipm_la_LIBADD = \ $(top_builddir)/common/libcommon.la diff --git a/libipm/scp.c b/libipm/scp.c index 45f35e4b..5cca6edc 100644 --- a/libipm/scp.c +++ b/libipm/scp.c @@ -40,12 +40,21 @@ static const char * msgno_to_str(unsigned short n) { return - (n == E_SCP_GATEWAY_REQUEST) ? "SCP_GATEWAY_REQUEST" : - (n == E_SCP_GATEWAY_RESPONSE) ? "SCP_GATEWAY_RESPONSE" : + (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; } @@ -147,6 +156,7 @@ scp_port_to_display_string(const char *port, char *buff, unsigned int bufflen) /*****************************************************************************/ struct trans * scp_connect(const char *port, + const char *peername, int (*term_func)(void)) { char sock_path[256]; @@ -162,8 +172,12 @@ scp_connect(const char *port, trans_delete(t); t = NULL; } - else if (libipm_init_trans(t, LIBIPM_FAC_SCP, msgno_to_str) != - E_LI_SUCCESS) + 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; @@ -214,16 +228,48 @@ scp_msg_in_start(struct trans *trans) /*****************************************************************************/ int -scp_send_gateway_request(struct trans *trans, - const char *username, - const char *password, - const char *ip_addr) +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_GATEWAY_REQUEST, + (int)E_SCP_SYS_LOGIN_REQUEST, "sss", username, password, @@ -238,93 +284,99 @@ scp_send_gateway_request(struct trans *trans, /*****************************************************************************/ int -scp_get_gateway_request(struct trans *trans, - const char **username, - const char **password, - const char **ip_addr) +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); + return libipm_msg_in_parse( trans, "sss", + username, password, ip_addr); } /*****************************************************************************/ int -scp_send_gateway_response(struct trans *trans, - int auth_result) +scp_send_login_response(struct trans *trans, + enum scp_login_status login_result, + int server_closed) { return libipm_msg_out_simple_send( trans, - (int)E_SCP_GATEWAY_RESPONSE, - "i", - auth_result); + (int)E_SCP_LOGIN_RESPONSE, + "ib", + login_result, + (server_closed != 0)); /* Convert to 0/1 */ } /*****************************************************************************/ int -scp_get_gateway_response(struct trans *trans, - int *auth_result) +scp_get_login_response(struct trans *trans, + enum scp_login_status *login_result, + int *server_closed) { - int32_t i_auth_result = 0; - int rv = libipm_msg_in_parse(trans, "i", &i_auth_result); + int32_t i_login_result = 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 */ + if (server_closed == NULL) + { + server_closed = &dummy; + } + + int rv = libipm_msg_in_parse(trans, "ib", &i_login_result, server_closed); if (rv == 0) { - *auth_result = i_auth_result; + *login_result = (enum scp_login_status)i_login_result; } 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, - const char *username, - const char *password, enum scp_session_type type, unsigned short width, unsigned short height, unsigned char bpp, const char *shell, - const char *directory, - const char *ip_addr) + const char *directory) { - int rv = libipm_msg_out_simple_send( - trans, - (int)E_SCP_CREATE_SESSION_REQUEST, - "ssyqqysss", - username, - password, - type, - width, - height, - bpp, - shell, - directory, - ip_addr); - - /* Wipe the output buffer to remove the password */ - libipm_msg_out_erase(trans); - - return rv; + 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, - const char **username, - const char **password, enum scp_session_type *type, unsigned short *width, unsigned short *height, unsigned char *bpp, const char **shell, - const char **directory, - const char **ip_addr) + const char **directory) { /* Intermediate values */ uint8_t i_type; @@ -332,21 +384,15 @@ scp_get_create_session_request(struct trans *trans, uint16_t i_height; uint8_t i_bpp; - /* Make sure the buffer is cleared after processing this message */ - libipm_set_flags(trans, LIBIPM_E_MSG_IN_ERASE_AFTER_USE); - int rv = libipm_msg_in_parse( trans, - "ssyqqysss", - username, - password, + "yqqyss", &i_type, &i_width, &i_height, &i_bpp, shell, - directory, - ip_addr); + directory); if (rv == 0) { @@ -364,7 +410,7 @@ scp_get_create_session_request(struct trans *trans, int scp_send_create_session_response(struct trans *trans, - int auth_result, + enum scp_screate_status status, int display, const struct guid *guid) { @@ -374,7 +420,7 @@ scp_send_create_session_response(struct trans *trans, trans, (int)E_SCP_CREATE_SESSION_RESPONSE, "iiB", - auth_result, + status, display, &guid_descriptor); } @@ -383,12 +429,12 @@ scp_send_create_session_response(struct trans *trans, int scp_get_create_session_response(struct trans *trans, - int *auth_result, + enum scp_screate_status *status, int *display, struct guid *guid) { /* Intermediate values */ - int32_t i_auth_result; + int32_t i_status; int32_t i_display; const struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) }; @@ -396,12 +442,12 @@ scp_get_create_session_response(struct trans *trans, int rv = libipm_msg_in_parse( trans, "iiB", - &i_auth_result, + &i_status, &i_display, &guid_descriptor); if (rv == 0) { - *auth_result = i_auth_result; + *status = (enum scp_screate_status)i_status; *display = i_display; } @@ -411,36 +457,12 @@ scp_get_create_session_response(struct trans *trans, /*****************************************************************************/ int -scp_send_list_sessions_request(struct trans *trans, - const char *username, - const char *password) +scp_send_list_sessions_request(struct trans *trans) { - int rv; - - rv = libipm_msg_out_simple_send( - trans, - (int)E_SCP_LIST_SESSIONS_REQUEST, - "ss", - username, - password); - - /* Wipe the output buffer to remove the password */ - libipm_msg_out_erase(trans); - - return rv; -} - -/*****************************************************************************/ - -int -scp_get_list_sessions_request(struct trans *trans, - const char **username, - const char **password) -{ - /* 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, "ss", username, password); + return libipm_msg_out_simple_send( + trans, + (int)E_SCP_LIST_SESSIONS_REQUEST, + NULL); } /*****************************************************************************/ @@ -465,7 +487,7 @@ scp_send_list_sessions_response( rv = libipm_msg_out_simple_send( trans, (int)E_SCP_LIST_SESSIONS_RESPONSE, - "iiuyqqyxss", + "iiuyqqyxis", status, info->sid, info->display, @@ -474,7 +496,7 @@ scp_send_list_sessions_response( info->height, info->bpp, info->start_time, - info->username, + info->uid, info->start_ip_addr); } @@ -511,12 +533,12 @@ scp_get_list_sessions_response( uint16_t i_height; uint8_t i_bpp; int64_t i_start_time; - char *i_username; + int32_t i_uid; char *i_start_ip_addr; rv = libipm_msg_in_parse( trans, - "iuyqqyxss", + "iuyqqyxis", &i_sid, &i_display, &i_type, @@ -524,7 +546,7 @@ scp_get_list_sessions_response( &i_height, &i_bpp, &i_start_time, - &i_username, + &i_uid, &i_start_ip_addr); if (rv == 0) @@ -532,7 +554,6 @@ scp_get_list_sessions_response( /* 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_username) + 1 + g_strlen(i_start_ip_addr) + 1; if ((p = (struct scp_session_info *)g_malloc(len, 1)) == NULL) { @@ -542,9 +563,8 @@ scp_get_list_sessions_response( { /* Set up the string pointers in the block to point * into the memory allocated after the block */ - p->username = (char *)p + sizeof(struct scp_session_info); p->start_ip_addr = - p->username + g_strlen(i_username) + 1; + (char *)p + sizeof(struct scp_session_info); /* Copy the data over */ p->sid = i_sid; @@ -554,7 +574,7 @@ scp_get_list_sessions_response( p->height = i_height; p->bpp = i_bpp; p->start_time = i_start_time; - g_strcpy(p->username, i_username); + p->uid = i_uid; g_strcpy(p->start_ip_addr, i_start_ip_addr); } } @@ -563,3 +583,14 @@ scp_get_list_sessions_response( } 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); +} diff --git a/libipm/scp.h b/libipm/scp.h index 27b3b116..ae6d3a97 100644 --- a/libipm/scp.h +++ b/libipm/scp.h @@ -43,12 +43,24 @@ struct trans; /* Message codes */ enum scp_msg_code { - E_SCP_GATEWAY_REQUEST = 1, - E_SCP_GATEWAY_RESPONSE, + E_SCP_SET_PEERNAME_REQUEST = 1, + // No E_SCP_SET_PEERNAME_RESPONSE + + E_SCP_SYS_LOGIN_REQUEST, + E_SCP_UDS_LOGIN_REQUEST, + E_SCP_LOGIN_RESPONSE, /* Shared between login request types */ + + E_SCP_LOGOUT_REQUEST, + // No S_SCP_LOGOUT_RESPONSE + E_SCP_CREATE_SESSION_REQUEST, E_SCP_CREATE_SESSION_RESPONSE, + E_SCP_LIST_SESSIONS_REQUEST, - E_SCP_LIST_SESSIONS_RESPONSE + E_SCP_LIST_SESSIONS_RESPONSE, + + E_SCP_CLOSE_CONNECTION_REQUEST + // No E_SCP_CLOSE_CONNECTION_RESPONSE }; /* Common facilities */ @@ -97,6 +109,7 @@ scp_port_to_display_string(const char *port, char *buff, unsigned int bufflen); * Connect to an SCP server * * @param port Port definition (e.g. from sesman.ini) + * @param peername Name of this program or object (e.g. "xrdp-sesadmin") * @param term_func Function to poll during connection for program * termination, or NULL for none. * @return Initialised SCP transport @@ -104,16 +117,19 @@ scp_port_to_display_string(const char *port, char *buff, unsigned int bufflen); * The returned transport has the is_term member set to term_func. */ struct trans * -scp_connect(const char *port, +scp_connect(const char *port, + const char *peername, int (*term_func)(void)); /** * Converts a standard trans connected to an SCP endpoint to an SCP transport * + * If you are running on a client, you may wish to use + * scp_send_set_peername_request() after the commnect to inform the + * server who you are. + * * @param trans connected endpoint * @return != 0 for error - * - * The returned transport has the is_term member set to term_func. */ int scp_init_trans(struct trans *trans); @@ -170,9 +186,54 @@ scp_msg_in_start(struct trans *trans); void scp_msg_in_reset(struct trans *trans); +/* -------------------- Setup messages-------------------- */ /** - * Send an E_SCP_GATEWAY_REQUEST (SCP client) + * Send an E_SCP_SET_PEERNAME_REQUEST (SCP client) + * + * @param trans SCP transport + * @param peername Peername + * @return != 0 for error + * + * Server does not send a response + * + * This message is sent automatically by scp_connect(), but it can + * be sent at any time. + */ +int +scp_send_set_peername_request(struct trans *trans, + const char *peername); + +/** + * Parse an incoming E_SCP_SET_PEERNAME_REQUEST message (SCP server) + * + * @param trans SCP transport + * @param[out] peername peername + * @return != 0 for error + */ +int +scp_get_set_peername_request(struct trans *trans, + const char **peername); + +/* -------------------- Login messages-------------------- */ + +/** + * Send an E_SCP_UDS_LOGIN_REQUEST (SCP client) + * + * User is logged in using their socket details + * + * @param trans SCP transport + * @return != 0 for error + * + * Server replies with E_SCP_LOGIN_RESPONSE + */ +int +scp_send_uds_login_request(struct trans *trans); + +/** + * Send an E_SCP_SYS_LOGIN_REQUEST (SCP client) + * + * User is logged in using explicit credentials * * @param trans SCP transport * @param username Username @@ -180,16 +241,16 @@ scp_msg_in_reset(struct trans *trans); * @param ip_addr IP address for the client (or "" if not known) * @return != 0 for error * - * Server replies with E_SCP_GATEWAY_RESPONSE + * Server replies with E_SCP_LOGIN_RESPONSE */ int -scp_send_gateway_request(struct trans *trans, - const char *username, - const char *password, - const char *ip_addr); +scp_send_sys_login_request(struct trans *trans, + const char *username, + const char *password, + const char *ip_addr); /** - * Parse an incoming E_SCP_GATEWAY_REQUEST message (SCP server) + * Parse an incoming E_SCP_SYS_LOGIN_REQUEST message (SCP server) * * @param trans SCP transport * @param[out] username Username @@ -198,78 +259,89 @@ scp_send_gateway_request(struct trans *trans, * @return != 0 for error */ int -scp_get_gateway_request(struct trans *trans, - const char **username, - const char **password, - const char **ip_addr); +scp_get_sys_login_request(struct trans *trans, + const char **username, + const char **password, + const char **ip_addr); /** - * Send an E_SCP_GATEWAY_RESPONSE (SCP server) + * Send an E_SCP_LOGIN_RESPONSE (SCP server) * * @param trans SCP transport - * @param auth_result 0 for success, PAM error code otherwise + * @param login_result What happened to the login + * @param server_closed. If login fails, whether server has closed connection. + * If not, a retry can be made. * @return != 0 for error */ int -scp_send_gateway_response(struct trans *trans, - int auth_result); +scp_send_login_response(struct trans *trans, + enum scp_login_status login_result, + int server_closed); /** - * Parses an incoming E_SCP_GATEWAY_RESPONSE (SCP client) + * Parses an incoming E_SCP_LOGIN_RESPONSE (SCP client) * * @param trans SCP transport - * @param[out] auth_result 0 for success, PAM error code otherwise + * @param[out] login_result 0 for success, PAM error code otherwise + * @param[out] server_closed. If login fails, whether server has closed + * connection. If not a retry can be made. * @return != 0 for error */ int -scp_get_gateway_response(struct trans *trans, - int *auth_result); +scp_get_login_response(struct trans *trans, + enum scp_login_status *login_result, + int *server_closed); -/* Session messages */ +/** + * Send an E_SCP_LOGOUT_REQUEST (SCP client) + * + * @param trans SCP transport + * @return != 0 for error + * + * Logs the user out (if they are logged in), so that another + * login request can be sent, maybe with a different user. + * + * A reply is not sent + */ +int +scp_send_logout_request(struct trans *trans); + +/* -------------------- Session messages-------------------- */ /** * Send an E_SCP_CREATE_SESSION_REQUEST (SCP client) * * @param trans SCP transport - * @param username Username of session to create or re-connect to - * @param password Password for user * @param type Session type * @param width Initial session width * @param height Initial session height * @param bpp Session bits-per-pixel (ignored for Xorg sessions) * @param shell User program to run. May be "" * @param directory Directory to run the program in. May be "" - * @param ip_addr IP address for the client (or "" if not known) * @return != 0 for error * * Server replies with E_SCP_CREATE_SESSION_RESPONSE */ int scp_send_create_session_request(struct trans *trans, - const char *username, - const char *password, enum scp_session_type type, unsigned short width, unsigned short height, unsigned char bpp, const char *shell, - const char *directory, - const char *ip_addr); + const char *directory); /** * Parse an incoming E_SCP_CREATE_SESSION_REQUEST (SCP server) * * @param trans SCP transport - * @param[out] username Username of session to create or re-connect to - * @param[out] password Password for user * @param[out] type Session type * @param[out] width Initial session width * @param[out] height Initial session height * @param[out] bpp Session bits-per-pixel (ignored for Xorg sessions) * @param[out] shell User program to run. May be "" * @param[out] directory Directory to run the program in. May be "" - * @param[out] ip_addr IP address for the client. May be "" * @return != 0 for error * * Returned string pointers are valid until scp_msg_in_reset() is @@ -277,29 +349,26 @@ scp_send_create_session_request(struct trans *trans, */ int scp_get_create_session_request(struct trans *trans, - const char **username, - const char **password, enum scp_session_type *type, unsigned short *width, unsigned short *height, unsigned char *bpp, const char **shell, - const char **directory, - const char **ip_addr); + const char **directory); /** * Send an E_SCP_CREATE_SESSION_RESPONSE (SCP server) * * @param trans SCP transport - * @param auth_result 0 for success, PAM error code otherwise - * @param display Should be zero if authentication failed. - * @param guid Guid for session. Should be all zeros if authentication failed + * @param status Status of creation request + * @param display Should be zero if create session failed. + * @param guid Guid for session. Should be all zeros if create session failed * * @return != 0 for error */ int scp_send_create_session_response(struct trans *trans, - int auth_result, + enum scp_screate_status status, int display, const struct guid *guid); @@ -308,73 +377,29 @@ scp_send_create_session_response(struct trans *trans, * Parse an incoming E_SCP_CREATE_SESSION_RESPONSE (SCP client) * * @param trans SCP transport - * @param[out] auth_result 0 for success, PAM error code otherwise - * @param[out] display Should be zero if authentication failed. - * @param[out] guid Guid for session. Should be all zeros if authentication + * @param[out] status Status of creation request + * @param[out] display Should be zero if create session failed. + * @param[out] guid Guid for session. Should be all zeros if create session * failed * * @return != 0 for error */ int scp_get_create_session_response(struct trans *trans, - int *auth_result, + enum scp_screate_status *status, int *display, struct guid *guid); -/** - * Status of an E_SCP_LIST_SESSIONS_RESPONSE message - */ -enum scp_list_sessions_status -{ - /** - * This message contains a valid session, and other messages - * will be sent - */ - E_SCP_LS_SESSION_INFO = 0, - - /** - * This message indicates the end of a list of sessions. No session - * is contained in the message */ - E_SCP_LS_END_OF_LIST, - - /** - * Authentication failed for the user - */ - E_SCP_LS_AUTHENTICATION_FAIL = 100, - - /** - * A client-side error occurred allocating memory for the session - */ - E_SCP_LS_NO_MEMORY -}; - /** * Send an E_LIST_SESSIONS_REQUEST (SCP client) * * @param trans SCP transport - * @param username Username - * @param password Password * @return != 0 for error * * Server replies with one or more E_SCP_LIST_SESSIONS_RESPONSE */ int -scp_send_list_sessions_request(struct trans *trans, - const char *username, - const char *password); - -/** - * Parse an incoming E_LIST_SESSIONS_REQUEST (SCP server) - * - * @param trans SCP transport - * @param[out] username Username - * @param[out] password Password - * @return != 0 for error - */ -int -scp_get_list_sessions_request(struct trans *trans, - const char **username, - const char **password); +scp_send_list_sessions_request(struct trans *trans); /** * Send an E_LIST_SESSIONS_RESPONSE (SCP server) @@ -411,5 +436,16 @@ scp_get_list_sessions_response( enum scp_list_sessions_status *status, struct scp_session_info **info); +/** + * Send an E_CLOSE_CONNECTION_REQUEST (SCP client) + * + * @param trans SCP transport + * @return != 0 for error + * + * Server closes the connection quietly. + */ +int +scp_send_close_connection_request(struct trans *trans); + #endif /* SCP_H */ diff --git a/libipm/scp_application_types.c b/libipm/scp_application_types.c new file mode 100644 index 00000000..08d4353f --- /dev/null +++ b/libipm/scp_application_types.c @@ -0,0 +1,84 @@ +/** + * 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_application_types.c + * @brief Support routines for types in scp_application_types.h + * @author Matt Burt + */ + +#if defined(HAVE_CONFIG_H) +#include +#endif + +#include "scp_application_types.h" +#include "os_calls.h" + +/*****************************************************************************/ +const char * +scp_login_status_to_str(enum scp_login_status n, + char *buff, unsigned int buff_size) +{ + const char *str = + (n == E_SCP_LOGIN_OK) ? "OK" : + (n == E_SCP_LOGIN_ALREADY_LOGGED_IN) ? "A user is already logged in" : + (n == E_SCP_LOGIN_NO_MEMORY) ? "No memory for login" : + (n == E_SCP_LOGIN_NOT_AUTHENTICATED) ? "User does not exist, or could not be authenticated" : + (n == E_SCP_LOGIN_NOT_AUTHORIZED) ? "User is not authorized" : + (n == E_SCP_LOGIN_GENERAL_ERROR) ? "General login error" : + /* Default */ NULL; + + if (str == NULL) + { + g_snprintf(buff, buff_size, "[login error code #%d]", (int)n); + } + else + { + g_snprintf(buff, buff_size, "%s", str); + } + + return buff; +} + +/*****************************************************************************/ +const char * +scp_screate_status_to_str(enum scp_screate_status n, + char *buff, unsigned int buff_size) +{ + const char *str = + (n == E_SCP_SCREATE_OK) ? "OK" : + (n == E_SCP_SCREATE_NO_MEMORY) ? "No memory for session" : + (n == E_SCP_SCREATE_NOT_LOGGED_IN) ? "Connection is not logged in" : + (n == E_SCP_SCREATE_MAX_REACHED) ? "Max session limit reached" : + (n == E_SCP_SCREATE_NO_DISPLAY) ? "No X displays are avaiable" : + (n == E_SCP_SCREATE_GENERAL_ERROR) ? "General session creation error" : + /* Default */ NULL; + + if (str == NULL) + { + g_snprintf(buff, buff_size, "[session creation error code #%d]", + (int)n); + } + else + { + g_snprintf(buff, buff_size, "%s", str); + } + + return buff; +} diff --git a/libipm/scp_application_types.h b/libipm/scp_application_types.h index d8e7c01a..0f6083bc 100644 --- a/libipm/scp_application_types.h +++ b/libipm/scp_application_types.h @@ -26,7 +26,7 @@ #ifndef SCP_APPLICATION_TYPES_H #define SCP_APPLICATION_TYPES_H -#include +#include /** * Select the desktop application session type @@ -57,9 +57,85 @@ struct scp_session_info unsigned short height; ///< Initial session height unsigned char bpp; ///< Session bits-per-pixel time_t start_time; ///< When session was created - char *username; ///< Username for session + uid_t uid; ///< Username for session char *start_ip_addr; ///< IP address of starting client }; +/** + * Status of a login request + */ +enum scp_login_status +{ + E_SCP_LOGIN_OK = 0, ///< The connection is now loggned in + E_SCP_LOGIN_ALREADY_LOGGED_IN, //< A user is currently logged in + E_SCP_LOGIN_NO_MEMORY, ///< Memory allocation failure + /** + * User couldn't be authenticated, or user doesn't exist */ + E_SCP_LOGIN_NOT_AUTHENTICATED, + E_SCP_LOGIN_NOT_AUTHORIZED, ///< User is authenticated, but not authorized + E_SCP_LOGIN_GENERAL_ERROR ///< An unspecific error has occurred +}; + +/** + * Convert an scp_login_status code to a readable string for output + * @param n Message code + * @param buff to contain string + * @param buff_size length of buff + * @return buff is returned for convenience. + */ +const char * +scp_login_status_to_str(enum scp_login_status n, + char *buff, unsigned int buff_size); + +/** + * Status of a session creation request + */ +enum scp_screate_status +{ + E_SCP_SCREATE_OK = 0, ///< Session created + E_SCP_SCREATE_NO_MEMORY, ///< Memory allocation failure + E_SCP_SCREATE_NOT_LOGGED_IN, ///< Connection is not logged in + E_SCP_SCREATE_MAX_REACHED, ///< Max number of sessions already reached + E_SCP_SCREATE_NO_DISPLAY, ///< No X server display number is available + E_SCP_SCREATE_GENERAL_ERROR ///< An unspecific error has occurred +}; + +/** + * Convert an scp_session creation code to a readable string for output + * @param n Message code + * @param buff to contain string + * @param buff_size length of buff + * @return buff is returned for convenience. + */ +const char * +scp_screate_status_to_str(enum scp_screate_status n, + char *buff, unsigned int buff_size); + +/** + * Status of an list sessions message + */ +enum scp_list_sessions_status +{ + /** + * This message contains a valid session, and other messages + * will be sent + */ + E_SCP_LS_SESSION_INFO = 0, + + /** + * This message indicates the end of a list of sessions. No session + * is contained in the message */ + E_SCP_LS_END_OF_LIST, + + /** + * Client hasn't logged in yet + */ + E_SCP_LS_NOT_LOGGED_IN = 100, + /** + * A client-side error occurred allocating memory for the session + */ + E_SCP_LS_NO_MEMORY +}; + #endif /* SCP_APPLICATION_TYPES_H */