/* only used during connection */ struct stream * APP_CC libxrdp_force_read(struct trans* trans) { int bytes; struct stream *s; s = trans->in_s; init_stream(s, 32 * 1024); if (trans_force_read(trans, 4) != 0) { g_writeln("libxrdp_force_read: error"); return 0; } bytes = libxrdp_get_pdu_bytes(s->data); if (bytes < 1) { g_writeln("libxrdp_force_read: error"); return 0; } if (bytes > 32 * 1024) { g_writeln("libxrdp_force_read: error"); return 0; } if (trans_force_read(trans, bytes - 4) != 0) { g_writeln("libxrdp_force_read: error"); return 0; } return s; }
static int xrdp_caps_process_glyphcache(struct xrdp_rdp *self, struct stream *s, int len) { int glyph_support_level; if (len < 40 + 4 + 2 + 2) /* MS-RDPBCGR 2.2.7.1.8 */ { g_writeln("xrdp_caps_process_glyphcache: error"); return 1; } in_uint8s(s, 40); /* glyph cache */ in_uint8s(s, 4); /* frag cache */ in_uint16_le(s, glyph_support_level); in_uint8s(s, 2); /* pad */ if (glyph_support_level == GLYPH_SUPPORT_ENCODE) { self->client_info.use_cache_glyph_v2 = 1; } g_writeln("xrdp_caps_process_glyphcache: support level %d ", glyph_support_level); return 0; }
enum logReturns DEFAULT_CC internalReadConfiguration(const char *inFilename, const char *applicationName) { int fd; enum logReturns ret = LOG_GENERAL_ERROR; struct list *sec; struct list *param_n; struct list *param_v; if (inFilename == NULL) { g_writeln("The inifile is null to readConfiguration!"); return ret; } fd = g_file_open(inFilename); if (-1 == fd) { ret = LOG_ERROR_NO_CFG; g_writeln("We could not open the configuration file to read log parameters"); return ret; } /* we initialize the memory for the configuration and set all content to zero. */ ret = internalInitAndAllocStruct(); if (ret != LOG_STARTUP_OK) { g_file_close(fd); return ret; } sec = list_create(); sec->auto_free = 1; file_read_sections(fd, sec); param_n = list_create(); param_n->auto_free = 1; param_v = list_create(); param_v->auto_free = 1; /* read logging config */ ret = internal_config_read_logging(fd, g_staticLogConfig, param_n, param_v, applicationName); if (ret != LOG_STARTUP_OK) { g_file_close(fd); return ret; } /* cleanup */ list_delete(sec); list_delete(param_v); list_delete(param_n); g_file_close(fd); return ret; }
static int APP_CC xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len) { g_writeln("xrdp_caps_process_frame_ack:"); self->client_info.use_frame_acks = 1; in_uint32_le(s, self->client_info.max_unacknowledged_frame_count); g_writeln(" max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count); return 0; }
static int APP_CC xrdp_caps_process_surface_cmds(struct xrdp_rdp *self, struct stream *s, int len) { int cmdFlags; g_writeln("xrdp_caps_process_surface_cmds:"); in_uint32_le(s, cmdFlags); in_uint8s(s, 4); /* reserved */ g_writeln(" cmdFlags 0x%08x", cmdFlags); return 0; }
void xrdp_shutdown(int sig) { LONG_PTR threadid; threadid = tc_get_threadid(); g_writeln("shutting down"); g_writeln("signal %d threadid %p", sig, threadid); if (WaitForSingleObject(g_TermEvent, 0) != WAIT_OBJECT_0) SetEvent(g_TermEvent); }
enum logReturns DEFAULT_CC log_start_from_param(const struct log_config *iniParams) { enum logReturns ret = LOG_GENERAL_ERROR; if (g_staticLogConfig != NULL) { log_message(LOG_LEVEL_ALWAYS, "Log already initialized"); return ret; } if (iniParams == NULL) { g_writeln("inparam to log_start_from_param is NULL"); return ret; } else { /*Copy the struct information*/ ret = internalInitAndAllocStruct(); if (ret != LOG_STARTUP_OK) { g_writeln("internalInitAndAllocStruct failed"); return ret; } g_staticLogConfig->enable_syslog = iniParams->enable_syslog; g_staticLogConfig->fd = iniParams->fd; g_staticLogConfig->log_file = g_strdup(iniParams->log_file); g_staticLogConfig->log_level = iniParams->log_level; g_staticLogConfig->log_lock = iniParams->log_lock; g_staticLogConfig->log_lock_attr = iniParams->log_lock_attr; g_staticLogConfig->program_name = iniParams->program_name; g_staticLogConfig->syslog_level = iniParams->syslog_level; ret = internal_log_start(g_staticLogConfig); if (ret != LOG_STARTUP_OK) { g_writeln("Could not start log"); if (g_staticLogConfig != NULL) { g_free(g_staticLogConfig); g_staticLogConfig = NULL; } } } return ret; }
void DEFAULT_CC xrdp_shutdown(int sig) { tbus threadid; threadid = tc_get_threadid(); g_writeln("shutting down"); g_writeln("signal %d threadid %p", sig, threadid); if (!g_is_wait_obj_set(g_term_event)) { g_set_wait_obj(g_term_event); } }
void APP_CC list_dump_items(struct list* self) { int index; if (self->count == 0) { g_writeln("List is empty"); } for (index = 0; index < self->count; index++) { g_writeln("%d: %s", index, list_get_item(self, index)); } }
static int xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len) { g_writeln("xrdp_caps_process_frame_ack:"); self->client_info.use_frame_acks = 1; in_uint32_le(s, self->client_info.max_unacknowledged_frame_count); if (self->client_info.max_unacknowledged_frame_count < 0) { g_writeln(" invalid max_unacknowledged_frame_count value (%d), setting to 0", self->client_info.max_unacknowledged_frame_count); self->client_info.max_unacknowledged_frame_count = 0; } g_writeln(" max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count); return 0; }
/* return error */ int DEFAULT_CC lib_mod_set_param(struct mod* mod, char* name, char* value) { if (g_strcasecmp(name, "username") == 0) { g_strncpy(mod->username, value, 255); } else if (g_strcasecmp(name, "password") == 0) { g_strncpy(mod->password, value, 255); } else if (g_strcasecmp(name, "ip") == 0) { g_strncpy(mod->ip, value, 255); } else if (g_strcasecmp(name, "port") == 0) { g_strncpy(mod->port, value, 255); } else if (g_strcasecmp(name, "rfx") == 0) { mod->rfx = g_atoi(value); g_writeln("mod->rfx = %d",mod->rfx); } return 0; }
/** * Converts a string representing th log level to a value * @param buf * @return */ enum logLevels DEFAULT_CC internal_log_text2level(const char *buf) { if (0 == g_strcasecmp(buf, "0") || 0 == g_strcasecmp(buf, "core")) { return LOG_LEVEL_ALWAYS; } else if (0 == g_strcasecmp(buf, "1") || 0 == g_strcasecmp(buf, "error")) { return LOG_LEVEL_ERROR; } else if (0 == g_strcasecmp(buf, "2") || 0 == g_strcasecmp(buf, "warn") || 0 == g_strcasecmp(buf, "warning")) { return LOG_LEVEL_WARNING; } else if (0 == g_strcasecmp(buf, "3") || 0 == g_strcasecmp(buf, "info")) { return LOG_LEVEL_INFO; } else if (0 == g_strcasecmp(buf, "4") || 0 == g_strcasecmp(buf, "debug")) { return LOG_LEVEL_DEBUG; } g_writeln("Your configured log level is corrupt - we use debug log level"); return LOG_LEVEL_DEBUG; }
/** * @brief Converts xrdp log levels to textual logging levels * @param lvl logging level * @param str pointer to a string, must be allocated before * @return The log string in str pointer. * */ void DEFAULT_CC internal_log_lvl2str(const enum logLevels lvl, char *str) { switch (lvl) { case LOG_LEVEL_ALWAYS: snprintf(str, 9, "%s", "[CORE ] "); break; case LOG_LEVEL_ERROR: snprintf(str, 9, "%s", "[ERROR] "); break; case LOG_LEVEL_WARNING: snprintf(str, 9, "%s", "[WARN ] "); break; case LOG_LEVEL_INFO: snprintf(str, 9, "%s", "[INFO ] "); break; case LOG_LEVEL_DEBUG: snprintf(str, 9, "%s", "[DEBUG] "); break; default: snprintf(str, 9, "%s", "PRG ERR!"); g_writeln("Programming error - undefined log level!!!"); } }
/* returns error */ int APP_CC send_channel_data(int chan_id, char *data, int size) { int index; //g_writeln("send_channel_data chan_id %d size %d", chan_id, size); LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size)); if (chan_id == -1) { g_writeln("send_channel_data: error, chan_id is -1"); return 1; } for (index = 0; index < g_num_chan_items; index++) { if (g_chan_items[index].id == chan_id) { add_data_to_chan_item(g_chan_items + index, data, size); check_chan_items(); return 0; } } return 1; }
/** * Creates a string consisting of all parameters that is hosted in the param list * @param self * @param outstr, allocate this buffer before you use this function * @param len the allocated len for outstr * @return */ char *APP_CC dumpItemsToString(struct list *self, char *outstr, int len) { g_memset(outstr, 0, len); int index; tbus item; int totalLen = 0; if (self->count == 0) { g_writeln("List is empty"); } for (index = 0; index < self->count; index++) { /* +1 = one space*/ totalLen = totalLen + g_strlen((char *)list_get_item(self, index)) + 1; if (len > totalLen) { g_strcat(outstr, (char *)list_get_item(self, index)); g_strcat(outstr, " "); } } return outstr ; }
/* produce a hex dump */ void APP_CC g_hexdump(char* p, int len) { unsigned char* line; int i; int thisline; int offset; line = (unsigned char*)p; offset = 0; while (offset < len) { g_printf("%04x ", offset); thisline = len - offset; if (thisline > 16) { thisline = 16; } for (i = 0; i < thisline; i++) { g_printf("%02x ", line[i]); } for (; i < 16; i++) { g_printf(" "); } for (i = 0; i < thisline; i++) { g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); } g_writeln(""); offset += thisline; line += thisline; } }
int APP_CC xrdp_audit(struct xrdp_process *process, const char*action, const char* message) { // This sends an http 0.9 request, i.e. no headers char client_ip[256] = {0,}; char data[4096] = {0,}; char username[256] = {0,}; char device_name[256] = {0,}; char accesstoken[256] = {0,}; xrdp_mm_get_value(process->wm->mm, "osirium_account", username, 255); xrdp_mm_get_value(process->wm->mm, "device_name", device_name, 255); xrdp_mm_get_value(process->wm->mm, "accesstoken", accesstoken, 255); xrdp_mm_get_value(process->wm->mm, "client_ip_addr", client_ip, 255); if (username[0] == 0) { g_snprintf(username, 255, "%s", g_getenv("USER")); } if (device_name[0] == 0) { g_strcpy(device_name, "unknown"); } if (accesstoken[0] == 0) { g_strcpy(accesstoken, "unknown"); } g_snprintf(data, sizeof(data)-1, REQUEST_TEMPLATE, username, //process->wm->session->client_info->username,// username "rdp", // type device_name, //process->session->client_info->hostname, // devicename action, // action accesstoken, // accesstoken // process->server_trans->skt client_ip //process->session->client_info->hostname // client_ip ); g_writeln(data); fflush(stdout); // open socket int sck = g_tcp_socket(); fflush(stdout); if (g_tcp_connect(sck, AUDIT_ADDRESS, AUDIT_PORT) == 0) { // left as blocking socket !! fflush(stdout); // get url int sent = g_tcp_send(sck, data, g_strlen(data), 0); if ( g_tcp_can_recv(sck, 1000) > 0) // at most 1 second { // read response and ignore. int rlen = g_tcp_recv(sck, data, sizeof(data)-1, 0); } else { } fflush(stdout); // close socket g_tcp_close(sck); } }
static int APP_CC xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s, int len) { int extraFlags; int client_does_fastpath_output; if (len < 10 + 2) { g_writeln("xrdp_caps_process_general: error"); return 1; } in_uint16_le(s, self->client_info.client_os_major); /* osMajorType (2 bytes) */ in_uint16_le(s, self->client_info.client_os_minor); /* osMinorType (2 bytes) */ in_uint8s(s, 6); in_uint16_le(s, extraFlags); /* extraFlags (2 bytes) */ self->client_info.op1 = extraFlags & NO_BITMAP_COMPRESSION_HDR; /* use_compact_packets is pretty much 'use rdp5' */ self->client_info.use_compact_packets = (extraFlags != 0); /* op2 is a boolean to use compact bitmap headers in bitmap cache */ /* set it to same as 'use rdp5' boolean */ self->client_info.op2 = self->client_info.use_compact_packets; /* FASTPATH_OUTPUT_SUPPORTED 0x0001 */ client_does_fastpath_output = extraFlags & FASTPATH_OUTPUT_SUPPORTED; if ((self->client_info.use_fast_path & 1) && !client_does_fastpath_output) { /* server supports fast path output and client does not, turn it off */ self->client_info.use_fast_path &= ~1; } return 0; }
int APP_CC xrdp_caps_process_rail(struct xrdp_rdp *self, struct stream *s, int len) { int i32; if (len < 4) { g_writeln("xrdp_caps_process_rail: error"); return 1; } in_uint32_le(s, i32); self->client_info.rail_support_level = i32; g_writeln("xrdp_process_capset_rail: rail_support_level %d", self->client_info.rail_support_level); return 0; }
enum logReturns DEFAULT_CC internal_log_start(struct log_config *l_cfg) { enum logReturns ret = LOG_GENERAL_ERROR; if (0 == l_cfg) { ret = LOG_ERROR_MALLOC; return ret; } /* if logfile is NULL, we return error */ if (0 == l_cfg->log_file) { g_writeln("log_file not properly assigned"); return ret; } /* if progname is NULL, we return error */ if (0 == l_cfg->program_name) { g_writeln("program_name not properly assigned"); return ret; } /* open file */ l_cfg->fd = internal_log_file_open(l_cfg->log_file); if (-1 == l_cfg->fd) { return LOG_ERROR_FILE_OPEN; } /* if syslog is enabled, open it */ if (l_cfg->enable_syslog) { openlog(l_cfg->program_name, LOG_CONS | LOG_PID, LOG_DAEMON); } #ifdef LOG_ENABLE_THREAD pthread_mutexattr_init(&(l_cfg->log_lock_attr)); pthread_mutex_init(&(l_cfg->log_lock), &(l_cfg->log_lock_attr)); #endif return LOG_STARTUP_OK; }
static int APP_CC xrdp_caps_process_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s, int len) { int codec_id; if (len < 1) { g_writeln("xrdp_caps_process_cache_v3_codec_id: error"); return 1; } in_uint8(s, codec_id); g_writeln("xrdp_caps_process_cache_v3_codec_id: cache_v3_codec_id %d", codec_id); self->client_info.v3_codec_id = codec_id; return 0; }
void DEFAULT_CC logd_shutdown(int sig) { g_writeln("shutdown xrdp-logd daemon"); g_tcp_close(log_socket); g_file_close(log_fd); running = 0; }
int EXPORT_CC libxrdp_get_pdu_bytes(const char *aheader) { int rv; const tui8 *header; rv = -1; header = (const tui8 *) aheader; if (header[0] == 0x03) { /* TPKT */ rv = (header[2] << 8) | header[3]; } else if (header[0] == 0x30) { /* TSRequest (NLA) */ if (header[1] & 0x80) { if ((header[1] & ~(0x80)) == 1) { rv = header[2]; rv += 3; } else if ((header[1] & ~(0x80)) == 2) { rv = (header[2] << 8) | header[3]; rv += 4; } else { g_writeln("libxrdp_get_pdu_bytes: error TSRequest!"); return -1; } } else { rv = header[1]; rv += 2; } } else { /* Fast-Path */ if (header[1] & 0x80) { rv = ((header[1] & 0x7F) << 8) | header[2]; } else { rv = header[1]; } } return rv; }
void APP_CC logd_main_loop() { int client = 0; char buffer[1024]; int count; log_fd = open(LOGGING_FILE, O_WRONLY | O_CREAT | O_APPEND | O_SYNC, S_IRUSR | S_IWUSR); g_mkdir("/var/spool/xrdp"); g_chmod_hex("/var/spool/xrdp", 0775); if ( g_directory_exist("/var/spool/xrdp") == 0) { g_writeln("Unable to create the logging socket"); g_exit(1); } g_writeln("xrdp logging spool application\n"); log_socket = g_create_unix_socket(LOGGING_SOCKET); g_chmod_hex(LOGGING_SOCKET, 0xFFFF); if ( log_socket == 1) { g_writeln("Unable to create logging socket"); return ; } if (log_fd < 0){ g_writeln("Unable to create logging instance\n"); } running = 1; while(running) { client = g_wait_connection(log_socket); count = g_tcp_recv(client, (char*)buffer, 1024, 0); while(count > 0) { g_file_write(log_fd, buffer, count); count = g_tcp_recv(client, (char*)buffer, 1024, 0); } count = 0; g_tcp_close(client); } }
int APP_CC xrdp_tls_print_error(char *func, SSL *connection, int value) { switch (SSL_get_error(connection, value)) { case SSL_ERROR_ZERO_RETURN: g_writeln("xrdp_tls_print_error: %s: Server closed TLS connection", func); return 1; case SSL_ERROR_WANT_READ: g_writeln("xrdp_tls_print_error: SSL_ERROR_WANT_READ"); return 0; case SSL_ERROR_WANT_WRITE: g_writeln("xrdp_tls_print_error: SSL_ERROR_WANT_WRITE"); return 0; case SSL_ERROR_SYSCALL: g_writeln("xrdp_tls_print_error: %s: I/O error", func); return 1; case SSL_ERROR_SSL: g_writeln("xrdp_tls_print_error: %s: Failure in SSL library (protocol error?)", func); return 1; default: g_writeln("xrdp_tls_print_error: %s: Unknown error", func); return 1; } }
/* get the number of client cursor cache */ static int APP_CC xrdp_caps_process_pointer(struct xrdp_rdp *self, struct stream *s, int len) { int i; int colorPointerFlag; int no_new_cursor; if (len < 2 + 2 + 2) { g_writeln("xrdp_caps_process_pointer: error"); return 1; } no_new_cursor = self->client_info.pointer_flags & 2; in_uint16_le(s, colorPointerFlag); self->client_info.pointer_flags = colorPointerFlag; in_uint16_le(s, i); i = MIN(i, 32); self->client_info.pointer_cache_entries = i; if (colorPointerFlag & 1) { g_writeln("xrdp_caps_process_pointer: client supports " "new(color) cursor"); in_uint16_le(s, i); i = MIN(i, 32); self->client_info.pointer_cache_entries = i; } else { g_writeln("xrdp_caps_process_pointer: client does not support " "new(color) cursor"); } if (no_new_cursor) { g_writeln("xrdp_caps_process_pointer: new(color) cursor is " "disabled by config"); self->client_info.pointer_flags = 0; } return 0; }
int DEFAULT_CC server_msg(struct xrdp_mod* mod, char* msg, int code) { struct xrdp_wm* wm; if (code == 1) { g_writeln(msg); return 0; } wm = (struct xrdp_wm*)(mod->wm); return xrdp_wm_log_msg(wm, msg); }
/*Returns 0 on success*/ int g_tcp_set_no_delay(int sck) { int ret = 1; /* error */ #if defined(_WIN32) int option_value; int option_len; #else int option_value; unsigned int option_len; #endif option_len = sizeof(option_value); /* SOL_TCP IPPROTO_TCP */ if (getsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char *) &option_value, &option_len) == 0) { if (option_value == 0) { option_value = 1; option_len = sizeof(option_value); if (setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char *) &option_value, option_len) == 0) { ret = 0; /* success */ } else { g_writeln("Error setting tcp_nodelay"); } } } else { g_writeln("Error getting tcp_nodelay"); } return ret; }
/*Returns 0 on success*/ int g_tcp_set_keepalive(int sck) { int ret = 1; /* error */ #if defined(_WIN32) int option_value; int option_len; #else int option_value; unsigned int option_len; #endif option_len = sizeof(option_value); /* SOL_TCP IPPROTO_TCP */ if (getsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char *) &option_value, &option_len) == 0) { if (option_value == 0) { option_value = 1; option_len = sizeof(option_value); if (setsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char *) &option_value, option_len) == 0) { ret = 0; /* success */ } else { g_writeln("Error setting tcp_keepalive"); } } } else { g_writeln("Error getting tcp_keepalive"); } return ret; }
static int APP_CC xrdp_caps_process_window(struct xrdp_rdp *self, struct stream *s, int len) { int i32; if (len < 4 + 1 + 2) { g_writeln("xrdp_caps_process_window: error"); return 1; } in_uint32_le(s, i32); self->client_info.wnd_support_level = i32; in_uint8(s, i32); self->client_info.wnd_num_icon_caches = i32; in_uint16_le(s, i32); self->client_info.wnd_num_icon_cache_entries = i32; g_writeln("xrdp_process_capset_window wnd_support_level %d " "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d", self->client_info.wnd_support_level, self->client_info.wnd_num_icon_caches, self->client_info.wnd_num_icon_cache_entries); return 0; }