/*
  decode_pcanywhere.c

  Symantec pcAnywhere.

  Thanks to Pascal Longpre <longprep@HOTMAIL.COM> for his BUGTRAQ post
  on pcAnywhere encryption, and for providing me with traffic traces.
  
  Copyright (c) 2000 Dug Song <dugsong@monkey.org>
  
  $Id: decode_pcanywhere.c,v 1.4 2000/06/14 06:43:32 dugsong Exp $
*/

#include "config.h"

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include "decode.h"

int
decode_pcanywhere(u_char *buf, int len)
{
	u_char *p, *end;
	int i;
	
	Buf[0] = '\0';
	
	if (len < 6 || *(u_int32_t *)buf != 0)
		return (0);
	
	/* Version 7, no encryption. */
	if (buf[4] != 0x8d) {
		buf[len - 1] = '\0';
		if ((p = strchr(buf + 4, 0x6f)) != NULL) *p = '\0';
		
		for (p = strtok(buf + 5, "\r"); p; p = strtok(NULL, "\r")) {
			strlcat(Buf, p, sizeof(Buf));
			strlcat(Buf, "\n", sizeof(Buf));
		}
		return (strlen(Buf));
	}
	/* Version 9, lame encryption. */
	end = buf + len;
	for (p = buf + 5; end - p > 2; p++) {
		if (*p++ != 0x06)
			break;
		
		if (p > end || *p > 56 || end - p - 1 < *p)
			break;
		
		for (i = *p++ - 1; i > 0; i--)
			p[i] = p[i-1] ^ p[i] ^ (i - 1);
		p[0] ^= 0xab;
		
		i = *--p; memmove(p, p + 1, i); p[i] = '\0';	/* i suk */
		
		if (is_ascii_string(p, i)) {
			strlcat(Buf, p, sizeof(Buf));
			strlcat(Buf, "\n", sizeof(Buf));
		}
		p += i;
	}
	return (strlen(Buf));
}

