static int ProcXResQueryClientPixmapBytes (ClientPtr client) { REQUEST(xXResQueryClientPixmapBytesReq); xXResQueryClientPixmapBytesReply rep; int clientID; unsigned long bytes; REQUEST_SIZE_MATCH(xXResQueryClientPixmapBytesReq); clientID = CLIENT_ID(stuff->xid); if((clientID >= currentMaxClients) || !clients[clientID]) { client->errorValue = stuff->xid; return BadValue; } bytes = 0; FindClientResourcesByType(clients[clientID], RT_PIXMAP, ResFindPixmaps, (pointer)(&bytes)); /* * Make sure win background pixmaps also held to account. */ FindClientResourcesByType(clients[clientID], RT_WINDOW, ResFindWindowPixmaps, (pointer)(&bytes)); /* * GC Tile & Stipple pixmaps too. */ FindClientResourcesByType(clients[clientID], RT_GC, ResFindGCPixmaps, (pointer)(&bytes)); #ifdef COMPOSITE /* FIXME: include composite pixmaps too */ #endif rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; rep.bytes = bytes; #ifdef _XSERVER64 rep.bytes_overflow = bytes >> 32; #else rep.bytes_overflow = 0; #endif if (client->swapped) { int n; swaps (&rep.sequenceNumber, n); swapl (&rep.length, n); swapl (&rep.bytes, n); swapl (&rep.bytes_overflow, n); } WriteToClient (client,sizeof(xXResQueryClientPixmapBytesReply),(char*)&rep); return (client->noClientException); }
int dixLookupClient(ClientPtr *pClient, XID rid, ClientPtr client, Mask access) { pointer pRes; int rc = BadValue, clientIndex = CLIENT_ID(rid); if (!clientIndex || !clients[clientIndex] || (rid & SERVER_BIT)) goto bad; rc = dixLookupResourceByClass(&pRes, rid, RC_ANY, client, DixGetAttrAccess); if (rc != Success) goto bad; rc = XaceHook(XACE_CLIENT_ACCESS, client, clients[clientIndex], access); if (rc != Success) goto bad; *pClient = clients[clientIndex]; return Success; bad: if (client) client->errorValue = rid; *pClient = NULL; return rc; }
/* * Free one of the per-client per-window resources, clearing * redirect and the per-window pointer as appropriate */ void compFreeClientWindow (WindowPtr pWin, XID id) { CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw, *prev; Bool wasMapped = pWin->mapped; if (!cw) return; for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next) { if (ccw->id == id) { *prev = ccw->next; if (ccw->update == CompositeRedirectManual) cw->update = CompositeRedirectAutomatic; free(ccw); break; } } if (!cw->clients) { if (wasMapped) { DisableMapUnmapEvents (pWin); UnmapWindow (pWin, FALSE); EnableMapUnmapEvents (pWin); } if (pWin->redirectDraw != RedirectDrawNone) compFreePixmap (pWin); if (cw->damage) DamageDestroy (cw->damage); RegionUninit(&cw->borderClip); dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL); free(cw); } else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone) { DamageRegister (&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; pWin->redirectDraw = RedirectDrawAutomatic; DamageRegionAppend(&pWin->drawable, &pWin->borderSize); } if (wasMapped && !pWin->mapped) { Bool overrideRedirect = pWin->overrideRedirect; pWin->overrideRedirect = TRUE; DisableMapUnmapEvents (pWin); MapWindow (pWin, clients[CLIENT_ID(id)]); EnableMapUnmapEvents (pWin); pWin->overrideRedirect = overrideRedirect; } }
/* * Handles a message received from the UDP tunnel. Returns 0 if successful, -1 * on some error it handled, or -2 if the client is to disconnect. */ int handle_message(client_t *c, uint16_t id, uint8_t msg_type, char *data, int data_len) { int ret = 0; char addrstr[ADDRSTRLEN]; switch(msg_type) { case MSG_TYPE_GOODBYE: ret = -2; break; case MSG_TYPE_HELLOACK: client_got_helloack(c); CLIENT_ID(c) = id; ret = client_send_helloack(c, ntohs(*((uint16_t *)data))); if(debug_level >= DEBUG_LEVEL1) { sock_get_str(c->tcp_sock, addrstr, sizeof(addrstr)); printf("New connection(%d): tcp://%s", CLIENT_ID(c), addrstr); sock_get_str(c->udp_sock, addrstr, sizeof(addrstr)); printf(" -> udp://%s\n", addrstr); } break; case MSG_TYPE_DATA0: case MSG_TYPE_DATA1: ret = client_got_udp_data(c, data, data_len, msg_type); if(ret == 0) ret = client_send_tcp_data(c); break; case MSG_TYPE_ACK0: case MSG_TYPE_ACK1: ret = client_got_ack(c, msg_type); break; default: ret = -1; break; } return ret; }
/* * Checks the timeout state of the client and resend the data if the timeout * is up. */ int client_check_and_resend(client_t* client, struct timeval curr_tv) { if((client->tcp2udp_state == CLIENT_WAIT_ACK0 || client->tcp2udp_state == CLIENT_WAIT_ACK1) && timercmp(&curr_tv, &client->tcp2udp_timeout, >)) { client->resend_count++; if(debug_level >= DEBUG_LEVEL2) printf("client(%d): resending data, count %d\n", CLIENT_ID(client), client->resend_count); return client_send_udp_data(client); }
/*! * \brief * Callback for when new data is available in a pipe * * \param[in] source the event source * \param[in] condition the condition which has been satisfied * \param[in] data an unsigned integer as specified by #CHANNEL_ID, * converted to a \c gpointer using * \c GUINT_TO_POINTER() * * \return * \c FALSE when the event source should be removed, otherwise \c TRUE */ static gboolean io_watch_callback(GIOChannel *source, GIOCondition condition, gpointer data) { const guint8 input_type = GPOINTER_TO_UINT(data); gchar buffer[BUFFER_SIZE]; gsize bytes_read; GError *error = NULL; GIOStatus status; GIOChannel *write_to = NULL; if (IS_STDOUT(input_type)) { write_to = channel_stdin[1 ^ CLIENT_ID(input_type)]; } do { status = g_io_channel_read_chars(source, buffer, BUFFER_SIZE, &bytes_read, &error); if (error != NULL) { stop_channels(source, write_to); print_error(error->message); return FALSE; } if (bytes_read == 0) continue; if (write_to != NULL) { g_io_channel_write_chars(write_to, buffer, bytes_read, NULL, NULL); g_io_channel_flush(write_to, NULL); } append_text(buffer, bytes_read, input_type); } while (status == G_IO_STATUS_NORMAL); if ((condition & ~G_IO_IN) != 0) { stop_channels(source, write_to); return FALSE; } /* for some reason I can't figure out, this function is called repeatedly with condition==G_IO_IN when the client process ends - this check should prevent the program from becoming unresponsive and consuming 100% CPU */ return clients[CLIENT_ID(input_type)].is_running; }
int compUnredirectSubwindows(ClientPtr pClient, WindowPtr pWin, int update) { CompSubwindowsPtr csw = GetCompSubwindows(pWin); CompClientWindowPtr ccw; if (!csw) return BadValue; for (ccw = csw->clients; ccw; ccw = ccw->next) if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index) { FreeResource(ccw->id, RT_NONE); return Success; } return BadValue; }
/* * Closes the TCP and UDP connections for the client and remove its stuff from * the lists. */ void disconnect_and_remove_client(uint16_t id, list_t* clients, fd_set* fds) { client_t* c; c = list_get(clients, &id); if(!c) return; client_send_goodbye(c); if(debug_level >= DEBUG_LEVEL1) printf("Client %d disconnected.\n", CLIENT_ID(c)); client_remove_udp_fd_from_set(c, fds); client_remove_tcp_fd_from_set(c, fds); client_disconnect_tcp(c); client_disconnect_udp(c); list_delete(clients, &id); }
/* * Free one of the per-client per-subwindows resources, * which frees one redirect per subwindow */ void compFreeClientSubwindows (WindowPtr pWin, XID id) { CompSubwindowsPtr csw = GetCompSubwindows (pWin); CompClientWindowPtr ccw, *prev; WindowPtr pChild; if (!csw) return; for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next) { if (ccw->id == id) { ClientPtr pClient = clients[CLIENT_ID(id)]; *prev = ccw->next; if (ccw->update == CompositeRedirectManual) { /* * tell damage extension that damage events for this client are * critical output */ DamageExtSetCritical (pClient, FALSE); csw->update = CompositeRedirectAutomatic; if (pWin->mapped) (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE); } /* * Unredirect all existing subwindows */ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) (void) compUnredirectWindow (pClient, pChild, ccw->update); free(ccw); break; } } /* * Check if all of the per-client records are gone */ if (!csw->clients) { dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, NULL); free(csw); } }
static void SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceResourceAccessRec *rec = calldata; SecurityStateRec *subj, *obj; int cid = CLIENT_ID(rec->id); Mask requested = rec->access_mode; Mask allowed = SecurityResourceMask; subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); /* disable background None for untrusted windows */ if ((requested & DixCreateAccess) && (rec->rtype == RT_WINDOW)) if (subj->haveState && subj->trustLevel != XSecurityClientTrusted) ((WindowPtr)rec->res)->forcedBG = TRUE; /* additional permissions for specific resource types */ if (rec->rtype == RT_WINDOW) allowed |= SecurityWindowExtraMask; /* special checks for server-owned resources */ if (cid == 0) { if (rec->rtype & RC_DRAWABLE) /* additional operations allowed on root windows */ allowed |= SecurityRootWindowExtraMask; else if (rec->rtype == RT_COLORMAP) /* allow access to default colormaps */ allowed = requested; else /* allow read access to other server-owned resources */ allowed |= DixReadAccess; } if (clients[cid] != NULL) { obj = dixLookupPrivate(&clients[cid]->devPrivates, stateKey); if (SecurityDoCheck(subj, obj, requested, allowed) == Success) return; } SecurityAudit("Security: denied client %d access %x to resource 0x%x " "of client %d on request %s\n", rec->client->index, requested, rec->id, cid, SecurityLookupRequestName(rec->client)); rec->status = BadAccess; /* deny access */ }
int compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin) { CompSubwindowsPtr csw = GetCompSubwindows (pParent); CompClientWindowPtr ccw; if (!csw) return Success; for (ccw = csw->clients; ccw; ccw = ccw->next) { int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)], pWin, ccw->update); if (ret != Success) return ret; } return Success; }
void UngrabAllDevices(Bool kill_client) { DeviceIntPtr dev; ClientPtr client; ErrorF("Ungrabbing all devices%s; grabs listed below:\n", kill_client ? " and killing their owners" : ""); for (dev = inputInfo.devices; dev; dev = dev->next) { if (!dev->deviceGrab.grab) continue; PrintDeviceGrabInfo(dev); client = clients[CLIENT_ID(dev->deviceGrab.grab->resource)]; if (!kill_client || !client || client->clientGone) dev->deviceGrab.DeactivateGrab(dev); if (kill_client) CloseDownClient(client); } ErrorF("End list of ungrabbed devices\n"); }
static int ProcXResQueryClientResources (ClientPtr client) { REQUEST(xXResQueryClientResourcesReq); xXResQueryClientResourcesReply rep; int i, clientID, num_types; int *counts; REQUEST_SIZE_MATCH(xXResQueryClientResourcesReq); clientID = CLIENT_ID(stuff->xid); if((clientID >= currentMaxClients) || !clients[clientID]) { client->errorValue = stuff->xid; return BadValue; } counts = xcalloc(lastResourceType + 1, sizeof(int)); FindAllClientResources(clients[clientID], ResFindAllRes, counts); num_types = 0; for(i = 0; i <= lastResourceType; i++) { if(counts[i]) num_types++; } rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.num_types = num_types; rep.length = bytes_to_int32(rep.num_types * sz_xXResType); if (client->swapped) { int n; swaps (&rep.sequenceNumber, n); swapl (&rep.length, n); swapl (&rep.num_types, n); } WriteToClient (client,sizeof(xXResQueryClientResourcesReply),(char*)&rep); if(num_types) { xXResType scratch; char *name; for(i = 0; i < lastResourceType; i++) { if(!counts[i]) continue; name = (char *)LookupResourceName(i + 1); if (strcmp(name, XREGISTRY_UNKNOWN)) scratch.resource_type = MakeAtom(name, strlen(name), TRUE); else { char buf[40]; snprintf(buf, sizeof(buf), "Unregistered resource %i", i + 1); scratch.resource_type = MakeAtom(buf, strlen(buf), TRUE); } scratch.count = counts[i]; if(client->swapped) { int n; swapl (&scratch.resource_type, n); swapl (&scratch.count, n); } WriteToClient (client, sz_xXResType, (char *) &scratch); } } xfree(counts); return (client->noClientException); }
/* * Handles a message received from the UDP tunnel. Returns 0 if successful, -1 * on some error it handled, or -2 if the client is to disconnect. */ int handle_message(uint16_t id, uint8_t msg_type, char *data, int data_len,uint32_t sourceid, list_t *clients,list_t *conn_clients) { client_t *c; client_t *c2; int ret = 0; uint16_t req_id; char addrstr[ADDRSTRLEN]; if(debug_level >= DEBUG_LEVEL2) printf("handle msg from %d type %d \n ",sourceid,msg_type); switch(msg_type) { case MSG_TYPE_GOODBYE: ret = -2; break; case MSG_TYPE_HELLOACK: { char * ptr_de=NULL; char * keyfile=malloc(64); sprintf(keyfile,"%s.key",lhost); req_id = ntohs(*((uint16_t*)data)); //req_id = ntohs(*((uint16_t*)data)); data+=sizeof(req_id); data_len-=sizeof(req_id); ptr_de=my_rsadecrypt(data,keyfile); printf("key is %s",ptr_de); if(debug_level >= DEBUG_LEVEL1) printf("req id %d ",req_id); c = list_get(conn_clients, &req_id); if(debug_level >= DEBUG_LEVEL1) printf("find client %d \n",CLIENT_ID(c)); client_got_helloack(c); CLIENT_ID(c) = id; memcpy(c->deskey,ptr_de,strlen(ptr_de)); ret = client_send_helloack(c, ntohs(*((uint16_t *)data))); if(debug_level >= DEBUG_LEVEL1) { sock_get_str(c->tcp_sock, addrstr, sizeof(addrstr)); printf("New connection(%d): tcp://%s", CLIENT_ID(c), addrstr); sock_get_str(c->udp_sock, addrstr, sizeof(addrstr)); printf(" -> udp://%s\n", addrstr); } c = list_add(clients, c, 1); list_delete(conn_clients, &id); ret = client_socks5_helloack(c); break; } case MSG_TYPE_DATA0: //case MSG_TYPE_DATA1: c = list_get(clients, &id); ret = client_got_udp_data(c, data, data_len, msg_type); if(ret == 0) ret = client_send_tcp_data(c); break; //case MSG_TYPE_ACK0: // case MSG_TYPE_ACK1: //ret = client_got_ack(c, msg_type); // break; case MSG_TYPE_RELAYKEY: { client_t *c2; if(id != 0) break; char * ptr_de; char * keyfile=malloc(64); sprintf(keyfile,"%s.key",lhost); c2 = list_get_at(relay_clients, 0); //printf("c2->rsakey is %s \n",c2->rsakey); ptr_de=my_rsadecrypt(data,keyfile); //printf("relaykey is %s len is %d \n",ptr_de,strlen(ptr_de)); memcpy(c2->rsakey,ptr_de,strlen(ptr_de)); //printf("c2->rsakey is %s \n",c2->rsakey); break; } case MSG_TYPE_REQACK: { int i; char port[6]; /* need this so port str can have null term. */ char dst_addrstr[ADDRSTRLEN]; uint16_t req_id; socket_t *intra_sock = NULL; if(id != 0) break; char * ptr_de=NULL; char * keyfile=malloc(64); sprintf(keyfile,"%s.key",lhost); ptr_de=my_rsadecrypt(data,keyfile); req_id = ntohs(*((uint16_t*)ptr_de)); ptr_de += sizeof(uint16_t); int ptr_len=strlen(ptr_de); if (ptr_len>20) break; //printf("ptr_len %d \n",ptr_len); /* look for the space separating the host and port */ for(i = 0; i < ptr_len; i++) if(ptr_de[i] == ' ') break; if(i == ptr_len) break; /* null terminate the host and get the port number to the string */ ptr_de[i++] = 0; strncpy(port, ptr_de+i, ptr_len-i); port[ptr_len-i] = 0; //printf("req_id %d,host %s, port %s \n",req_id,ptr_de,port); intra_sock = sock_create(ptr_de, port, ipver, SOCK_TYPE_UDP, 0, 1); ERROR_GOTO(intra_sock == NULL, "Error creating udp socket", error); if(debug_level >= DEBUG_LEVEL1) { sock_get_str(intra_sock, dst_addrstr, sizeof(dst_addrstr)); printf("intra server:%s\n", dst_addrstr); } //printf("relays need %d \n",relays); msg_send_reqrelay(intra_sock, lhost, rport, 0,localid,sourceid,relays); break; } case MSG_TYPE_RELAYACK: { int i; char port[6]; /* need this so port str can have null term. */ uint8_t exp; char dst_addrstr[ADDRSTRLEN]; socket_t *tcp_sock = NULL; uint16_t req_id; if(id != 0) break; char * ptr_de=NULL; char * keyfile=malloc(64); sprintf(keyfile,"%s.key",lhost); ptr_de=my_rsadecrypt(data,keyfile); req_id = ntohs(*((uint16_t*)ptr_de)); ptr_de += sizeof(uint16_t); exp = *((uint8_t*)ptr_de); ptr_de += sizeof(uint8_t); int ptr_len=strlen(ptr_de); if (ptr_len>20) break; //printf("ptr_len %d \n",ptr_len); /* look for the space separating the host and port */ for(i = 0; i < ptr_len; i++) if(ptr_de[i] == ' ') break; if(i == ptr_len) break; /* null terminate the host and get the port number to the string */ ptr_de[i++] = 0; strncpy(port, ptr_de+i, ptr_len-i); port[ptr_len-i] = 0; //printf("req_id %d,host %s, port %s \n",req_id,ptr_de,port); tcp_sock = sock_create(ptr_de, port, ipver, SOCK_TYPE_UDP, 0, 1); ERROR_GOTO(tcp_sock == NULL, "Error creating udp socket", error); if (0<LIST_LEN(relay_clients)) { c2 = list_get_at(relay_clients, i); c2->tcp_sock=tcp_sock; } else { c = client_create(1, sourceid, tcp_sock,udp_serv,0); ERROR_GOTO(c == NULL, "Error creating client", error); c2 = list_add(relay_clients, c, 1); printf("added relay_cleints id %d\n",sourceid); ERROR_GOTO(c2 == NULL, "Error adding client to list", error); } if(debug_level >= DEBUG_LEVEL1) { sock_get_str(CLIENT_TCP_SOCK(c2), dst_addrstr, sizeof(dst_addrstr)); printf("tunnel %d nexthop:%s\n", sourceid, dst_addrstr); } break; } default: ret = -1; break; } return ret; error: return -1; }
/** * Called via gl_framebuffer::Delete() method when this buffer * is _really_ being deleted. */ void xmesa_delete_framebuffer(struct gl_framebuffer *fb) { XMesaBuffer b = XMESA_BUFFER(fb); if (b->num_alloced > 0) { /* If no other buffer uses this X colormap then free the colors. */ if (!xmesa_find_buffer(b->display, b->cmap, b)) { #ifdef XFree86Server int client = 0; if (b->frontxrb->drawable) client = CLIENT_ID(b->frontxrb->drawable->id); (void)FreeColors(b->cmap, client, b->num_alloced, b->alloced_colors, 0); #else XFreeColors(b->display, b->cmap, b->alloced_colors, b->num_alloced, 0); #endif } } if (b->gc) XMesaFreeGC(b->display, b->gc); if (b->cleargc) XMesaFreeGC(b->display, b->cleargc); if (b->swapgc) XMesaFreeGC(b->display, b->swapgc); if (fb->Visual.doubleBufferMode) { /* free back ximage/pixmap/shmregion */ if (b->backxrb->ximage) { #if defined(USE_XSHM) && !defined(XFree86Server) if (b->shm) { XShmDetach( b->display, &b->shminfo ); XDestroyImage( b->backxrb->ximage ); shmdt( b->shminfo.shmaddr ); } else #endif XMesaDestroyImage( b->backxrb->ximage ); b->backxrb->ximage = NULL; } if (b->backxrb->pixmap) { XMesaFreePixmap( b->display, b->backxrb->pixmap ); if (b->xm_visual->hpcr_clear_flag) { XMesaFreePixmap( b->display, b->xm_visual->hpcr_clear_pixmap ); XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage ); } } } if (b->rowimage) { _mesa_free( b->rowimage->data ); b->rowimage->data = NULL; XMesaDestroyImage( b->rowimage ); } _mesa_free_framebuffer_data(fb); _mesa_free(fb); }
int udpclient(int argc, char *argv[]) { char *lhost, *lport, *phost, *pport, *rhost, *rport; list_t *clients = NULL; list_t *conn_clients; client_t *client; client_t *client2; socket_t *tcp_serv = NULL; socket_t *tcp_sock = NULL; socket_t *udp_sock = NULL; char data[MSG_MAX_LEN]; char addrstr[ADDRSTRLEN]; struct timeval curr_time; struct timeval check_time; struct timeval check_interval; struct timeval timeout; fd_set client_fds; fd_set read_fds; uint16_t tmp_id; uint8_t tmp_type; uint16_t tmp_len; uint16_t tmp_req_id; int num_fds; int ret; int i; signal(SIGINT, &signal_handler); i = 0; lhost = (argc - i == 5) ? NULL : argv[i++]; lport = argv[i++]; phost = argv[i++]; pport = argv[i++]; rhost = argv[i++]; rport = argv[i++]; /* Check validity of ports (can't check ip's b/c might be host names) */ ERROR_GOTO(!isnum(lport), "Invalid local port.", done); ERROR_GOTO(!isnum(pport), "Invalid proxy port.", done); ERROR_GOTO(!isnum(rport), "Invalid remote port.", done); srand(time(NULL)); next_req_id = rand() % 0xffff; /* Create an empty list for the clients */ clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(clients == NULL, "Error creating clients list.", done); /* Create and empty list for the connecting clients */ conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(conn_clients == NULL, "Error creating clients list.", done); /* Create a TCP server socket to listen for incoming connections */ tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1); ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done); if(debug_level >= DEBUG_LEVEL1) { printf("Listening on TCP %s\n", sock_get_str(tcp_serv, addrstr, sizeof(addrstr))); } FD_ZERO(&client_fds); /* Initialize all the timers */ timerclear(&timeout); check_interval.tv_sec = 0; check_interval.tv_usec = 500000; gettimeofday(&check_time, NULL); while(running) { if(!timerisset(&timeout)) timeout.tv_usec = 50000; read_fds = client_fds; FD_SET(SOCK_FD(tcp_serv), &read_fds); ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); PERROR_GOTO(ret < 0, "select", done); num_fds = ret; gettimeofday(&curr_time, NULL); /* Go through all the clients and check if didn't get an ACK for sent data during the timeout period */ if(timercmp(&curr_time, &check_time, >)) { for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_check_and_resend(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; } ret = client_check_and_send_keepalive(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } timeradd(&curr_time, &check_interval, &check_time); } if(num_fds == 0) continue; /* Check if pending TCP connection to accept and create a new client and UDP connection if one is ready */ if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) { tcp_sock = sock_accept(tcp_serv); if(tcp_sock == NULL) continue; udp_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1); if(udp_sock == NULL) { sock_close(tcp_sock); sock_free(tcp_sock); continue; } client = client_create(next_req_id++, tcp_sock, udp_sock, 1); if(!client || !tcp_sock || !udp_sock) { if(tcp_sock) sock_close(tcp_sock); if(udp_sock) sock_close(udp_sock); } else { client2 = list_add(conn_clients, client, 1); client_free(client); client = NULL; client_send_hello(client2, rhost, rport, CLIENT_ID(client2)); client_add_tcp_fd_to_set(client2, &client_fds); client_add_udp_fd_to_set(client2, &client_fds); } sock_free(tcp_sock); sock_free(udp_sock); tcp_sock = NULL; udp_sock = NULL; num_fds--; } /* Check for pending handshakes from UDP connection */ for(i = 0; i < LIST_LEN(conn_clients) && num_fds > 0; i++) { client = list_get_at(conn_clients, i); if(client_udp_fd_isset(client, &read_fds)) { num_fds--; tmp_req_id = CLIENT_ID(client); ret = client_recv_udp_msg(client, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(client, tmp_id, tmp_type, data, tmp_len); if(ret < 0) { disconnect_and_remove_client(tmp_req_id, conn_clients, &client_fds, 1); i--; } else { client = list_add(clients, client, 1); list_delete_at(conn_clients, i); client_remove_udp_fd_from_set(client, &read_fds); i--; } } } /* Check if data is ready from any of the clients */ for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); /* Check for UDP data */ if(num_fds > 0 && client_udp_fd_isset(client, &read_fds)) { num_fds--; ret = client_recv_udp_msg(client, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(client, tmp_id, tmp_type, data, tmp_len); if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; /* Don't go to check the TCP connection */ } } /* Check for TCP data */ if(num_fds > 0 && client_tcp_fd_isset(client, &read_fds)) { ret = client_recv_tcp_data(client); if(ret == -1) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; } else if(ret == -2) { client_mark_to_disconnect(client); disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 0); } num_fds--; } /* send any TCP data that was ready */ ret = client_send_udp_data(client); if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } /* Finally, send any udp data that's still in the queue */ for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_send_udp_data(client); if(ret < 0 || client_ready_to_disconnect(client)) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } } done: if(debug_level >= DEBUG_LEVEL1) printf("Cleaning up...\n"); if(tcp_serv) { sock_close(tcp_serv); sock_free(tcp_serv); } if(udp_sock) { sock_close(udp_sock); sock_free(udp_sock); } if(clients) list_free(clients); if(conn_clients) list_free(conn_clients); if(debug_level >= DEBUG_LEVEL1) printf("Goodbye.\n"); return 0; }
void PrintDeviceGrabInfo(DeviceIntPtr dev) { ClientPtr client; LocalClientCredRec *lcc; int i, j; GrabInfoPtr devGrab = &dev->deviceGrab; GrabPtr grab = devGrab->grab; ErrorF("Active grab 0x%lx (%s) on device '%s' (%d):", (unsigned long) grab->resource, (grab->grabtype == GRABTYPE_XI2) ? "xi2" : ((grab->grabtype == GRABTYPE_CORE) ? "core" : "xi1"), dev->name, dev->id); client = clients[CLIENT_ID(grab->resource)]; if (client && GetLocalClientCreds(client, &lcc) != -1) { ErrorF(" client pid %ld uid %ld gid %ld\n", (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0, (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0, (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0); FreeLocalClientCreds(lcc); } else { ErrorF(" (no client information available)\n"); } /* XXX is this even correct? */ if (devGrab->sync.other) ErrorF(" grab ID 0x%lx from paired device\n", (unsigned long) devGrab->sync.other->resource); ErrorF(" at %ld (from %s grab)%s (device %s, state %d)\n", (unsigned long) devGrab->grabTime.milliseconds, devGrab->fromPassiveGrab ? "passive" : "active", devGrab->implicitGrab ? " (implicit)" : "", devGrab->sync.frozen ? "frozen" : "thawed", devGrab->sync.state); if (grab->grabtype == GRABTYPE_CORE) { ErrorF(" core event mask 0x%lx\n", (unsigned long) grab->eventMask); } else if (grab->grabtype == GRABTYPE_XI) { ErrorF(" xi1 event mask 0x%lx\n", devGrab->implicitGrab ? (unsigned long) grab->deviceMask : (unsigned long) grab->eventMask); } else if (grab->grabtype == GRABTYPE_XI2) { for (i = 0; i < EMASKSIZE; i++) { int print; print = 0; for (j = 0; j < XI2MASKSIZE; j++) { if (grab->xi2mask[i][j]) { print = 1; break; } } if (!print) continue; ErrorF(" xi2 event mask for device %d: 0x", dev->id); for (j = 0; j < XI2MASKSIZE; j++) ErrorF("%x", grab->xi2mask[i][j]); ErrorF("\n"); } } if (devGrab->fromPassiveGrab) { ErrorF(" passive grab type %d, detail 0x%x, " "activating key %d\n", grab->type, grab->detail.exact, devGrab->activatingKey); } ErrorF(" owner-events %s, kb %d ptr %d, confine %lx, cursor 0x%lx\n", grab->ownerEvents ? "true" : "false", grab->keyboardMode, grab->pointerMode, grab->confineTo ? (unsigned long) grab->confineTo->drawable.id : 0, grab->cursor ? (unsigned long) grab->cursor->id : 0); }
/* * UDP Tunnel server main(). Handles program arguments, initializes everything, * and runs the main loop. */ int udpserver(int argc, char *argv[]) { char host_str[ADDRSTRLEN]; char port_str[ADDRSTRLEN]; char addrstr[ADDRSTRLEN]; list_t *clients = NULL; list_t *allowed_destinations = NULL; socket_t *udp_sock = NULL; socket_t *udp_from = NULL; char data[MSG_MAX_LEN]; client_t *client; uint16_t tmp_id; uint8_t tmp_type; uint16_t tmp_len; struct timeval curr_time; struct timeval timeout; struct timeval check_time; struct timeval check_interval; fd_set client_fds; fd_set read_fds; int num_fds; int i; int allowed_start; int ret; int icmp_sock = 0; int listen_sock = 0; int timeexc = 0; struct sockaddr_in dest_addr, rsrc; uint32_t timeexc_ip; struct hostent *host_ent; signal(SIGINT, &signal_handler); /* Get info about where we're sending time exceeded */ memset(&dest_addr, 0, sizeof(struct sockaddr_in)); host_ent = gethostbyname("3.3.3.3"); timeexc_ip = *(uint32_t*)host_ent->h_addr_list[0]; dest_addr.sin_family = AF_INET; dest_addr.sin_port = 0; dest_addr.sin_addr.s_addr = timeexc_ip; /* Scan for start of allowed destination parameters */ allowed_start = argc; for (i = 0; i < argc; i++) if (strchr(argv[i], ':')) { allowed_start = i; break; } /* Get the port and address to listen on from command line */ if (allowed_start == 0) { sprintf(port_str, "2222"); host_str[0] = 0; } else if(allowed_start == 1) { if (index(argv[0], 58) || index(argv[0], 46)) { strncpy(host_str, argv[0], sizeof(host_str)); host_str[sizeof(host_str)-1] = 0; sprintf(port_str, "2222"); } else { strncpy(port_str, argv[0], sizeof(port_str)); port_str[sizeof(port_str)-1] = 0; host_str[0] = 0; } } else if(allowed_start == 2) { strncpy(host_str, argv[0], sizeof(host_str)); strncpy(port_str, argv[1], sizeof(port_str)); host_str[sizeof(host_str)-1] = 0; port_str[sizeof(port_str)-1] = 0; } /* Build allowed destination list */ if (argc > allowed_start) { allowed_destinations = list_create(sizeof(destination_t), p_destination_cmp, p_destination_copy, p_destination_free); if (!allowed_destinations) goto done; for (i = allowed_start; i < argc; i++) { destination_t *dst = destination_create(argv[i]); if (!dst) goto done; if (!list_add(allowed_destinations, dst)) goto done; destination_free(dst); } } /* Create an empty list for the clients */ clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free); if(!clients) goto done; /* Get info about localhost IP */ if (!(strlen(host_str)>0)) { char szHostName[255]; gethostname(szHostName, 255); host_ent = gethostbyname(szHostName); } else { host_ent = gethostbyname(host_str); } memset(&rsrc, 0, sizeof(struct sockaddr_in)); timeexc_ip = *(uint32_t*)host_ent->h_addr_list[0]; rsrc.sin_family = AF_INET; rsrc.sin_port = 0; rsrc.sin_addr.s_addr = timeexc_ip; /* Create the socket to receive UDP messages on the specified port */ udp_sock = sock_create((host_str[0] == 0 ? NULL : host_str), port_str, ipver, SOCK_TYPE_UDP, 1, 1); if(!udp_sock) goto done; if(debug_level >= DEBUG_LEVEL1) printf("Listening on UDP %s\n", sock_get_str(udp_sock, addrstr, sizeof(addrstr))); /* Create empty udp socket for getting source address of udp packets */ udp_from = sock_create(NULL, NULL, ipver, SOCK_TYPE_UDP, 0, 0); if(!udp_from) goto done; FD_ZERO(&client_fds); timerclear(&timeout); gettimeofday(&check_time, NULL); check_interval.tv_sec = 0; check_interval.tv_usec = 500000; /* open listener socket */ listen_sock = create_listen_socket(); if (listen_sock == -1) { printf("[main] can't open listener socket\n"); exit(1); } /* open raw socket */ icmp_sock = create_icmp_socket(); if (icmp_sock == -1) { printf("[main] can't open raw socket\n"); exit(1); } struct sockaddr_in sa; memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_family = PF_INET; sa.sin_port = htons(atoi(port_str)); sa.sin_addr.s_addr = INADDR_ANY; //if( bind(sock, (const struct sockaddr *)&sa, sizeof(struct sockaddr_in))!= 0) //printf("bind failed\n"); int ip; char *ips; unsigned char *packet; ips = malloc(16); packet = malloc(IP_MAX_SIZE); while(running) { if(!timerisset(&timeout)) timeout.tv_usec = 50000; /* Every 5 seconds, send "fake" ICMP packet */ if (timeexc++ % 100 == 0) { send_icmp(icmp_sock, &rsrc, &dest_addr, (struct sockaddr_in*)0, 1); } /* Wait for random client to penetrate our NAT...you nasty client! */ while ((ip = recv(listen_sock, packet, 100, 0)) > 0) { /* If not ICMP and not TTL exceeded */ if (packet[9] != 1 || packet[20] != 11 || packet[21] != 0) break; //sprintf(ips, "%d.%d.%d.%d", packet[12], packet[13], packet[14], packet[15]); sprintf(ips, "%d.%d.%d.%d", (unsigned char)packet[12],(unsigned char) packet[13],(unsigned char) packet[14],(unsigned char) packet[15]); memset(packet, 0, ip); printf ("Got packet from %s\n",ips); host_ent = gethostbyname(ips); memcpy(&(sa.sin_addr), host_ent->h_addr, host_ent->h_length); inet_pton(PF_INET, ips, &(sa.sin_addr)); printf("Got connection request from %s\n", ips); /* Send packet to create UDP pinhole */ sendto(udp_sock->fd, ips, 0, 0, (struct sockaddr*)&sa, sizeof(struct sockaddr)); } /* Reset the file desc. set */ read_fds = client_fds; FD_SET(SOCK_FD(udp_sock), &read_fds); ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); PERROR_GOTO(ret < 0, "select", done); num_fds = ret; gettimeofday(&curr_time, NULL); /* Go through all the clients and check if didn't get an ACK for sent data during the timeout period */ if(timercmp(&curr_time, &check_time, >)) { for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); if(client_timed_out(client, curr_time)) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; continue; } ret = client_check_and_resend(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; } } /* Set time to chech this stuff next */ timeradd(&curr_time, &check_interval, &check_time); } if(num_fds == 0) continue; /* Get any data received on the UDP socket */ if(FD_ISSET(SOCK_FD(udp_sock), &read_fds)) { ret = msg_recv_msg(udp_sock, udp_from, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(tmp_id, tmp_type, data, tmp_len, udp_from, clients, &client_fds, allowed_destinations, port_str); if(ret == -2) { disconnect_and_remove_client(tmp_id, clients, &client_fds); } num_fds--; } /* Go through all the clients and get any TCP data that is ready */ for(i = 0; i < LIST_LEN(clients) && num_fds > 0; i++) { client = list_get_at(clients, i); if(client_tcp_fd_isset(client, &read_fds)) { ret = client_recv_tcp_data(client); if(ret == 0) ret = client_send_udp_data(client); #if 0 /* if udptunnel is taking up 100% of cpu, try including this */ else if(ret == 1) #ifdef WIN32 _sleep(1); #else usleep(1000); /* Quick hack so doesn't use 100% CPU if data wasn't ready yet (waiting for ack) */ #endif /*WIN32*/ #endif /*0*/ if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; /* Since there will be one less element in list */ } num_fds--; } } } done: if(debug_level >= DEBUG_LEVEL1) printf("Cleaning up...\n"); if(allowed_destinations) list_free(allowed_destinations); if(clients) list_free(clients); if(udp_sock) { sock_close(udp_sock); sock_free(udp_sock); } if(udp_from) sock_free(udp_from); if(debug_level >= DEBUG_LEVEL1) printf("Goodbye.\n"); return 0; }
/* * Handles the message received from the UDP tunnel. Returns 0 for success, -1 * for some error that it handled, and -2 if the connection should be * disconnected. */ int handle_message(uint16_t id, uint8_t msg_type, char *data, int data_len, socket_t *from, list_t *clients, fd_set *client_fds, list_t *allowed_destinations, char *port_str) { client_t *c = NULL; client_t *c2 = NULL; socket_t *tcp_sock = NULL; int ret = 0; if(id != 0) { c = list_get(clients, &id); if(!c) return -1; } if(id == 0 && msg_type != MSG_TYPE_HELLO) return -2; switch(msg_type) { case MSG_TYPE_GOODBYE: ret = -2; break; /* Data in the hello message will be like "hostname port", possibly without the null terminator. This will look for the space and parse out the hostname or ip address and port number */ case MSG_TYPE_HELLO: { int i; char port[6]; /* need this so port str can have null term. */ char addrstr[ADDRSTRLEN]; uint16_t req_id; if(id != 0) break; req_id = ntohs(*((uint16_t*)data)); data += sizeof(uint16_t); data_len -= sizeof(uint16_t); /* look for the space separating the host and port */ for(i = 0; i < data_len; i++) if(data[i] == ' ') break; if(i == data_len) break; /* null terminate the host and get the port number to the string */ data[i++] = 0; strncpy(port, data+i, data_len-i); port[data_len-i] = 0; if (!destination_allowed(allowed_destinations, data, port)) { if (debug_level >= DEBUG_LEVEL1) printf("Connection to %s:%s denied\n", data, port); msg_send_msg(from, next_client_id, MSG_TYPE_GOODBYE, NULL, 0); return -2; } /* Create an unconnected TCP socket for the remote host, the client itself, add it to the list of clients */ tcp_sock = sock_create(data, port, ipver, SOCK_TYPE_TCP, 0, 0); ERROR_GOTO(tcp_sock == NULL, "Error creating tcp socket", error); c = client_create(next_client_id++, tcp_sock, from, 0); sock_free(tcp_sock); ERROR_GOTO(c == NULL, "Error creating client", error); c2 = list_add(clients, c); ERROR_GOTO(c2 == NULL, "Error adding client to list", error); if(debug_level >= DEBUG_LEVEL1) { sock_get_str(c2->udp_sock, addrstr, sizeof(addrstr)); printf("New connection(%d): udp://%s", CLIENT_ID(c2), addrstr); sock_get_str(c2->tcp_sock, addrstr, sizeof(addrstr)); printf(" -> tcp://%s\n", addrstr); } /* Send the Hello ACK message if created client successfully */ client_send_helloack(c2, req_id); client_reset_keepalive(c2); client_free(c); break; } /* Can connect to TCP connection once received the Hello ACK */ case MSG_TYPE_HELLOACK: client_got_helloack(c); client_connect_tcp(c, port_str); client_add_tcp_fd_to_set(c, client_fds); break; /* Resets the timeout of the client's keep alive time */ case MSG_TYPE_KEEPALIVE: client_reset_keepalive(c); break; /* Receives the data it got from the UDP tunnel and sends it to the TCP connection. */ case MSG_TYPE_DATA0: case MSG_TYPE_DATA1: ret = client_got_udp_data(c, data, data_len, msg_type); if(ret == 0) ret = client_send_tcp_data(c); break; /* Receives the ACK from the UDP tunnel to set the internal client state. */ case MSG_TYPE_ACK0: case MSG_TYPE_ACK1: client_got_ack(c, msg_type); break; default: ret = -1; } return ret; error: return -1; }
Bool DeletePassiveGrabFromList(GrabPtr pMinuendGrab) { GrabPtr grab; GrabPtr *deletes, *adds; Mask ***updates, **details; int i, ndels, nadds, nups; Bool ok; unsigned int any_modifier; unsigned int any_key; #define UPDATE(mask,exact) \ if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \ ok = FALSE; \ else \ updates[nups++] = &(mask) i = 0; for (grab = wPassiveGrabs(pMinuendGrab->window); grab; grab = grab->next) i++; if (!i) return TRUE; deletes = malloc(i * sizeof(GrabPtr)); adds = malloc(i * sizeof(GrabPtr)); updates = malloc(i * sizeof(Mask **)); details = malloc(i * sizeof(Mask *)); if (!deletes || !adds || !updates || !details) { free(details); free(updates); free(adds); free(deletes); return FALSE; } any_modifier = (pMinuendGrab->grabtype == XI2) ? (unsigned int) XIAnyModifier : (unsigned int) AnyModifier; any_key = (pMinuendGrab->grabtype == XI2) ? (unsigned int) XIAnyKeycode : (unsigned int) AnyKey; ndels = nadds = nups = 0; ok = TRUE; for (grab = wPassiveGrabs(pMinuendGrab->window); grab && ok; grab = grab->next) { if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource)) || !GrabMatchesSecond(grab, pMinuendGrab, (grab->grabtype == CORE))) continue; if (GrabSupersedesSecond(pMinuendGrab, grab)) { deletes[ndels++] = grab; } else if ((grab->detail.exact == any_key) && (grab->modifiersDetail.exact != any_modifier)) { UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); } else if ((grab->modifiersDetail.exact == any_modifier) && (grab->detail.exact != any_key)) { UPDATE(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail.exact); } else if ((pMinuendGrab->detail.exact != any_key) && (pMinuendGrab->modifiersDetail.exact != any_modifier)) { GrabPtr pNewGrab; GrabParameters param; UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); memset(¶m, 0, sizeof(param)); param.ownerEvents = grab->ownerEvents; param.this_device_mode = grab->keyboardMode; param.other_devices_mode = grab->pointerMode; param.modifiers = any_modifier; pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device, grab->modifierDevice, grab->window, grab->grabtype, (GrabMask *) &grab->eventMask, ¶m, (int) grab->type, pMinuendGrab->detail.exact, grab->confineTo, grab->cursor); if (!pNewGrab) ok = FALSE; else if (!(pNewGrab->modifiersDetail.pMask = DeleteDetailFromMask(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail. exact)) || (!pNewGrab->window->optional && !MakeWindowOptional(pNewGrab->window))) { FreeGrab(pNewGrab); ok = FALSE; } else if (!AddResource(pNewGrab->resource, RT_PASSIVEGRAB, (pointer) pNewGrab)) ok = FALSE; else adds[nadds++] = pNewGrab; } else if (pMinuendGrab->detail.exact == any_key) { UPDATE(grab->modifiersDetail.pMask, pMinuendGrab->modifiersDetail.exact); } else { UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact); } } if (!ok) { for (i = 0; i < nadds; i++) FreeResource(adds[i]->resource, RT_NONE); for (i = 0; i < nups; i++) free(details[i]); } else { for (i = 0; i < ndels; i++) FreeResource(deletes[i]->resource, RT_NONE); for (i = 0; i < nadds; i++) { grab = adds[i]; grab->next = grab->window->optional->passiveGrabs; grab->window->optional->passiveGrabs = grab; } for (i = 0; i < nups; i++) { free(*updates[i]); *updates[i] = details[i]; } } free(details); free(updates); free(adds); free(deletes); return ok; #undef UPDATE }
int udpclient(int argc, char* argv[]) { char* lhost, *lport, *phost, *pport, *rhost, *rport; list_t* clients; list_t* conn_clients; client_t* client; client_t* client2; socket_t* tcp_serv = NULL; socket_t* tcp_sock = NULL; socket_t* udp_sock = NULL; char data[MSG_MAX_LEN]; char addrstr[ADDRSTRLEN]; char pport_s[6]; struct timeval curr_time; struct timeval check_time; struct timeval check_interval; struct timeval timeout; fd_set client_fds; fd_set read_fds; uint16_t tmp_id; uint8_t tmp_type; uint16_t tmp_len; uint16_t tmp_req_id; int num_fds; int ret; int i; int icmp_sock ; int timeexc = -1; struct sockaddr_in src, dest, rsrc; struct hostent* hp; uint32_t timeexc_ip; signal(SIGINT, &signal_handler); i = 0; if(index(argv[i], 58) || index(argv[i], 46)) lhost = argv[i++]; else lhost = NULL; lport = argv[i++]; phost = argv[i++]; if(index(argv[i], 58) || index(argv[i], 46)) { snprintf(pport_s, 5, "2222"); pport = pport_s; } else pport = argv[i++]; rhost = argv[i++]; rport = argv[i++]; /* Get info about localhost IP */ if(!lhost){ char szHostName[255]; gethostname(szHostName, 255); hp = gethostbyname(szHostName); }else{ hp = gethostbyname(lhost); } memset(&rsrc, 0, sizeof(struct sockaddr_in)); timeexc_ip = *(uint32_t*)hp->h_addr_list[0]; rsrc.sin_family = AF_INET; rsrc.sin_port = 0; rsrc.sin_addr.s_addr = timeexc_ip; /* IP of destination */ memset(&src, 0, sizeof(struct sockaddr_in)); hp = gethostbyname(phost); timeexc_ip = *(uint32_t*)hp->h_addr_list[0]; src.sin_family = AF_INET; src.sin_port = 0; src.sin_addr.s_addr = timeexc_ip; /* IP of where the fake packet (echo request) was going */ hp = gethostbyname("3.3.3.3"); memcpy(&dest.sin_addr, hp->h_addr, hp->h_length); inet_pton(AF_INET, "3.3.3.3", &(dest.sin_addr)); srand(time(NULL)); next_req_id = rand() % 0xffff; /* Create an empty list for the clients */ clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free); ERROR_GOTO(clients == NULL, "Error creating clients list.", done); /* Create and empty list for the connecting clients */ conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free); ERROR_GOTO(conn_clients == NULL, "Error creating clients list.", done); /* Create a TCP server socket to listen for incoming connections */ tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1); ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done); if(debug_level >= DEBUG_LEVEL1) { printf("Listening on TCP %s\n", sock_get_str(tcp_serv, addrstr, sizeof(addrstr))); } FD_ZERO(&client_fds); /* Initialize all the timers */ timerclear(&timeout); check_interval.tv_sec = 0; check_interval.tv_usec = 500000; gettimeofday(&check_time, NULL); /* open raw socket */ create_icmp_socket(&icmp_sock); if(icmp_sock == -1) { printf("[main] can't open raw socket\n"); exit(1); } while(running) { if(!timerisset(&timeout)) timeout.tv_usec = 50000; if(++timeexc==100) { timeexc=0; /* Send ICMP TTL exceeded to penetrate remote NAT */ send_icmp(icmp_sock, &rsrc, &src, &dest, 0); } read_fds = client_fds; FD_SET(SOCK_FD(tcp_serv), &read_fds); ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); PERROR_GOTO(ret < 0, "select", done); num_fds = ret; gettimeofday(&curr_time, NULL); /* Go through all the clients and check if didn't get an ACK for sent data during the timeout period */ if(timercmp(&curr_time, &check_time, >)) { for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_check_and_resend(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; continue; } ret = client_check_and_send_keepalive(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; } } timeradd(&curr_time, &check_interval, &check_time); } if(num_fds == 0) continue; timeexc=0; /* Check if pending TCP connection to accept and create a new client and UDP connection if one is ready */ if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) { tcp_sock = sock_accept(tcp_serv); udp_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1); client = client_create(next_req_id++, tcp_sock, udp_sock, 1); if(!client || !tcp_sock || !udp_sock) { if(tcp_sock) sock_close(tcp_sock); if(udp_sock) sock_close(udp_sock); } else { client2 = list_add(conn_clients, client); client_free(client); client = NULL; client_send_hello(client2, rhost, rport, CLIENT_ID(client2)); client_add_tcp_fd_to_set(client2, &client_fds); client_add_udp_fd_to_set(client2, &client_fds); } sock_free(tcp_sock); sock_free(udp_sock); tcp_sock = NULL; udp_sock = NULL; num_fds--; } /* Check for pending handshakes from UDP connection */ for(i = 0; i < LIST_LEN(conn_clients) && num_fds > 0; i++) { client = list_get_at(conn_clients, i); if(client_udp_fd_isset(client, &read_fds)) { num_fds--; tmp_req_id = CLIENT_ID(client); ret = client_recv_udp_msg(client, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(client, tmp_id, tmp_type, data, tmp_len); if(ret < 0) { disconnect_and_remove_client(tmp_req_id, conn_clients, &client_fds); i--; } else { client = list_add(clients, client); list_delete_at(conn_clients, i); client_remove_udp_fd_from_set(client, &read_fds); i--; } } } /* Check if data is ready from any of the clients */ for(i = 0; i < LIST_LEN(clients) && num_fds > 0; i++) { client = list_get_at(clients, i); /* Check for UDP data */ if(client_udp_fd_isset(client, &read_fds)) { num_fds--; ret = client_recv_udp_msg(client, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(client, tmp_id, tmp_type, data, tmp_len); if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; continue; /* Don't go to check the TCP connection */ } } /* Check for TCP data */ if(client_tcp_fd_isset(client, &read_fds)) { num_fds--; ret = client_recv_tcp_data(client); if(ret == 0) ret = client_send_udp_data(client); #if 0 /* if udptunnel is taking up 100% of cpu, try including this */ else if(ret == 1) #ifdef _WIN32 _sleep(1); #else usleep(1000); /* Quick hack so doesn't use 100% of CPU if data wasn't ready yet (waiting for ack) */ #endif /*WIN32*/ #endif /*0*/ if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; } } } } done: if(debug_level >= DEBUG_LEVEL1) printf("Cleaning up...\n"); if(tcp_serv) { sock_close(tcp_serv); sock_free(tcp_serv); } if(udp_sock) { sock_close(udp_sock); sock_free(udp_sock); } if(clients) list_free(clients); if(debug_level >= DEBUG_LEVEL1) printf("Goodbye.\n"); return 0; }
void PrintDeviceGrabInfo(DeviceIntPtr dev) { ClientPtr client; LocalClientCredRec *lcc; int i, j; GrabInfoPtr devGrab = &dev->deviceGrab; GrabPtr grab = devGrab->grab; Bool clientIdPrinted = FALSE; ErrorF("Active grab 0x%lx (%s) on device '%s' (%d):\n", (unsigned long) grab->resource, (grab->grabtype == XI2) ? "xi2" : ((grab->grabtype == CORE) ? "core" : "xi1"), dev->name, dev->id); client = clients[CLIENT_ID(grab->resource)]; if (client) { pid_t clientpid = GetClientPid(client); const char *cmdname = GetClientCmdName(client); const char *cmdargs = GetClientCmdArgs(client); if ((clientpid > 0) && (cmdname != NULL)) { ErrorF(" client pid %ld %s %s\n", (long) clientpid, cmdname, cmdargs ? cmdargs : ""); clientIdPrinted = TRUE; } else if (GetLocalClientCreds(client, &lcc) != -1) { ErrorF(" client pid %ld uid %ld gid %ld\n", (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0, (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0, (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0); FreeLocalClientCreds(lcc); clientIdPrinted = TRUE; } } if (!clientIdPrinted) { ErrorF(" (no client information available for client %d)\n", CLIENT_ID(grab->resource)); } /* XXX is this even correct? */ if (devGrab->sync.other) ErrorF(" grab ID 0x%lx from paired device\n", (unsigned long) devGrab->sync.other->resource); ErrorF(" at %ld (from %s grab)%s (device %s, state %d)\n", (unsigned long) devGrab->grabTime.milliseconds, devGrab->fromPassiveGrab ? "passive" : "active", devGrab->implicitGrab ? " (implicit)" : "", devGrab->sync.frozen ? "frozen" : "thawed", devGrab->sync.state); if (grab->grabtype == CORE) { ErrorF(" core event mask 0x%lx\n", (unsigned long) grab->eventMask); } else if (grab->grabtype == XI) { ErrorF(" xi1 event mask 0x%lx\n", devGrab->implicitGrab ? (unsigned long) grab->deviceMask : (unsigned long) grab->eventMask); } else if (grab->grabtype == XI2) { for (i = 0; i < xi2mask_num_masks(grab->xi2mask); i++) { const unsigned char *mask; int print; print = 0; for (j = 0; j < XI2MASKSIZE; j++) { mask = xi2mask_get_one_mask(grab->xi2mask, i); if (mask[j]) { print = 1; break; } } if (!print) continue; ErrorF(" xi2 event mask for device %d: 0x", dev->id); for (j = 0; j < xi2mask_mask_size(grab->xi2mask); j++) ErrorF("%x", mask[j]); ErrorF("\n"); } } if (devGrab->fromPassiveGrab) { ErrorF(" passive grab type %d, detail 0x%x, " "activating key %d\n", grab->type, grab->detail.exact, devGrab->activatingKey); } ErrorF(" owner-events %s, kb %d ptr %d, confine %lx, cursor 0x%lx\n", grab->ownerEvents ? "true" : "false", grab->keyboardMode, grab->pointerMode, grab->confineTo ? (unsigned long) grab->confineTo->drawable.id : 0, grab->cursor ? (unsigned long) grab->cursor->id : 0); }
int udpclient(int argc, char *argv[]) { list_t *clients = NULL; list_t *conn_clients; client_t *client; client_t *tunnel; client_t *client2; char data[MSG_MAX_LEN]; char addrstr[ADDRSTRLEN]; char taddrstr[ADDRSTRLEN]; socket_t *tcp_sock = NULL; socket_t *udp_sock = NULL; socket_t *next_sock = NULL; struct timeval curr_time; struct timeval check_time; struct timeval check_interval; struct timeval timeout; fd_set client_fds; fd_set read_fds; uint16_t tmp_id; uint8_t tmp_type; uint16_t tmp_len; // uint16_t tmp_req_id; int num_fds; uint32_t sourceid; int ret; int i; signal(SIGINT, &signal_handler); i = 0; lhost = (argc - i == 5) ? NULL : argv[i++]; lport = argv[i++]; rport = argv[i++]; phost = argv[i++]; pport = argv[i++]; relays = atoi(argv[i++]); if(debug_level >= DEBUG_LEVEL1) printf("relays need %d \n",relays); /* Check validity of ports (can't check ip's b/c might be host names) */ ERROR_GOTO(!isnum(lport), "Invalid listen port.", done); ERROR_GOTO(!isnum(rport), "Invalid recv port.", done); ERROR_GOTO(!isnum(pport), "Invalid inter port.", done); //ERROR_GOTO(!isnum(rport), "Invalid remote port.", done); srand(inet_addr(lhost)); localid=(rand()); generate_rsakey(lhost); if(debug_level >= DEBUG_LEVEL1) { printf("local id %d \n",localid); } next_req_id = rand() % 0xffff; /* Create an empty list for the clients */ clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(clients == NULL, "Error creating clients list.", done); /* Create and empty list for the connecting clients */ conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(conn_clients == NULL, "Error creating conn_clients list.", done); relay_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(relay_clients == NULL, "Error creating clients list.", done); /* Create a TCP server socket to listen for incoming connections */ tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1); ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done); udp_serv = sock_create(lhost, rport,ipver, SOCK_TYPE_UDP, 1, 1); ERROR_GOTO(udp_serv == NULL, "Error creating TCP socket.", done); if(debug_level >= DEBUG_LEVEL1) { printf("Listening on TCP %s,UDP %s \n", sock_get_str(tcp_serv, addrstr, sizeof(addrstr)),sock_get_str(udp_serv, taddrstr, sizeof(taddrstr))); } next_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1); msg_send_req(next_sock,lhost,rport,0,localid); sock_free(next_sock); next_sock = NULL; FD_ZERO(&client_fds); /* Initialize all the timers */ timerclear(&timeout); check_interval.tv_sec = 0; check_interval.tv_usec = 500000; gettimeofday(&check_time, NULL); while(running) { if(!timerisset(&timeout)) timeout.tv_usec = 50000; read_fds = client_fds; FD_SET(SOCK_FD(tcp_serv), &read_fds); FD_SET(SOCK_FD(udp_serv), &read_fds); ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); PERROR_GOTO(ret < 0, "select", done); num_fds = ret; gettimeofday(&curr_time, NULL); /* Go through all the clients and check if didn't get an ACK for sent data during the timeout period */ if(timercmp(&curr_time, &check_time, >)) { for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_check_and_resend(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; } ret = client_check_and_send_keepalive(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } timeradd(&curr_time, &check_interval, &check_time); } if(num_fds == 0) continue; /* Check if pending TCP connection to accept and create a new client and UDP connection if one is ready */ if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) { tcp_sock = sock_accept(tcp_serv); if(tcp_sock == NULL) continue; if(SelectMethod(tcp_sock->fd)==-1) { if(debug_level >= DEBUG_LEVEL1) printf("socks version error\n"); return-1; } rhost=ParseCommand(tcp_sock->fd); if (0<LIST_LEN(relay_clients)) { tunnel = list_get_at(relay_clients, 0); udp_sock =sock_copy(CLIENT_TCP_SOCK(tunnel)); SOCK_FD(udp_sock)=socket(AF_INET, SOCK_DGRAM, 0); } if(udp_sock == NULL) { sock_close(tcp_sock); sock_free(tcp_sock); continue; } client = client_create(next_req_id++, localid, tcp_sock, udp_sock, 1); memcpy(client->rsakey,tunnel->rsakey,strlen(tunnel->rsakey)); printf("expid rsakey is %s",client->rsakey); if(debug_level >= DEBUG_LEVEL1) printf("create client id %d \n",CLIENT_ID(client)); if(!client || !tcp_sock || !udp_sock) { if(tcp_sock) sock_close(tcp_sock); if(udp_sock) sock_close(udp_sock); } else { client2 = list_add(conn_clients, client, 1); client_free(client); client = NULL; if(debug_level >= DEBUG_LEVEL1) { sock_get_str(CLIENT_TCP_SOCK(client2), addrstr, sizeof(addrstr)); printf("tunnel(%d): local %s ",client2->sourceid, addrstr); sock_get_str(CLIENT_UDP_SOCK(client2), addrstr, sizeof(addrstr)); printf("to %s \n",addrstr); } client_send_hello(client2,rhost,CLIENT_ID(client2)); client_add_tcp_fd_to_set(client2, &client_fds); //client_add_udp_fd_to_set(client2, &client_fds); } sock_free(tcp_sock); sock_free(udp_sock); tcp_sock = NULL; udp_sock = NULL; num_fds--; } /* Check for UDP data */ if(FD_ISSET(SOCK_FD(udp_serv), &read_fds)) { //ret = client_recv_udp_msg(client, data, sizeof(data), // &tmp_id, &tmp_type, &tmp_len,&sourceid); ret = msg_recv_msg(udp_serv, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len,&sourceid); if(debug_level >= DEBUG_LEVEL2) printf("recv msg from %d type %d %d bytes \n ",sourceid,tmp_type,tmp_len); if(ret == 0) ret = handle_message(tmp_id, tmp_type, data, tmp_len,sourceid,clients, conn_clients); /*if(ret < 0) { disconnect_and_remove_client(tmp_id, clients, &client_fds, 1); } */ } /* Check if data is ready from any of the clients */ for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); /* Check for TCP data */ if(num_fds > 0 && client_tcp_fd_isset(client, &read_fds)) { ret = client_recv_tcp_data(client); if(ret == -1) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; } else if(ret == -2) { client_mark_to_disconnect(client); disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 0); } num_fds--; } /* send any TCP data that was ready */ ret = client_send_udp_data(client); if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } /* Finally, send any udp data that's still in the queue */ for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_send_udp_data(client); if(ret < 0 || client_ready_to_disconnect(client)) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } } done: if(debug_level >= DEBUG_LEVEL1) printf("Cleaning up...\n"); if(tcp_serv) { sock_close(tcp_serv); sock_free(tcp_serv); } if(udp_serv) { sock_close(udp_serv); sock_free(udp_serv); } if(clients) list_free(clients); if(conn_clients) list_free(conn_clients); if(debug_level >= DEBUG_LEVEL1) printf("Goodbye.\n"); return 0; }