Пример #1
0
static rfbBool handleBackChannelMessage(rfbClient* client,
	rfbServerToClientMsg* message)
{
	backChannelMsg msg;
	char* text;

	if(message->type != rfbBackChannel)
		return FALSE;

	rfbClientSetClientData(client, sendMessage, sendMessage);

	if(!ReadFromRFBServer(client, ((char*)&msg)+1, sizeof(msg)-1))
		return TRUE;
	msg.size = rfbClientSwap32IfLE(msg.size);
	text = malloc(msg.size);
	if(!ReadFromRFBServer(client, text, msg.size)) {
		free(text);
		return TRUE;
	}

	rfbClientLog("got back channel message: %s\n", text);
	free(text);

	return TRUE;
}
Пример #2
0
static bool
HandleRREBPP (uint32_t rx, uint32_t ry, uint32_t rw, uint32_t rh)
{
  rfbRREHeader hdr;
  CARDBPP pix;
  rfbRectangle subrect;

  if (!ReadFromRFBServer((uint8_t *)&hdr, sz_rfbRREHeader))
    return false;

  hdr.nSubrects = Swap32IfLE(hdr.nSubrects);

  if (!ReadFromRFBServer((uint8_t *)&pix, sizeof(pix)))
    return false;

  FillBufferRectangle(rx, ry, rw, rh, pix);

  for (uint32_t i = 0; i < hdr.nSubrects; i++) {
    if (!ReadFromRFBServer((uint8_t *)&pix, sizeof(pix)))
      return false;

    if (!ReadFromRFBServer((uint8_t *)&subrect, sz_rfbRectangle))
      return false;

    subrect.x = Swap16IfLE(subrect.x);
    subrect.y = Swap16IfLE(subrect.y);
    subrect.w = Swap16IfLE(subrect.w);
    subrect.h = Swap16IfLE(subrect.h);

    FillBufferRectangle(rx + subrect.x, ry + subrect.y,
                   subrect.w, subrect.h, pix);
  }

  return true;
}
Пример #3
0
static int
SelectSecurityType(void)
{
  CARD8 nSecTypes;
  char *secTypeNames[] = {"None", "VncAuth"};
  CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth};
  int nKnownSecTypes = sizeof(knownSecTypes);
  CARD8 *secTypes;
  CARD8 secType = rfbSecTypeInvalid;
  int i, j;

  /* Read the list of secutiry types. */
  if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes)))
    return rfbSecTypeInvalid;

  if (nSecTypes == 0) {
    ReadConnFailedReason();
    return rfbSecTypeInvalid;
  }

  secTypes = malloc(nSecTypes);
  if (!ReadFromRFBServer((char *)secTypes, nSecTypes))
    return rfbSecTypeInvalid;

  /* Find out if the server supports TightVNC protocol extensions */
  for (j = 0; j < (int)nSecTypes; j++) {
    if (secTypes[j] == rfbSecTypeTight) {
      free(secTypes);
      secType = rfbSecTypeTight;
      if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType)))
        return rfbSecTypeInvalid;
      fprintf(stderr, "Enabling TightVNC protocol extensions\n");
      return rfbSecTypeTight;
    }
  }

  /* Find first supported security type */
  for (j = 0; j < (int)nSecTypes; j++) {
    for (i = 0; i < nKnownSecTypes; i++) {
      if (secTypes[j] == knownSecTypes[i]) {
        secType = secTypes[j];
        if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
          free(secTypes);
          return rfbSecTypeInvalid;
        }
        break;
      }
    }
    if (secType != rfbSecTypeInvalid) break;
  }

  free(secTypes);

  if (secType == rfbSecTypeInvalid)
    fprintf(stderr, "Server did not offer supported security type\n");

  return (int)secType;
}
Пример #4
0
static rfbBool
HandleH264 (rfbClient* client, int rx, int ry, int rw, int rh)
{
    rfbH264Header hdr;
    char *framedata;

    DebugLog(("Framebuffer update with H264 (x: %d, y: %d, w: %d, h: %d)\n", rx, ry, rw, rh));

    /* First, read the frame size and allocate buffer to store the data */
    if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbH264Header))
        return FALSE;

    hdr.slice_type = rfbClientSwap32IfLE(hdr.slice_type);
    hdr.nBytes = rfbClientSwap32IfLE(hdr.nBytes);
    hdr.width = rfbClientSwap32IfLE(hdr.width);
    hdr.height = rfbClientSwap32IfLE(hdr.height);

    framedata = (char*) malloc(hdr.nBytes);

    /* Obtain frame data from the server */
    DebugLog(("Reading %d bytes of frame data (type: %d)\n", hdr.nBytes, hdr.slice_type));
    if (!ReadFromRFBServer(client, framedata, hdr.nBytes))
        return FALSE;

    /* First make sure we have a large enough raw buffer to hold the
     * decompressed data.  In practice, with a fixed BPP, fixed frame
     * buffer size and the first update containing the entire frame
     * buffer, this buffer allocation should only happen once, on the
     * first update.
     */
    if ( client->raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) {
        if ( client->raw_buffer != NULL ) {
            free( client->raw_buffer );
        }

        client->raw_buffer_size = (( rw * rh ) * ( BPP / 8 ));
        client->raw_buffer = (char*) malloc( client->raw_buffer_size );
        rfbClientLog("Allocated raw buffer of %d bytes (%dx%dx%d BPP)\n", client->raw_buffer_size, rw, rh, BPP);
    }

    /* Decode frame if frame data was sent. Server only sends frame data for the first
     * framebuffer update message for a particular frame buffer contents.
     * If more than 1 rectangle is updated, the messages after the first one (with
     * the H.264 frame) have nBytes == 0.
     */
    if (hdr.nBytes > 0) {
        DebugLog(("  decoding %d bytes of H.264 data\n", hdr.nBytes));
        h264_decode_frame(hdr.width, hdr.height, framedata, hdr.nBytes, hdr.slice_type);
    }

    DebugLog(("  updating rectangle (%d, %d)-(%d, %d)\n", rx, ry, rw, rh));
    put_updated_rectangle(client, rx, ry, rw, rh, hdr.width, hdr.height, hdr.nBytes != 0);

    free(framedata);

    return TRUE;
}
Пример #5
0
static Bool
HandleRREBPP (int rx, int ry, int rw, int rh)
{
  rfbRREHeader hdr;
  XGCValues gcv;
  int i;
  CARDBPP pix;
  rfbRectangle subrect;

  if (!ReadFromRFBServer((char *)&hdr, sz_rfbRREHeader))
    return False;

  hdr.nSubrects = Swap32IfLE(hdr.nSubrects);

  if (!ReadFromRFBServer((char *)&pix, sizeof(pix)))
    return False;

#if (BPP == 8)
  gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
#else
  gcv.foreground = pix;
#endif

  XChangeGC(dpy, gc, GCForeground, &gcv);
  XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);
#if VNC_CAPTURE
  myxfillrec(dpy, gc, rx, ry, rw, rh);
