/* return error */ int DEFAULT_CC lib_mod_event(struct mod* mod, int msg, tbus param1, tbus param2, tbus param3, tbus param4) { struct stream* s; int len; int rv; LIB_DEBUG(mod, "in lib_mod_event"); make_stream(s); init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, msg); out_uint32_le(s, param1); out_uint32_le(s, param2); out_uint32_le(s, param3); out_uint32_le(s, param4); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); rv = lib_send(mod, s->data, len); free_stream(s); LIB_DEBUG(mod, "out lib_mod_event"); return rv; }
/* return error */ int DEFAULT_CC lib_mod_signal(struct mod* mod) { LIB_DEBUG(mod, "in lib_mod_signal"); LIB_DEBUG(mod, "out lib_mod_signal"); return 0; }
/* return error */ int DEFAULT_CC lib_mod_connect(struct mod* mod) { LIB_DEBUG(mod, "in lib_mod_connect"); LIB_DEBUG(mod, "out lib_mod_connect"); return 0; }
/* return error */ int DEFAULT_CC lib_mod_event(struct mod* mod, int msg, long param1, long param2, long param3, long param4) { LIB_DEBUG(mod, "in lib_mod_event"); LIB_DEBUG(mod, "out lib_mod_event"); return 0; }
/* return error */ int DEFAULT_CC lib_mod_start(struct mod *mod, int w, int h, int bpp) { LIB_DEBUG(mod, "in lib_mod_start"); mod->width = w; mod->height = h; mod->bpp = bpp; LIB_DEBUG(mod, "out lib_mod_start"); return 0; }
int DEFAULT_CC lib_userChannel_mod_end(struct userChannel* u) { LIB_DEBUG(u, "lib_userChannel_mod_end"); if (u->mod) { xrdp_screen_delete(u->desktop); u->mod->mod_end(u->mod); } return 0; }
int DEFAULT_CC lib_userChannel_mod_start(struct userChannel* u, int w, int h, int bpp) { LIB_DEBUG(u, "lib_userChannel_mod_start"); u->server_width = w; u->server_height = h; u->server_bpp = bpp; int res = false; struct xrdp_wm* wm = (struct xrdp_wm*) u->wm; u->desktop = xrdp_screen_create(u->server_width, u->server_height, u->server_bpp, wm->client_info); res = u->mod->mod_start(u->mod, w, h, bpp); return res; }
/* return error */ int DEFAULT_CC lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2, tbus param3, tbus param4) { struct stream *s; int len; int key; int rv; LIB_DEBUG(mod, "in lib_mod_event"); make_stream(s); if ((msg >= 15) && (msg <= 16)) /* key events */ { key = param2; if (key > 0) { if (key == 65027) /* altgr */ { if (mod->shift_state) { g_writeln("special"); /* fix for mstsc sending left control down with altgr */ /* control down / up msg param1 param2 param3 param4 15 0 65507 29 0 16 0 65507 29 49152 */ init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 16); /* key up */ out_uint32_le(s, 0); out_uint32_le(s, 65507); /* left control */ out_uint32_le(s, 29); /* RDP scan code */ out_uint32_le(s, 0xc000); /* flags */ s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } } if (key == 65507) /* left control */ { mod->shift_state = msg == 15; } } } init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, msg); out_uint32_le(s, param1); out_uint32_le(s, param2); out_uint32_le(s, param3); out_uint32_le(s, param4); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); rv = lib_send(mod, s->data, len); free_stream(s); LIB_DEBUG(mod, "out lib_mod_event"); return rv; }
/* return error */ int DEFAULT_CC lib_mod_connect(struct mod *mod) { int error; int len; int i; int index; int use_uds; struct stream *s; char con_port[256]; int retry = 0; int send_error = 0; int rc = 0; unsigned int nbytes; char pidfile[128]; char ip[16]; char cookie[33]; char sessionid[128]; char sessiontoken[128]; struct passwd pwd; struct passwd *pwdresult; char pwdbuffer[16384]; char message[256]; char reply[256]; int sock; struct sockaddr_in server; json_t *request; json_t *response; json_t *display; json_error_t js_error; mod->server_msg(mod, "GoPCNX started connection", 0); sock = socket(AF_INET , SOCK_STREAM , 0); if (sock == -1) { mod->server_msg(mod, "Socket creation failed", 0); return 1; } server.sin_addr.s_addr = inet_addr("127.0.0.1"); server.sin_family = AF_INET; server.sin_port = htons(9999); if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { mod->server_msg(mod, "Server connection failed", 0); return 1; } request = json_object(); json_object_set(request, "username", json_string(mod->username)); json_object_set(request, "password", json_string(mod->password)); json_object_set(request, "ip", json_string("127.0.0.1")); json_object_set(request, "link", json_string("lan")); display = json_object(); json_object_set(display, "width", json_integer(mod->width)); json_object_set(display, "height", json_integer(mod->height)); json_object_set(request, "display", display); json_decref(display); g_snprintf(message, sizeof(message)-1, "%s\n", json_dumps(request, 0)); json_decref(request); if (send(sock, message, strlen(message), 0) < 0) { mod->server_msg(mod, "Server request failed", 0); return 1; } if (recv(sock, reply, sizeof(reply), 0) < 0) { mod->server_msg(mod, "Server reply failed", 0); return 1; } response = json_loads(reply, 0, &js_error); if (response == NULL) { mod->server_msg(mod, "Decoding response failed", 0); return 1; } else { json_t *nxsession = json_object_get(response, "session"); json_t *err = json_object_get(response, "err"); int resume = json_is_true(json_object_get(response, "resume")); if (err) { mod->server_msg(mod, json_string_value(err), 0); return 1; } else if (resume) { resize_nxproxy(mod); } else { char sessionstash[512]; const char *cookie = json_string_value(json_object_get(nxsession, "cookie")); const char *host = json_string_value(json_object_get(nxsession, "host")); json_int_t port = json_integer_value(json_object_get(nxsession, "port")); getpwnam_r(mod->username, &pwd, pwdbuffer, sizeof(pwdbuffer), &pwdresult); if (pwdresult == NULL) { mod->server_msg(mod, "Uid lookup failed", 0); return 1; } if (!start_nxproxy(mod, cookie, (int)port)) { mod->server_msg(mod, "nxproxy failed to start", 0); return 1; } json_decref(nxsession); } } json_decref(response); LIB_DEBUG(mod, "in lib_mod_connect"); /* clear screen */ mod->server_begin_update(mod); mod->server_set_fgcolor(mod, 0); mod->server_fill_rect(mod, 0, 0, mod->width, mod->height); mod->server_end_update(mod); mod->server_msg(mod, "started connecting", 0); /* only support 8, 15, 16, and 24 bpp connections from rdp client */ if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24) { mod->server_msg(mod, "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } if (g_strcmp(mod->ip, "") == 0) { mod->server_msg(mod, "error - no ip set", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } make_stream(s); g_snprintf(con_port, 255, "%s", mod->port); use_uds = 0; if (con_port[0] == '/') { use_uds = 1; } mod->sck_closed = 0; i = 0; RECONNECT: while (1) { if (use_uds) { mod->sck = g_tcp_local_socket(); } else { mod->sck = g_tcp_socket(); g_tcp_set_non_blocking(mod->sck); g_tcp_set_no_delay(mod->sck); } /* mod->server_msg(mod, "connecting...", 0); */ if (use_uds) { error = g_tcp_local_connect(mod->sck, con_port); } else { error = g_tcp_connect(mod->sck, mod->ip, con_port); } if (error == -1) { if (g_tcp_last_error_would_block(mod->sck)) { error = 0; index = 0; while (!g_tcp_can_send(mod->sck, 100)) { index++; if ((index >= 30) || mod->server_is_term(mod)) { mod->server_msg(mod, "connect timeout", 0); error = 1; break; } } } else { /* mod->server_msg(mod, "connect error", 0); */ } } if (error == 0) { break; } g_tcp_close(mod->sck); mod->sck = 0; i++; if (i >= 20) { mod->server_msg(mod, "connection problem, giving up", 0); break; } g_sleep(500); } if (error == 0) { if (use_uds) { lib_mod_log_peer(mod); } } if (error == 0) { /* send version message */ init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 301); out_uint32_le(s, 0); out_uint32_le(s, 0); out_uint32_le(s, 0); out_uint32_le(s, 1); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } if (error == 0) { /* send screen size message */ init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 300); out_uint32_le(s, mod->width); out_uint32_le(s, mod->height); out_uint32_le(s, mod->bpp); out_uint32_le(s, 0); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } if (error == 0) { /* send invalidate message */ init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 200); /* x and y */ i = 0; out_uint32_le(s, i); /* width and height */ i = ((mod->width & 0xffff) << 16) | mod->height; out_uint32_le(s, i); out_uint32_le(s, 0); out_uint32_le(s, 0); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); send_error = lib_send(mod, s->data, len); } if (send_error) { if (retry < 50) { g_tcp_close(mod->sck); mod->server_msg(mod, "Doing a retry", 0); retry++; g_sleep(1000); goto RECONNECT; } error = send_error; } free_stream(s); if (error != 0) { mod->server_msg(mod, "some problem", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } else { mod->server_msg(mod, "connected ok", 0); mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); } LIB_DEBUG(mod, "out lib_mod_connect"); return 0; }
/* return error */ int DEFAULT_CC lib_mod_signal(struct mod *mod) { struct stream *s; int num_orders; int index; int rv; int len; int type; char *phold; LIB_DEBUG(mod, "in lib_mod_signal"); make_stream(s); init_stream(s, 8192); rv = lib_recv(mod, s->data, 8); if (rv == 0) { in_uint16_le(s, type); in_uint16_le(s, num_orders); in_uint32_le(s, len); if (type == 1) /* original order list */ { init_stream(s, len); rv = lib_recv(mod, s->data, len); if (rv == 0) { for (index = 0; index < num_orders; index++) { in_uint16_le(s, type); rv = lib_mod_process_orders(mod, type, s); if (rv != 0) { break; } } } } else if (type == 2) /* caps */ { g_writeln("lib_mod_signal: type 2 len %d", len); init_stream(s, len); rv = lib_recv(mod, s->data, len); if (rv == 0) { for (index = 0; index < num_orders; index++) { phold = s->p; in_uint16_le(s, type); in_uint16_le(s, len); switch (type) { default: g_writeln("lib_mod_signal: unknown cap type %d len %d", type, len); break; } s->p = phold + len; } lib_send_client_info(mod); } } else if (type == 3) /* order list with len after type */ { init_stream(s, len); rv = lib_recv(mod, s->data, len); if (rv == 0) { for (index = 0; index < num_orders; index++) { phold = s->p; in_uint16_le(s, type); in_uint16_le(s, len); rv = lib_mod_process_orders(mod, type, s); if (rv != 0) { break; } s->p = phold + len; } } } else { g_writeln("unknown type %d", type); } } free_stream(s); LIB_DEBUG(mod, "out lib_mod_signal"); return rv; }
/* return error */ int DEFAULT_CC lib_mod_signal(struct mod* mod) { struct stream* s; int num_orders; int index; int rv; int len; int type; int x; int y; int cx; int cy; int fgcolor; int opcode; int width; int height; int srcx; int srcy; int len_bmpdata; int style; int x1; int y1; int x2; int y2; char* bmpdata; char cur_data[32 * (32 * 3)]; char cur_mask[32 * (32 / 8)]; LIB_DEBUG(mod, "in lib_mod_signal"); make_stream(s); init_stream(s, 8192); rv = lib_recv(mod, s->data, 8); if (rv == 0) { in_uint16_le(s, type); in_uint16_le(s, num_orders); in_uint32_le(s, len); if (type == 1) { init_stream(s, len); rv = lib_recv(mod, s->data, len); if (rv == 0) { for (index = 0; index < num_orders; index++) { in_uint16_le(s, type); //g_writeln("-------------lib_mod_signal: type=%d",type); switch (type) { case 1: /* server_begin_update */ rv = mod->server_begin_update(mod); break; case 2: /* server_end_update */ rv = mod->server_end_update(mod); break; case 3: /* server_fill_rect */ in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); rv = mod->server_fill_rect(mod, x, y, cx, cy); break; case 4: /* server_screen_blt */ in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); in_sint16_le(s, srcx); in_sint16_le(s, srcy); rv = mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy); break; case 5: /* server_paint_rect */ in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); in_uint32_le(s, len_bmpdata); in_uint8p(s, bmpdata, len_bmpdata); in_uint16_le(s, width); in_uint16_le(s, height); in_sint16_le(s, srcx); in_sint16_le(s, srcy); rv = mod->server_paint_rect(mod, x, y, cx, cy, bmpdata, width, height, srcx, srcy); break; case 10: /* server_set_clip */ in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); rv = mod->server_set_clip(mod, x, y, cx, cy); break; case 11: /* server_reset_clip */ rv = mod->server_reset_clip(mod); break; case 12: /* server_set_fgcolor */ in_uint32_le(s, fgcolor); rv = mod->server_set_fgcolor(mod, fgcolor); break; case 14: in_uint16_le(s, opcode); rv = mod->server_set_opcode(mod, opcode); break; case 17: in_uint16_le(s, style); in_uint16_le(s, width); rv = mod->server_set_pen(mod, style, width); break; case 18: in_sint16_le(s, x1); in_sint16_le(s, y1); in_sint16_le(s, x2); in_sint16_le(s, y2); rv = mod->server_draw_line(mod, x1, y1, x2, y2); break; case 19: in_sint16_le(s, x); in_sint16_le(s, y); in_uint8a(s, cur_data, 32 * (32 * 3)); in_uint8a(s, cur_mask, 32 * (32 / 8)); rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask); break; default: rv = 1; break; } if (rv != 0) { break; } } } } } free_stream(s); LIB_DEBUG(mod, "out lib_mod_signal"); return rv; }
/* return error */ int DEFAULT_CC lib_mod_connect(struct mod* mod) { int error; int len; int i; int index; int use_uds; struct stream* s; char con_port[256]; LIB_DEBUG(mod, "in lib_mod_connect"); /* clear screen */ mod->server_begin_update(mod); mod->server_set_fgcolor(mod, 0); mod->server_fill_rect(mod, 0, 0, mod->width, mod->height); mod->server_end_update(mod); mod->server_msg(mod, "started connecting", 0); /* only support 8, 15, 16, and 24 bpp connections from rdp client */ if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24) { mod->server_msg(mod, "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } if (g_strcmp(mod->ip, "") == 0) { mod->server_msg(mod, "error - no ip set", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } make_stream(s); g_sprintf(con_port, "%s", mod->port); use_uds = 0; if (con_port[0] == '/') { use_uds = 1; } mod->sck_closed = 0; i = 0; while (1) { if (use_uds) { mod->sck = g_tcp_local_socket(); } else { mod->sck = g_tcp_socket(); } g_tcp_set_non_blocking(mod->sck); g_tcp_set_no_delay(mod->sck); mod->server_msg(mod, "connecting...", 0); if (use_uds) { error = g_tcp_local_connect(mod->sck, con_port); } else { error = g_tcp_connect(mod->sck, mod->ip, con_port); } if (error == -1) { if (g_tcp_last_error_would_block(mod->sck)) { error = 0; index = 0; while (!g_tcp_can_send(mod->sck, 100)) { index++; if ((index >= 30) || mod->server_is_term(mod)) { mod->server_msg(mod, "connect timeout", 0); error = 1; break; } } } else { mod->server_msg(mod, "connect error", 0); } } if (error == 0) { break; } g_tcp_close(mod->sck); mod->sck = 0; i++; if (i >= 4) { mod->server_msg(mod, "connection problem, giving up", 0); break; } g_sleep(250); } if (error == 0) { init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 300); out_uint32_le(s, mod->width); out_uint32_le(s, mod->height); out_uint32_le(s, mod->bpp); out_uint32_le(s, mod->rfx); /* send rfx flag */ s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } if (error == 0) { init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 200); /* x and y */ i = 0; out_uint32_le(s, i); /* width and height */ i = ((mod->width & 0xffff) << 16) | mod->height; out_uint32_le(s, i); out_uint32_le(s, 0); out_uint32_le(s, 0); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } free_stream(s); if (error != 0) { mod->server_msg(mod, "some problem", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } else { mod->server_msg(mod, "connected ok", 0); mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); } LIB_DEBUG(mod, "out lib_mod_connect"); return 0; }