You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.4 KiB
C

/*
* probe_vnc.c
*
* Copyright (C) Brian de Alwis 2004
*
* This file is part of transcode, a video stream processing tool
*
* transcode is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* transcode is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "transcode.h"
#include "tcinfo.h"
#include "ioaux.h"
#include "tc.h"
#include "libtc/libtc.h"
/* Some VNC constants */
#define VNCREC_MAGIC_STRING "vncLog0.0"
#define VNCREC_MAGIC_SIZE (9)
#define VNC_RFB_PROTOCOL_SCANF_FORMAT "RFB %03d.%03d\n"
#define VNC_RFB_PROTO_VERSION_SIZE (12)
#define VNC33_CHALLENGESIZE (16)
#define VNC33_rfbConnFailed (0)
#define VNC33_rfbNoAuth (1)
#define VNC33_rfbVncAuth (2)
#define VNC33_rfbVncAuthOK (0)
#define VNC33_rfbVncAuthFailed (1)
#define VNC33_rfbVncAuthTooMany (2)
/*
RFB 3.X protocol is as follows (from vncrec source code):
* server send 12-byte (SIZE_SIZE_RFB_PROTO_VERSION) header
encoding the RFB version as an ASCII string
* server sends 4-byte number (big-endian) to alert auth
requirements
* if requiring auth, server then sends 16-byte (VNC33_CHALLENGESIZE)
packet, which is to be encrypted and sent back (same size).
The server then sends 32-bit word result on pass-fail. Entire
thing aborted if not passed.
* client sends 1-byte message
* server then sends a display-paramters message, containing
(in order) the width (2-byte), height (2-byte), preferred pixel
format (1-byte), and desktop name (1-byte with length, n bytes).
*/
void probe_vnc(info_t *ipipe)
{
unsigned char buf[100];
unsigned char matchingBuffer[100];
int index = 0, major, minor, authReqs;
int width, height;
if(tc_pread(ipipe->fd_in, buf, sizeof(buf)) != sizeof(buf)) {
tc_log_error(__FILE__, "end of stream");
ipipe->error=1;
return;
}
/* Check VNCREC magic */
ac_memcpy(matchingBuffer, &buf[index], VNCREC_MAGIC_SIZE);
matchingBuffer[VNCREC_MAGIC_SIZE] = 0;
if(strcmp(matchingBuffer, VNCREC_MAGIC_STRING)) { /* NOT EQUAL */
tc_log_error(__FILE__, "unsupported version of vncrec (\"%s\")",
matchingBuffer);
ipipe->error=1;
return;
}
index += VNCREC_MAGIC_SIZE;
/* Ensure RFB protocol is valid */
ac_memcpy(matchingBuffer, &buf[index], VNC_RFB_PROTO_VERSION_SIZE);
matchingBuffer[VNC_RFB_PROTO_VERSION_SIZE] = 0;
if(sscanf(matchingBuffer, VNC_RFB_PROTOCOL_SCANF_FORMAT, &major, &minor) != 2) {
tc_log_error(__FILE__, "unknown RFB protocol (\"%s\")",
matchingBuffer);
ipipe->error=1;
return;
}
if (ipipe->verbose & TC_DEBUG) {
tc_log_msg(__FILE__, "File recorded as RFB Protocol v%d.%d",
major, minor);
}
if(major != 3) {
tc_log_error(__FILE__, "unsupported RFB protocol (only support v3)");
ipipe->error=1;
return;
}
index += VNC_RFB_PROTO_VERSION_SIZE;
/* Check authentication requirements */
authReqs = (buf[index] << 24) | (buf[index+1] << 16)
| (buf[index+2] << 8) | buf[index+3];
index += 4;
switch(authReqs) {
case VNC33_rfbNoAuth:
if (ipipe->verbose & TC_DEBUG)
tc_log_msg(__FILE__, "No authorization required.");
break;
case VNC33_rfbVncAuth: {
int authResp =
index += VNC33_CHALLENGESIZE;
authResp = (buf[index] << 24) | (buf[index+1] << 16)
| (buf[index+2] << 8) | buf[index+3];
/* switch(authResp) { ... } */
index += 4;
break;
}
case VNC33_rfbConnFailed:
default:
tc_log_error(__FILE__, "apparently connection failed?");
ipipe->error=1;
return;
}
/* Receive display parameters */
width = (buf[index] << 8) | buf[index+1];
height = (buf[index+2] << 8) | buf[index+3];
ipipe->probe_info->width = width;
ipipe->probe_info->height = height;
ipipe->probe_info->fps = 25.;
ipipe->probe_info->frc = 3;
ipipe->probe_info->codec = TC_CODEC_RGB;
ipipe->probe_info->magic = ipipe->magic;
}