#endif

  for (i = 0; i < hdr.nSubrects; i++) {
    if (!ReadFromRFBServer((char *)&pix, sizeof(pix)))
      return False;

    if (!ReadFromRFBServer((char *)&subrect, sz_rfbRectangle))
      return False;

    subrect.x = Swap16IfLE(subrect.x);
    subrect.y = Swap16IfLE(subrect.y);
    subrect.w = Swap16IfLE(subrect.w);
    subrect.h = Swap16IfLE(subrect.h);

#if (BPP == 8)
    gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
#else
    gcv.foreground = pix;
#endif

    XChangeGC(dpy, gc, GCForeground, &gcv);
    XFillRectangle(dpy, desktopWin, gc, rx + subrect.x, ry + subrect.y,
		   subrect.w, subrect.h);
#if VNC_CAPTURE
    myxfillrec(dpy, gc, rx+ subrect.x, ry+ subrect.y, subrect.w, subrect.h);
#endif
  }

  return True;
}
Пример #6
0
static Bool
HandleCoRREBPP (int rx, int ry, int rw, int rh)
{
    rfbRREHeader hdr;
    XGCValues gcv;
    int i;
    CARDBPP pix;
    CARD8 *ptr;
    int x, y, w, h;

    if (!ReadFromRFBServer((char *)&hdr, sz_rfbRREHeader))
	return False;

    hdr.nSubrects = Swap32IfLE(hdr.nSubrects);

    if (!ReadFromRFBServer((char *)&pix, sizeof(pix)))
	return False;

#if (BPP == 8)
    gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
#else
    gcv.foreground = pix;
#endif

    XChangeGC(dpy, gc, GCForeground, &gcv);
    XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh);

    if (!ReadFromRFBServer(buffer, hdr.nSubrects * (4 + (BPP / 8))))
	return False;

    ptr = (CARD8 *)buffer;

    for (i = 0; i < hdr.nSubrects; i++) {
	pix = *(CARDBPP *)ptr;
	ptr += BPP/8;
	x = *ptr++;
	y = *ptr++;
	w = *ptr++;
	h = *ptr++;

#if (BPP == 8)
	gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix);
#else
	gcv.foreground = pix;
#endif

	XChangeGC(dpy, gc, GCForeground, &gcv);
	XFillRectangle(dpy, desktopWin, gc, rx + x, ry + y, w, h);
    }

    return True;
}
Пример #7
0
static Bool
ReadAuthenticationResult(void)
{
  CARD32 authResult;

  if (!ReadFromRFBServer((char *)&authResult, 4))
    return False;

  authResult = Swap32IfLE(authResult);

  switch (authResult) {
  case rfbAuthOK:
    if (!appData.ffInfo) {
      fprintf(stderr, "Authentication successful\n");
    }
    break;
  case rfbAuthFailed:
    if (protocolMinorVersion >= 8) {
      ReadConnFailedReason();
    } else {
      fprintf(stderr, "Authentication failure\n");
    }
    return False;
  case rfbAuthTooMany:
    fprintf(stderr, "Authentication failure, too many tries\n");
    return False;
  default:
    fprintf(stderr, "Unknown result of authentication (%d)\n",
	    (int)authResult);
    return False;
  }

  return True;
}
Пример #8
0
static Bool
SetupTunneling(void)
{
  rfbTunnelingCapsMsg caps;
  CARD32 tunnelType;

  /* In the protocol version 3.7t, the server informs us about
     supported tunneling methods. Here we read this information. */

  if (!ReadFromRFBServer((char *)&caps, sz_rfbTunnelingCapsMsg))
    return False;

  caps.nTunnelTypes = Swap32IfLE(caps.nTunnelTypes);

  if (caps.nTunnelTypes) {
    if (!ReadCapabilityList(tunnelCaps, caps.nTunnelTypes))
      return False;

    /* We cannot do tunneling anyway yet. */
    tunnelType = Swap32IfLE(rfbNoTunneling);
    if (!WriteExact(rfbsock, (char *)&tunnelType, sizeof(tunnelType)))
      return False;
  }

  return True;
}
Пример #9
0
static Bool
PerformAuthenticationTight(void)
{
  rfbAuthenticationCapsMsg caps;
  CARD32 authScheme;
  int i;

  /* In the protocol version 3.7t, the server informs us about supported
     authentication schemes. Here we read this information. */

  if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg))
    return False;

  caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);

  if (!caps.nAuthTypes) {
    fprintf(stderr, "No authentication needed\n");
    return True;
  }

  if (!ReadCapabilityList(authCaps, caps.nAuthTypes))
    return False;

  /* Prefer Unix login authentication if a user name was given. */
  if (appData.userLogin && CapsIsEnabled(authCaps, rfbAuthUnixLogin)) {
    authScheme = Swap32IfLE(rfbAuthUnixLogin);
    if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
      return False;
    return AuthenticateUnixLogin();
  }

  /* Otherwise, try server's preferred authentication scheme. */
  for (i = 0; i < CapsNumEnabled(authCaps); i++) {
    authScheme = CapsGetByOrder(authCaps, i);
    if (authScheme != rfbAuthUnixLogin && authScheme != rfbAuthVNC)
      continue;                 /* unknown scheme - cannot use it */
    authScheme = Swap32IfLE(authScheme);
    if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
      return False;
    authScheme = Swap32IfLE(authScheme); /* convert it back */
    if (authScheme == rfbAuthUnixLogin) {
      return AuthenticateUnixLogin();
    } else if (authScheme == rfbAuthVNC) {
      return AuthenticateVNC();
    } else {
      /* Should never happen. */
      fprintf(stderr, "Assertion failed: unknown authentication scheme\n");
      return False;
    }
  }

  fprintf(stderr, "No suitable authentication schemes offered by server\n");
  return False;
}
Пример #10
0
static void
ReadConnFailedReason(void)
{
  CARD32 reasonLen;
  char *reason = NULL;

  if (ReadFromRFBServer((char *)&reasonLen, sizeof(reasonLen))) {
    reasonLen = Swap32IfLE(reasonLen);
    if ((reason = malloc(reasonLen)) != NULL &&
        ReadFromRFBServer(reason, reasonLen)) {
      fprintf(stderr,"VNC connection failed: %.*s\n", (int)reasonLen, reason);
      free(reason);
      return;
    }
  }

  fprintf(stderr, "VNC connection failed\n");

  if (reason != NULL)
    free(reason);
}
Пример #11
0
static Bool
ReadCapabilityList(CapsContainer *caps, int count)
{
  rfbCapabilityInfo msginfo;
  int i;

  for (i = 0; i < count; i++) {
    if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo))
      return False;
    msginfo.code = Swap32IfLE(msginfo.code);
    CapsEnable(caps, &msginfo);
  }

  return True;
}
Пример #12
0
Bool
VNCViewer::HandleRREBPP (sgVNCViewer *ct, int rx, int ry, int rw, int rh)
{
    rfbRREHeader hdr;
    int i;
    CARDBPP pix;
    rfbRectangle subrect;

    if (!ReadFromRFBServer((char *)&hdr, sz_rfbRREHeader))
        return False;

    hdr.nSubrects = Swap32IfLE(hdr.nSubrects);

    if (!ReadFromRFBServer((char *)&pix, sizeof(pix)))
        return False;
 
    ct->FillToScreen(pix, rx, ry, rw, rh);

    for (i = 0; i < hdr.nSubrects; i++) {
        if (!ReadFromRFBServer((char *)&pix, sizeof(pix)))
            return False;

        if (!ReadFromRFBServer((char *)&subrect, sz_rfbRectangle))
            return False;

        subrect.x = Swap16IfLE(subrect.x);
        subrect.y = Swap16IfLE(subrect.y);
        subrect.w = Swap16IfLE(subrect.w);
        subrect.h = Swap16IfLE(subrect.h);

        ct->FillToScreen(pix, rx + subrect.x, ry + subrect.y,
                         subrect.w, subrect.h);
    }

    return True;
}
Пример #13
0
static Bool
ReadInteractionCaps(void)
{
  rfbInteractionCapsMsg intr_caps;

  /* Read the counts of list items following */
  if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg))
    return False;
  intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes);
  intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes);
  intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes);

  /* Read the lists of server- and client-initiated messages */
  return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) &&
	  ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) &&
	  ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes));
}
Пример #14
0
static Bool
PerformAuthenticationTight(void)
{
  rfbAuthenticationCapsMsg caps;
  CARD32 authScheme;
  int i;

  /* In protocols 3.7t/3.8t, the server informs us about supported
     authentication schemes. Here we read this information. */

  if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg))
    return False;

  caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);

  /* Special case - empty capability list stands for no authentication. */
  if (!caps.nAuthTypes)
    return AuthenticateNone();

  if (!ReadCapabilityList(authCaps, caps.nAuthTypes))
    return False;

  /* Try server's preferred authentication scheme. */
  for (i = 0; i < CapsNumEnabled(authCaps); i++) {
    authScheme = CapsGetByOrder(authCaps, i);
    if (authScheme != rfbAuthVNC && authScheme != rfbAuthNone)
      continue;                 /* unknown scheme - cannot use it */
    authScheme = Swap32IfLE(authScheme);
    if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
      return False;
    authScheme = Swap32IfLE(authScheme); /* convert it back */

    switch (authScheme) {
    case rfbAuthNone:
      return AuthenticateNone();
    case rfbAuthVNC:
      return AuthenticateVNC();
    default:                      /* should never happen */
      fprintf(stderr, "Internal error: Invalid authentication type\n");
      return False;
    }
  }

  fprintf(stderr, "No suitable authentication schemes offered by server\n");
  return False;
}
Пример #15
0
static bool handleRaw( rfbClient *c, int rx, int ry, int rw, int rh )
{
	int y=ry, h=rh;
	int bytesPerLine = rw * c->format.bitsPerPixel / 8;
	int linesToRead = RFB_BUFFER_SIZE / bytesPerLine;

	while( h > 0 )
	{
		if( linesToRead > h )
			linesToRead = h;

		if( !ReadFromRFBServer( c, c->buffer,bytesPerLine * linesToRead ) )
			return false;

		CopyRectangle( c, (uint8_t *)c->buffer, rx, y, rw,linesToRead );

		h -= linesToRead;
		y += linesToRead;
	}

	return true;
}
Пример #16
0
static int
ReadSecurityType(void)
{
  CARD32 secType;

  /* Read the security type */
  if (!ReadFromRFBServer((char *)&secType, sizeof(secType)))
    return rfbSecTypeInvalid;

  secType = Swap32IfLE(secType);

  if (secType == rfbSecTypeInvalid) {
    ReadConnFailedReason();
    return rfbSecTypeInvalid;
  }

  if (secType != rfbSecTypeNone && secType != rfbSecTypeVncAuth) {
    fprintf(stderr, "Unknown security type from RFB server: %d\n",
            (int)secType);
    return rfbSecTypeInvalid;
  }

  return (int)secType;
}
Пример #17
0
Bool HandleCursorShape(int xhot, int yhot, int width, int height, CARD32 enc)
{
  int bytesPerPixel;
  size_t bytesPerRow, bytesMaskData;
/*  Drawable dr;*/
  rfbXCursorColors rgb;
  CARD32 colors[2];
  char *buf;
  CARD8 *ptr;
  int x, y, b;

  bytesPerPixel = myFormat.bitsPerPixel / 8;
  bytesPerRow = (width + 7) / 8;
  bytesMaskData = bytesPerRow * height;
/*  dr = DefaultRootWindow(dpy);*/

  FreeSoftCursor();

  if (width * height == 0)
    return True;

  /* Allocate memory for pixel data and temporary mask data. */

  rcSource = malloc(width * height * bytesPerPixel);
  if (rcSource == NULL)
    return False;

  buf = malloc(bytesMaskData);
  if (buf == NULL) {
    free(rcSource);
    return False;
  }

  /* Read and decode cursor pixel data, depending on the encoding type. */

  if (enc == rfbEncodingXCursor) {

    /* Read and convert background and foreground colors. */
    if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) {
      free(rcSource);
      free(buf);
      return False;
    }
    colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue);
    colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue);

    /* Read 1bpp pixel data into a temporary buffer. */
    if (!ReadFromRFBServer(buf, bytesMaskData)) {
      free(rcSource);
      free(buf);
      return False;
    }

    /* Convert 1bpp data to byte-wide color indices. */
    ptr = rcSource;
    for (y = 0; y < height; y++) {
      for (x = 0; x < width / 8; x++) {
	for (b = 7; b >= 0; b--) {
	  *ptr = buf[y * bytesPerRow + x] >> b & 1;
	  ptr += bytesPerPixel;
	}
      }
      for (b = 7; b > 7 - width % 8; b--) {
	*ptr = buf[y * bytesPerRow + x] >> b & 1;
	ptr += bytesPerPixel;
      }
    }

    /* Convert indices into the actual pixel values. */
    switch (bytesPerPixel) {
    case 1:
      for (x = 0; x < width * height; x++)
	rcSource[x] = (CARD8)colors[rcSource[x]];
      break;
    case 2:
      for (x = 0; x < width * height; x++)
	((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]];
      break;
    case 4:
      for (x = 0; x < width * height; x++)
	((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]];
      break;
    }

  } else {			/* enc == rfbEncodingRichCursor */

    if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) {
Пример #18
0
static Bool
AuthenticateUnixLogin(void)
{
  CARD32 loginLen, passwdLen, authResult;
  char *login;
  char *passwd;
  struct passwd *ps;

  fprintf(stderr, "Performing Unix login-style authentication\n");

  if (appData.userLogin) {
    login = appData.userLogin;
  } else {
    ps = getpwuid(getuid());
    login = ps->pw_name;
  }

  fprintf(stderr, "Using user name \"%s\"\n", login);

  if (appData.passwordDialog) {
    passwd = DoPasswordDialog();
  } else {
    passwd = getpass("Password: "******"Reading password failed\n");
    return False;
  }

  loginLen = Swap32IfLE((CARD32)strlen(login));
  passwdLen = Swap32IfLE((CARD32)strlen(passwd));

  if (!WriteExact(rfbsock, (char *)&loginLen, sizeof(loginLen)) ||
      !WriteExact(rfbsock, (char *)&passwdLen, sizeof(passwdLen)))
    return False;

  if (!WriteExact(rfbsock, login, strlen(login)) ||
      !WriteExact(rfbsock, passwd, strlen(passwd)))
    return False;

  /* Lose the password from memory */
  memset(passwd, '\0', strlen(passwd));

  if (!ReadFromRFBServer((char *)&authResult, sizeof(authResult)))
    return False;

  authResult = Swap32IfLE(authResult);

  switch (authResult) {
  case rfbVncAuthOK:
    fprintf(stderr, "Authentication succeeded\n");
    break;
  case rfbVncAuthFailed:
    fprintf(stderr, "Authentication failed\n");
    return False;
  case rfbVncAuthTooMany:
    fprintf(stderr, "Authentication failed - too many tries\n");
    return False;
  default:
    fprintf(stderr, "Unknown authentication result: %d\n",
	    (int)authResult);
    return False;
  }

  return True;
}
Пример #19
0
static Bool
AuthenticateVNC(void)
{
  CARD32 authScheme, authResult;
  CARD8 challenge[CHALLENGESIZE];
  char *passwd;
  char  buffer[64];
  char* cstatus;
  int   len;

  fprintf(stderr, "Performing standard VNC authentication\n");

  if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE))
    return False;

  if (appData.passwordFile) {
    passwd = vncDecryptPasswdFromFile(appData.passwordFile);
    if (!passwd) {
      fprintf(stderr, "Cannot read valid password from file \"%s\"\n",
	      appData.passwordFile);
      return False;
    }
  } else if (appData.autoPass) {
    passwd = buffer;
    cstatus = fgets(buffer, sizeof buffer, stdin);
    if (cstatus == NULL)
       buffer[0] = '\0';
    else
    {
       len = strlen(buffer);
       if (len > 0 && buffer[len - 1] == '\n')
	  buffer[len - 1] = '\0';
    }
  } else if (appData.passwordDialog) {
    passwd = DoPasswordDialog();
  } else {
    passwd = getpass("Password: "******"Reading password failed\n");
    return False;
  }
  if (strlen(passwd) > 8) {
    passwd[8] = '\0';
  }

  vncEncryptBytes(challenge, passwd);

  /* Lose the password from memory */
  memset(passwd, '\0', strlen(passwd));

  if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE))
    return False;

  if (!ReadFromRFBServer((char *)&authResult, 4))
    return False;

  authResult = Swap32IfLE(authResult);

  switch (authResult) {
  case rfbVncAuthOK:
    fprintf(stderr, "VNC authentication succeeded\n");
    break;
  case rfbVncAuthFailed:
    fprintf(stderr, "VNC authentication failed\n");
    return False;
  case rfbVncAuthTooMany:
    fprintf(stderr, "VNC authentication failed - too many tries\n");
    return False;
  default:
    fprintf(stderr, "Unknown VNC authentication result: %d\n",
	    (int)authResult);
    return False;
  }

  return True;
}
Пример #20
0
Bool
HandleRFBServerMessage()
{
  rfbServerToClientMsg msg;

  if (!ReadFromRFBServer((char *)&msg, 1))
    return False;

  switch (msg.type) {

  case rfbSetColourMapEntries:
  {
    fprintf(stderr, "Received unsupported rfbSetColourMapEntries\n");
    return False; /* unsupported */
  }

  case rfbFramebufferUpdate:
  {
    rfbFramebufferUpdateRectHeader rect;
    int linesToRead;
    int bytesPerLine;
    int i;

    if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
			   sz_rfbFramebufferUpdateMsg - 1))
      return False;

    msg.fu.nRects = Swap16IfLE(msg.fu.nRects);

    for (i = 0; i < msg.fu.nRects; i++) {
      if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
	return False;

      rect.r.x = Swap16IfLE(rect.r.x);
      rect.r.y = Swap16IfLE(rect.r.y);
      rect.r.w = Swap16IfLE(rect.r.w);
      rect.r.h = Swap16IfLE(rect.r.h);

      rect.encoding = Swap32IfLE(rect.encoding);

      if (rect.encoding == rfbEncodingXCursor) {
	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rfbEncodingXCursor)) {
	  return False;
	}
        continue;
      }
      if (rect.encoding == rfbEncodingRichCursor) {
	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rfbEncodingRichCursor)) {
	  return False;
	}
        continue;
      }

      if (rect.encoding == rfbEncodingPointerPos) {
	if (!HandleCursorPos(rect.r.x, rect.r.y)) {
	  return False;
	}
        appData.gotCursorPos = 1;
	continue;
      }

      if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
	  (rect.r.y + rect.r.h > si.framebufferHeight))
	{
	  fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
	  return False;
	}

      if ((rect.r.h * rect.r.w) == 0) {
	fprintf(stderr,"Zero size rect - ignoring\n");
	continue;
      }

      /* If RichCursor encoding is used, we should prevent collisions
	 between framebuffer updates and cursor drawing operations. */
      SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);

      switch (rect.encoding) {

      case rfbEncodingRaw:

	bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
	linesToRead = BUFFER_SIZE / bytesPerLine;

	while (rect.r.h > 0) {
	  if (linesToRead > rect.r.h)
	    linesToRead = rect.r.h;

	  if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
	    return False;
	  CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
			   linesToRead);

	  rect.r.h -= linesToRead;
	  rect.r.y += linesToRead;

	}
	break;

      case rfbEncodingCopyRect:
      {
	rfbCopyRect cr;
          char *buffer;

	if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
	  return False;

          if (!BufferWritten()) {
            /* Ignore attempts to do copy-rect when we have nothing to
             * copy from.
             */
            break;
        }

 	cr.srcX = Swap16IfLE(cr.srcX);
	cr.srcY = Swap16IfLE(cr.srcY);

	/* If RichCursor encoding is used, we should extend our
	   "cursor lock area" (previously set to destination
	   rectangle) to the source rectangle as well. */
	SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);

        buffer = CopyScreenToData(cr.srcX, cr.srcY, rect.r.w, rect.r.h);
        CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
        free(buffer);

	break;
      }

      case rfbEncodingRRE:
      {
	if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	break;
      }

      case rfbEncodingCoRRE:
      {
	if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	  return False;
	break;
      }

      case rfbEncodingHextile:
      {
	if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	break;
      }

      case rfbEncodingZlib:
      {
	if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	break;
     }

      case rfbEncodingTight:
      {
	if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	break;
      }

      case rfbEncodingZRLE:
        if (!zrleDecode(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
          return False;
	break;

      default:
	fprintf(stderr,"Unknown rect encoding %d\n",
		(int)rect.encoding);
	return False;
      }

      /* Now we may discard "soft cursor locks". */
      SoftCursorUnlockScreen();

        /* Done. Save the screen image. */
    }

      /* RealVNC sometimes returns an initial black screen. */
      if (BufferIsBlank() && appData.ignoreBlank) {
          if (!appData.quiet && appData.ignoreBlank != 1) {
              /* user did not specify either -quiet or -ignoreblank */
              fprintf(stderr, "Warning: discarding received blank screen (use -allowblank to accept,\n   or -ignoreblank to suppress this message)\n");
              appData.ignoreBlank = 1;
          }
          RequestNewUpdate();
      } else {
          return False;
      }

    break;
  }

  case rfbBell:
    /* ignore */
    break;

  case rfbServerCutText:
  {
    if (!ReadFromRFBServer(((char *)&msg) + 1,
			   sz_rfbServerCutTextMsg - 1))
      return False;

    msg.sct.length = Swap32IfLE(msg.sct.length);

    if (serverCutText)
      free(serverCutText);

    serverCutText = malloc(msg.sct.length+1);

    if (!ReadFromRFBServer(serverCutText, msg.sct.length))
      return False;

    serverCutText[msg.sct.length] = 0;

    newServerCutText = True;

    break;
  }

  default:
    fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
    return False;
  }

  return True;
}
Пример #21
0
static Bool
HandleHextileBPP (int rx, int ry, int rw, int rh)
{
  CARDBPP bg, fg;
/*  XGCValues gcv; */
  int i;
  CARD8 *ptr;
  int x, y, w, h;
  int sx, sy, sw, sh;
  CARD8 subencoding;
  CARD8 nSubrects;

  for (y = ry; y < ry+rh; y += 16) {
    for (x = rx; x < rx+rw; x += 16) {
      w = h = 16;
      if (rx+rw - x < 16)
	w = rx+rw - x;
      if (ry+rh - y < 16)
	h = ry+rh - y;

      if (!ReadFromRFBServer((char *)&subencoding, 1))
	return False;

      if (subencoding & rfbHextileRaw) {
	if (!ReadFromRFBServer(buffer, w * h * (BPP / 8)))
	  return False;

/*	CopyDataToScreen(buffer, x, y, w, h); */
	continue;
      }

      if (subencoding & rfbHextileBackgroundSpecified)
	if (!ReadFromRFBServer((char *)&bg, sizeof(bg)))
	  return False;

#if (BPP == 8)
/*      if (appData.useBGR233)
	gcv.foreground = BGR233ToPixel[bg];
      else */
#endif
/*	gcv.foreground = bg;

      XChangeGC(dpy, gc, GCForeground, &gcv);
      XFillRectangle(dpy, desktopWin, gc, x, y, w, h); */

      if (subencoding & rfbHextileForegroundSpecified)
	if (!ReadFromRFBServer((char *)&fg, sizeof(fg)))
	  return False;

      if (!(subencoding & rfbHextileAnySubrects)) {
	continue;
      }

      if (!ReadFromRFBServer((char *)&nSubrects, 1))
	return False;

      ptr = (CARD8 *)buffer;

      if (subencoding & rfbHextileSubrectsColoured) {
	if (!ReadFromRFBServer(buffer, nSubrects * (2 + (BPP / 8))))
	  return False;

	for (i = 0; i < nSubrects; i++) {
	  GET_PIXEL(fg, ptr);
	  sx = rfbHextileExtractX(*ptr);
	  sy = rfbHextileExtractY(*ptr);
	  ptr++;
	  sw = rfbHextileExtractW(*ptr);
	  sh = rfbHextileExtractH(*ptr);
	  ptr++;
#if (BPP == 8)
/*	  if (appData.useBGR233)
	    gcv.foreground = BGR233ToPixel[fg];
	  else */
#endif
/*	    gcv.foreground = fg;

	  XChangeGC(dpy, gc, GCForeground, &gcv);
	  XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh); */
	}

      } else {
	if (!ReadFromRFBServer(buffer, nSubrects * 2))
	  return False;

#if (BPP == 8)
/*	if (appData.useBGR233)
	  gcv.foreground = BGR233ToPixel[fg];
	else */
#endif
/*	  gcv.foreground = fg;

	XChangeGC(dpy, gc, GCForeground, &gcv); */

	for (i = 0; i < nSubrects; i++) {
	  sx = rfbHextileExtractX(*ptr);
	  sy = rfbHextileExtractY(*ptr);
	  ptr++;
	  sw = rfbHextileExtractW(*ptr);
	  sh = rfbHextileExtractH(*ptr);
	  ptr++;
/*	  XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh); */
	}
      }
    }
  }

  return True;
}
Пример #22
0
Bool
InitialiseRFBConnection()
{
  rfbProtocolVersionMsg pv;
  int major,minor;
  CARD32 authScheme, reasonLen, authResult;
  char *reason;
  CARD8 challenge[CHALLENGESIZE];
  char *passwd;
  int i;
  rfbClientInitMsg ci;

  if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) return False;

  pv[sz_rfbProtocolVersionMsg] = 0;

  if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
    fprintf(stderr,"Not a valid VNC server\n");
    return False;
  }

  if (!appData.quiet) {
     fprintf(stderr,"VNC server supports protocol version %d.%d (viewer %d.%d)\n",
             major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
  }

  major = rfbProtocolMajorVersion;
  minor = rfbProtocolMinorVersion;

  sprintf(pv,rfbProtocolVersionFormat,major,minor);

  if (!WriteToRFBServer(pv, sz_rfbProtocolVersionMsg)) return False;
  if (!ReadFromRFBServer((char *)&authScheme, 4)) return False;

  authScheme = Swap32IfLE(authScheme);

  switch (authScheme) {

  case rfbConnFailed:
    if (!ReadFromRFBServer((char *)&reasonLen, 4)) return False;
    reasonLen = Swap32IfLE(reasonLen);

    reason = malloc(reasonLen);

    if (!ReadFromRFBServer(reason, reasonLen)) return False;

    fprintf(stderr,"VNC connection failed: %.*s\n",(int)reasonLen, reason);
    return False;

  case rfbNoAuth:
    if (!appData.quiet) {
      fprintf(stderr,"No authentication needed\n");
    }
    break;

  case rfbVncAuth:
    if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) return False;

    if (appData.passwordFile) {
      passwd = vncDecryptPasswdFromFile(appData.passwordFile);
      if (!passwd) {
	fprintf(stderr,"Cannot read valid password from file \"%s\"\n",
		appData.passwordFile);
	return False;
      } /* added this to read the command line password */
    } else if (appData.tpass) {
	passwd = appData.tpass;
    } else {
      passwd = getpass("Password: "******"Reading password failed\n");
      return False;
    }
    if (strlen(passwd) > 8) {
      passwd[8] = '\0';
    }

    vncEncryptBytes(challenge, passwd);

	/* Lose the password from memory */
    for (i = strlen(passwd); i >= 0; i--) {
      passwd[i] = '\0';
    }

    if (!WriteToRFBServer((char *)challenge, CHALLENGESIZE)) return False;

    if (!ReadFromRFBServer((char *)&authResult, 4)) return False;

    authResult = Swap32IfLE(authResult);

    switch (authResult) {
    case rfbVncAuthOK:
      if (!appData.quiet) {
        fprintf(stderr,"VNC authentication succeeded\n");
      }
      break;
    case rfbVncAuthFailed:
      fprintf(stderr,"VNC authentication failed\n");
      return False;
    case rfbVncAuthTooMany:
      fprintf(stderr,"VNC authentication failed - too many tries\n");
      return False;
    default:
      fprintf(stderr,"Unknown VNC authentication result: %d\n",
	      (int)authResult);
      return False;
    }
    break;

  default:
    fprintf(stderr,"Unknown authentication scheme from VNC server: %d\n",
	    (int)authScheme);
    return False;
  }

  ci.shared = 1;

  if (!WriteToRFBServer((char *)&ci, sz_rfbClientInitMsg)) return False;

  if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) return False;

  si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
  si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
  si.format.redMax = Swap16IfLE(si.format.redMax);
  si.format.greenMax = Swap16IfLE(si.format.greenMax);
  si.format.blueMax = Swap16IfLE(si.format.blueMax);
  si.nameLength = Swap32IfLE(si.nameLength);

  desktopName = malloc(si.nameLength + 1);
  if (!desktopName) {
    fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
            (unsigned long)si.nameLength);
    return False;
  }

  if (!ReadFromRFBServer(desktopName, si.nameLength)) return False;

  desktopName[si.nameLength] = 0;

  if (!appData.quiet) {
    fprintf(stderr,"Desktop name \"%s\"\n",desktopName);

    fprintf(stderr,"Connected to VNC server, using protocol version %d.%d\n",
            rfbProtocolMajorVersion, rfbProtocolMinorVersion);

    fprintf(stderr,"VNC server default format:\n");
    PrintPixelFormat(&si.format);
  }

  return True;
}
Пример #23
0
Bool HandleXCursor(int xhot, int yhot, int width, int height)
{
  rfbXCursorColors colors;
  size_t bytesPerRow, bytesData;
  char *buf = NULL;
  XColor bg, fg;
  Drawable dr;
  unsigned int wret = 0, hret = 0;
  Pixmap source, mask;
  Cursor cursor;
  int i;

  bytesPerRow = (width + 7) / 8;
  bytesData = bytesPerRow * height;
  dr = DefaultRootWindow(dpy);

  if (width * height) {
    if (!ReadFromRFBServer((char *)&colors, sz_rfbXCursorColors))
      return False;

    buf = malloc(bytesData * 2);
    if (buf == NULL)
      return False;

    if (!ReadFromRFBServer(buf, bytesData * 2)) {
      free(buf);
      return False;
    }

    XQueryBestCursor(dpy, dr, width, height, &wret, &hret);
  }

  if (width * height == 0 || (int) wret < width || (int) hret < height) {
    /* Free resources */
    if (buf != NULL)
      free(buf);
    FreeX11Cursor();
    return True;
  }

  bg.red   = (unsigned short)colors.backRed   << 8 | colors.backRed;
  bg.green = (unsigned short)colors.backGreen << 8 | colors.backGreen;
  bg.blue  = (unsigned short)colors.backBlue  << 8 | colors.backBlue;
  fg.red   = (unsigned short)colors.foreRed   << 8 | colors.foreRed;
  fg.green = (unsigned short)colors.foreGreen << 8 | colors.foreGreen;
  fg.blue  = (unsigned short)colors.foreBlue  << 8 | colors.foreBlue;

  for (i = 0; (size_t) i < bytesData * 2; i++)
    buf[i] = (char)_reverse_byte[(int)buf[i] & 0xFF];

  source = XCreateBitmapFromData(dpy, dr, buf, width, height);
  mask = XCreateBitmapFromData(dpy, dr, &buf[bytesData], width, height);
  cursor = XCreatePixmapCursor(dpy, source, mask, &fg, &bg, xhot, yhot);
  XFreePixmap(dpy, source);
  XFreePixmap(dpy, mask);
  free(buf);

  XDefineCursor(dpy, desktopWin, cursor);
  FreeX11Cursor();
  prevXCursor = cursor;
  prevXCursorSet = True;

  return True;
}
Пример #24
0
/* VeNCrypt sub auth. 1 byte auth count, followed by count * 4 byte integers */
static rfbBool
ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result)
{
    uint8_t count=0;
    uint8_t loop=0;
    uint8_t flag=0;
    uint32_t tAuth[256], t;
    char buf1[500],buf2[10];
    uint32_t authScheme;

    if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;

    if (count==0)
    {
        rfbClientLog("List of security types is ZERO. Giving up.\n");
        return FALSE;
    }

    if (count>sizeof(tAuth))
    {
        rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth));
        return FALSE;
    }

    rfbClientLog("We have %d security types to read\n", count);
    authScheme=0;
    /* now, we have a list of available security types to read ( uint8_t[] ) */
    for (loop=0;loop<count;loop++)
    {
        if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 4)) return FALSE;
        t=rfbClientSwap32IfLE(tAuth[loop]);
        rfbClientLog("%d) Received security type %d\n", loop, t);
        if (flag) continue;
        if (t==rfbVeNCryptTLSNone ||
            t==rfbVeNCryptTLSVNC ||
            t==rfbVeNCryptTLSPlain ||
            t==rfbVeNCryptX509None ||
            t==rfbVeNCryptX509VNC ||
            t==rfbVeNCryptX509Plain)
        {
            flag++;
            authScheme=t;
            rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
            /* send back 4 bytes (in original byte order!) indicating which security type to use */
            if (!WriteToRFBServer(client, (char *)&tAuth[loop], 4)) return FALSE;
        }
        tAuth[loop]=t;
    }
    if (authScheme==0)
    {
        memset(buf1, 0, sizeof(buf1));
        for (loop=0;loop<count;loop++)
        {
            if (strlen(buf1)>=sizeof(buf1)-1) break;
            snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]);
            strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1);
        }
        rfbClientLog("Unknown VeNCrypt authentication scheme from VNC server: %s\n",
               buf1);
        return FALSE;
    }
    *result = authScheme;
    return TRUE;
}
Пример #25
0
rfbBool
HandleVeNCryptAuth(rfbClient* client)
{
  uint8_t major, minor, status;
  uint32_t authScheme;
  rfbBool anonTLS;
  gnutls_certificate_credentials_t x509_cred = NULL;
  int ret;

  if (!InitializeTLS()) return FALSE;

  /* Read VeNCrypt version */
  if (!ReadFromRFBServer(client, (char *)&major, 1) ||
      !ReadFromRFBServer(client, (char *)&minor, 1))
  {
    return FALSE;
  }
  rfbClientLog("Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor);

  if (major != 0 && minor != 2)
  {
    rfbClientLog("Unsupported VeNCrypt version.\n");
    return FALSE;
  }

  if (!WriteToRFBServer(client, (char *)&major, 1) ||
      !WriteToRFBServer(client, (char *)&minor, 1) ||
      !ReadFromRFBServer(client, (char *)&status, 1))
  {
    return FALSE;
  }

  if (status != 0)
  {
    rfbClientLog("Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor);
    return FALSE;
  }

  if (!ReadVeNCryptSecurityType(client, &authScheme)) return FALSE;
  if (!ReadFromRFBServer(client, (char *)&status, 1) || status != 1)
  {
    rfbClientLog("Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status);
    return FALSE;
  }
  client->subAuthScheme = authScheme;

  /* Some VeNCrypt security types are anonymous TLS, others are X509 */
  switch (authScheme)
  {
    case rfbVeNCryptTLSNone:
    case rfbVeNCryptTLSVNC:
    case rfbVeNCryptTLSPlain:
      anonTLS = TRUE;
      break;
    default:
      anonTLS = FALSE;
      break;
  }

  /* Get X509 Credentials if it's not anonymous */
  if (!anonTLS)
  {
    rfbCredential *cred;

    if (!client->GetCredential)
    {
      rfbClientLog("GetCredential callback is not set.\n");
      return FALSE;
    }
    cred = client->GetCredential(client, rfbCredentialTypeX509);
    if (!cred)
    {
      rfbClientLog("Reading credential failed\n");
      return FALSE;
    }

    x509_cred = CreateX509CertCredential(cred);
    FreeX509Credential(cred);
    if (!x509_cred) return FALSE;
  }

  /* Start up the TLS session */
  if (!InitializeTLSSession(client, anonTLS)) return FALSE;

  if (anonTLS)
  {
    if (!SetTLSAnonCredential(client)) return FALSE;
  }
  else
  {
    if ((ret = gnutls_credentials_set((gnutls_session_t)client->tlsSession, GNUTLS_CRD_CERTIFICATE, x509_cred)) < 0)
    {
      rfbClientLog("Cannot set x509 credential: %s.\n", gnutls_strerror(ret));
      FreeTLS(client);
      return FALSE;
    }
  }

  if (!HandshakeTLS(client)) return FALSE;

  /* TODO: validate certificate */

  /* We are done here. The caller should continue with client->subAuthScheme
   * to do actual sub authentication.
   */
  return TRUE;
}
Пример #26
0
Bool
VNCViewer::HandleHextileBPP (sgVNCViewer *ct, int rx, int ry, int rw, int rh)
{
    CARDBPP bg, fg;
    int i;
    CARD8 *ptr;
    int x, y, w, h;
    int sx, sy, sw, sh;
    CARD8 subencoding;
    CARD8 nSubrects;

    for (y = ry; y < ry+rh; y += 16) {
        for (x = rx; x < rx+rw; x += 16) {
            w = h = 16;
            if (rx+rw - x < 16)
                w = rx+rw - x;
            if (ry+rh - y < 16)
                h = ry+rh - y;

            if (!ReadFromRFBServer((char *)&subencoding, 1))
                return False;

            if (subencoding & rfbHextileRaw) {
                if (!ReadFromRFBServer(buffer, w * h * (BPP / 8)))
                    return False;

                ct->CopyDataToScreen(buffer, x, y, w, h);
                continue;
            }

            if (subencoding & rfbHextileBackgroundSpecified)
                if (!ReadFromRFBServer((char *)&bg, sizeof(bg)))
                    return False;

            ct->FillToScreen(bg, x, y, w, h);

            if (subencoding & rfbHextileForegroundSpecified)
                if (!ReadFromRFBServer((char *)&fg, sizeof(fg)))
                    return False;

            if (!(subencoding & rfbHextileAnySubrects)) {
                continue;
            }

            if (!ReadFromRFBServer((char *)&nSubrects, 1))
                return False;

            ptr = (CARD8 *)buffer;

            if (subencoding & rfbHextileSubrectsColoured) {
                if (!ReadFromRFBServer(buffer, nSubrects * (2 + (BPP / 8))))
                    return False;

                for (i = 0; i < nSubrects; i++) {
                    GET_PIXEL(fg, ptr);
                    sx = rfbHextileExtractX(*ptr);
                    sy = rfbHextileExtractY(*ptr);
                    ptr++;
                    sw = rfbHextileExtractW(*ptr);
                    sh = rfbHextileExtractH(*ptr);
                    ptr++;

                    ct->FillToScreen(fg, x+sx, y+sy, sw, sh);
                }

            } else {
                if (!ReadFromRFBServer(buffer, nSubrects * 2))
                    return False;

                for (i = 0; i < nSubrects; i++) {
                    sx = rfbHextileExtractX(*ptr);
                    sy = rfbHextileExtractY(*ptr);
                    ptr++;
                    sw = rfbHextileExtractW(*ptr);
                    sh = rfbHextileExtractH(*ptr);
                    ptr++;

                    ct->FillToScreen(fg, x+sx, y+sy, sw, sh);
                }
            }
        }
    }

    return True;
}
Пример #27
0
Bool
HandleRFBServerMessage()
{
  rfbServerToClientMsg msg;

  if (!ReadFromRFBServer((char *)&msg, 1))
    return False;

  switch (msg.type) {

  case rfbSetColourMapEntries:
  {
    int i;
    CARD16 rgb[3];
    XColor xc;

    if (!ReadFromRFBServer(((char *)&msg) + 1,
			   sz_rfbSetColourMapEntriesMsg - 1))
      return False;

    msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
    msg.scme.nColours = Swap16IfLE(msg.scme.nColours);

    for (i = 0; i < msg.scme.nColours; i++) {
      if (!ReadFromRFBServer((char *)rgb, 6))
	return False;
      xc.pixel = msg.scme.firstColour + i;
      xc.red = Swap16IfLE(rgb[0]);
      xc.green = Swap16IfLE(rgb[1]);
      xc.blue = Swap16IfLE(rgb[2]);
      xc.flags = DoRed|DoGreen|DoBlue;
      XStoreColor(dpy, cmap, &xc);
    }

    break;
  }

  case rfbFramebufferUpdate:
  {
    rfbFramebufferUpdateRectHeader rect;
    int linesToRead;
    int bytesPerLine;
    int i;
    int usecs;

    if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
			   sz_rfbFramebufferUpdateMsg - 1))
      return False;

    msg.fu.nRects = Swap16IfLE(msg.fu.nRects);

    for (i = 0; i < msg.fu.nRects; i++) {
      if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
	return False;

      rect.encoding = Swap32IfLE(rect.encoding);
      if (rect.encoding == rfbEncodingLastRect)
	break;

      rect.r.x = Swap16IfLE(rect.r.x);
      rect.r.y = Swap16IfLE(rect.r.y);
      rect.r.w = Swap16IfLE(rect.r.w);
      rect.r.h = Swap16IfLE(rect.r.h);

      if (rect.encoding == rfbEncodingXCursor ||
	  rect.encoding == rfbEncodingRichCursor) {
	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
			      rect.encoding)) {
	  return False;
	}
	continue;
      }

      if (rect.encoding == rfbEncodingPointerPos) {
	if (!HandleCursorPos(rect.r.x, rect.r.y)) {
	  return False;
	}
	continue;
      }

      if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
	  (rect.r.y + rect.r.h > si.framebufferHeight))
	{
	  fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
	  return False;
	}

      if (rect.r.h * rect.r.w == 0) {
	fprintf(stderr,"Zero size rect - ignoring\n");
	continue;
      }

      /* If RichCursor encoding is used, we should prevent collisions
	 between framebuffer updates and cursor drawing operations. */
      SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);

      switch (rect.encoding) {

      case rfbEncodingRaw:

	bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
	linesToRead = BUFFER_SIZE / bytesPerLine;

	while (rect.r.h > 0) {
	  if (linesToRead > rect.r.h)
	    linesToRead = rect.r.h;

	  if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
	    return False;

	  CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
			   linesToRead);

	  rect.r.h -= linesToRead;
	  rect.r.y += linesToRead;

	}
	break;

      case rfbEncodingCopyRect:
      {
	rfbCopyRect cr;

	if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
	  return False;

	cr.srcX = Swap16IfLE(cr.srcX);
	cr.srcY = Swap16IfLE(cr.srcY);

	/* If RichCursor encoding is used, we should extend our
	   "cursor lock area" (previously set to destination
	   rectangle) to the source rectangle as well. */
	SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);

	if (appData.copyRectDelay != 0) {
	  XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, srcGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	  XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, dstGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	  XSync(dpy,False);
	  usleep(appData.copyRectDelay * 1000);
	  XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, dstGC, rect.r.x,  rect.r.y, rect.r.w, rect.r.h);
#endif
	  XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, srcGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	}

	XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
#if VNC_CAPTURE
    myxcparea(dpy, gc, cr.srcX,  cr.srcY, rect.r.w, rect.r.h,rect.r.x,rect.r.y);
#endif

	break;
      }

      case rfbEncodingRRE:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingCoRRE:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingHextile:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingZlib:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
     }

      case rfbEncodingTight:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      default:
	fprintf(stderr,"Unknown rect encoding %d\n",
		(int)rect.encoding);
	return False;
      }

      /* Now we may discard "soft cursor locks". */
      SoftCursorUnlockScreen();
    }

#ifdef MITSHM
    /* if using shared memory PutImage, make sure that the X server has
       updated its framebuffer before we reuse the shared memory.  This is
       mainly to avoid copyrect using invalid screen contents - not sure
       if we'd need it otherwise. */

    if (appData.useShm)
      XSync(dpy, False);
#endif

    if (!SendIncrementalFramebufferUpdateRequest())
      return False;

    break;
  }

  case rfbBell:
  {
    Window toplevelWin;

    XBell(dpy, 0);

    if (appData.raiseOnBeep) {
      toplevelWin = XtWindow(toplevel);
      XMapRaised(dpy, toplevelWin);
    }

    break;
  }

  case rfbServerCutText:
  {
    if (!ReadFromRFBServer(((char *)&msg) + 1,
			   sz_rfbServerCutTextMsg - 1))
      return False;

    msg.sct.length = Swap32IfLE(msg.sct.length);

    if (serverCutText)
      free(serverCutText);

    serverCutText = malloc(msg.sct.length+1);

    if (!ReadFromRFBServer(serverCutText, msg.sct.length))
      return False;

    serverCutText[msg.sct.length] = 0;

    newServerCutText = True;

    break;
  }

  default:
    fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
    return False;
  }

  return True;
}
Пример #28
0
Bool
InitialiseRFBConnection(void)
{
  rfbProtocolVersionMsg pv;
  int server_major, server_minor;
  int viewer_major, viewer_minor;
  rfbClientInitMsg ci;
  int secType;

  /* if the connection is immediately closed, don't report anything, so
       that pmw's monitor can make test connections */

  if (listenSpecified)
    errorMessageOnReadFailure = False;

  if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg))
    return False;

  errorMessageOnReadFailure = True;

  pv[sz_rfbProtocolVersionMsg] = 0;

  if (sscanf(pv, rfbProtocolVersionFormat,
	     &server_major, &server_minor) != 2) {
    fprintf(stderr,"Not a valid VNC server\n");
    return False;
  }

  viewer_major = rfbProtocolMajorVersion;
  if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) {
    /* the server supports at least the standard protocol 3.7 */
    viewer_minor = rfbProtocolMinorVersion;
  } else {
    /* any other server version, request the standard 3.3 */
    viewer_minor = rfbProtocolFallbackMinorVersion;
  }

  fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n",
	  viewer_major, viewer_minor);

  sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor);

  if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg))
    return False;

  /* Read or select the security type. */
  if (viewer_minor == rfbProtocolMinorVersion) {
    secType = SelectSecurityType();
  } else {
    secType = ReadSecurityType();
  }
  if (secType == rfbSecTypeInvalid)
    return False;

  switch (secType) {
  case rfbSecTypeNone:
    fprintf(stderr, "No authentication needed\n");
    break;
  case rfbSecTypeVncAuth:
    if (!AuthenticateVNC())
      return False;
    break;
  case rfbSecTypeTight:
    tightVncProtocol = True;
    InitCapabilities();
    if (!SetupTunneling())
      return False;
    if (!PerformAuthenticationTight())
      return False;
    break;
  default:                      /* should never happen */
    fprintf(stderr, "Internal error: Invalid security type\n");
    return False;
  }

  ci.shared = (appData.shareDesktop ? 1 : 0);

  if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg))
    return False;

  if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg))
    return False;

  si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
  si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
  si.format.redMax = Swap16IfLE(si.format.redMax);
  si.format.greenMax = Swap16IfLE(si.format.greenMax);
  si.format.blueMax = Swap16IfLE(si.format.blueMax);
  si.nameLength = Swap32IfLE(si.nameLength);

  /* FIXME: Check arguments to malloc() calls. */
  desktopName = malloc(si.nameLength + 1);
  if (!desktopName) {
    fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
            (unsigned long)si.nameLength);
    return False;
  }

  if (!ReadFromRFBServer(desktopName, si.nameLength)) return False;

  desktopName[si.nameLength] = 0;

  fprintf(stderr,"Desktop name \"%s\"\n",desktopName);

  fprintf(stderr,"VNC server default format:\n");
  PrintPixelFormat(&si.format);

  if (tightVncProtocol) {
    /* Read interaction capabilities (protocol 3.7t) */
    if (!ReadInteractionCaps())
      return False;
  }

  return True;
}
Пример #29
0
static rfbBool handleEncodingLZORLE( rfbClient *client,
										rfbFramebufferUpdateRectHeader *r )
{
	if( r->encoding != rfbEncodingLZORLE )
	{
		return false;
	}

	uint16_t rx = r->r.x;
	uint16_t ry = r->r.y;
	const uint16_t rw = r->r.w;
	const uint16_t rh = r->r.h;

	RfbLZORLE::Header hdr;
	if( !ReadFromRFBServer( client, (char *) &hdr, sizeof( hdr ) ) )
	{
		qWarning( "failed reading RfbLZORLE::Header from server" );
		return false;
	}

	if( !hdr.compressed )
	{
		return handleRaw( client, rx, ry, rw, rh );
	}

	hdr.bytesLZO = rfbClientSwap32IfLE( hdr.bytesLZO );
	hdr.bytesRLE = rfbClientSwap32IfLE( hdr.bytesRLE );

	auto lzo_data = new uint8_t[hdr.bytesLZO];

	if( !ReadFromRFBServer( client, (char *) lzo_data, hdr.bytesLZO ) )
	{
		qWarning( "failed reading LZO data from server" );
		delete[] lzo_data;
		return false;
	}

	auto rle_data = new uint8_t[hdr.bytesRLE];

	lzo_uint decomp_bytes = hdr.bytesRLE;
	lzo1x_decompress_safe( (const unsigned char *) lzo_data,
				(lzo_uint) hdr.bytesLZO,
				(unsigned char *) rle_data,
				(lzo_uint *) &decomp_bytes, nullptr );
	if( decomp_bytes != hdr.bytesRLE )
	{
		delete[] rle_data;
		delete[] lzo_data;
		qCritical( "handleEncodingLZORLE(...): expected and real "
					"size of decompressed data do not match!" );
		return false;
	}

	QRgb *dst = ( (QRgb *) client->frameBuffer ) + client->width*ry + rx;
	int dx = 0;
	bool done = FALSE;
	const int sh = client->height;
	for( uint32_t i = 0; i < hdr.bytesRLE && done == false; i+=4 )
	{
		const QRgb val = rfbClientSwap24IfLE( *( (QRgb*)( rle_data + i ) ) );
		const uint8_t rleCount = rle_data[i+3];
		for( uint16_t j = 0; j <= rleCount; ++j )
		{
			*dst = val;
			if( ++dx >= rw )
			{
				dx = 0;
				if( ry+1 < sh )
				{
					++ry;
					dst = ( (QRgb *) client->frameBuffer ) + client->width*ry + rx;
				}
				else
				{
					done = true;
					break;
				}
			}
			else
			{
				++dst;
			}
		}
	}

	if( dx != 0 )
	{
		qWarning( "handleEncodingLZORLE(...): dx(%d) != 0", dx );
	}

	delete[] lzo_data;
	delete[] rle_data;

	return true;
}
Пример #30
0
static rfbBool
HandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh)
{
	rfbZRLEHeader header;
	int remaining;
	int inflateResult;
	int toRead;
	int min_buffer_size = rw * rh * (REALBPP / 8) * 2;

	/* First make sure we have a large enough raw buffer to hold the
	 * decompressed data.  In practice, with a fixed REALBPP, fixed frame
	 * buffer size and the first update containing the entire frame
	 * buffer, this buffer allocation should only happen once, on the
	 * first update.
	 */
	if ( client->raw_buffer_size < min_buffer_size) {

		if ( client->raw_buffer != NULL ) {

			free( client->raw_buffer );

		}

		client->raw_buffer_size = min_buffer_size;
		client->raw_buffer = (char*) malloc( client->raw_buffer_size );

	}

	if (!ReadFromRFBServer(client, (char *)&header, sz_rfbZRLEHeader))
		return FALSE;

	remaining = rfbClientSwap32IfLE(header.length);

	/* Need to initialize the decompressor state. */
	client->decompStream.next_in   = ( Bytef * )client->buffer;
	client->decompStream.avail_in  = 0;
	client->decompStream.next_out  = ( Bytef * )client->raw_buffer;
	client->decompStream.avail_out = client->raw_buffer_size;
	client->decompStream.data_type = Z_BINARY;

	/* Initialize the decompression stream structures on the first invocation. */
	if ( client->decompStreamInited == FALSE ) {

		inflateResult = inflateInit( &client->decompStream );

		if ( inflateResult != Z_OK ) {
			rfbClientLog(
					"inflateInit returned error: %d, msg: %s\n",
					inflateResult,
					client->decompStream.msg);
			return FALSE;
		}

		client->decompStreamInited = TRUE;

	}

	inflateResult = Z_OK;

	/* Process buffer full of data until no more to process, or
	 * some type of inflater error, or Z_STREAM_END.
	 */
	while (( remaining > 0 ) &&
			( inflateResult == Z_OK )) {

		if ( remaining > RFB_BUFFER_SIZE ) {
			toRead = RFB_BUFFER_SIZE;
		}
		else {
			toRead = remaining;
		}

		/* Fill the buffer, obtaining data from the server. */
		if (!ReadFromRFBServer(client, client->buffer,toRead))
			return FALSE;

		client->decompStream.next_in  = ( Bytef * )client->buffer;
		client->decompStream.avail_in = toRead;

		/* Need to uncompress buffer full. */
		inflateResult = inflate( &client->decompStream, Z_SYNC_FLUSH );

		/* We never supply a dictionary for compression. */
		if ( inflateResult == Z_NEED_DICT ) {
			rfbClientLog("zlib inflate needs a dictionary!\n");
			return FALSE;
		}
		if ( inflateResult < 0 ) {
			rfbClientLog(
					"zlib inflate returned error: %d, msg: %s\n",
					inflateResult,
					client->decompStream.msg);
			return FALSE;
		}

		/* Result buffer allocated to be at least large enough.  We should
		 * never run out of space!
		 */
		if (( client->decompStream.avail_in > 0 ) &&
				( client->decompStream.avail_out <= 0 )) {
			rfbClientLog("zlib inflate ran out of space!\n");
			return FALSE;
		}

		remaining -= toRead;

	} /* while ( remaining > 0 ) */

	if ( inflateResult == Z_OK ) {
		char* buf=client->raw_buffer;
		int i,j;

		remaining = client->raw_buffer_size-client->decompStream.avail_out;

		for(j=0; j<rh; j+=rfbZRLETileHeight)
			for(i=0; i<rw; i+=rfbZRLETileWidth) {
				int subWidth=(i+rfbZRLETileWidth>rw)?rw-i:rfbZRLETileWidth;
				int subHeight=(j+rfbZRLETileHeight>rh)?rh-j:rfbZRLETileHeight;
				int result=HandleZRLETile(client,(uint8_t *)buf,remaining,rx+i,ry+j,subWidth,subHeight);

				if(result<0) {
					rfbClientLog("ZRLE decoding failed (%d)\n",result);
return TRUE;
					return FALSE;
				}

				buf+=result;
				remaining-=result;
			}
	}
	else {

		rfbClientLog(
				"zlib inflate returned error: %d, msg: %s\n",
				inflateResult,
				client->decompStream.msg);
		return FALSE;

	}

	return TRUE;
}