diff -Nur xbmc-9.11+svn27924/xbmc/xbmc/lib/libRTMP/rtmp.cpp.orig xbmc-9.11+svn27924/xbmc/xbmc/lib/libRTMP/rtmp.cpp
--- xbmc/xbmc/lib/libRTMP/rtmp.cpp.orig	2010-02-03 16:13:04.000000000 +1100
+++ xbmc/xbmc/lib/libRTMP/rtmp.cpp		2010-02-18 15:05:29.000000000 +1100
@@ -24,6 +24,10 @@
 #include "AMFObject.h"
 #include <assert.h>
 
+#include <openssl/sha.h>
+#include <openssl/hmac.h>
+#include <openssl/rc4.h>
+
 #ifdef _LINUX
   #include <sys/errno.h>
   #include <sys/types.h>
@@ -37,7 +41,6 @@
 #include "URL.h"
 #include "utils/log.h"
 #include "utils/TimeUtils.h"
-#include "utils/EndianSwap.h"
 
 #define RTMP_SIG_SIZE 1536
 #define RTMP_LARGE_HEADER_SIZE 12
@@ -46,6 +49,13 @@
 
 using namespace RTMP_LIB;
 
+char SWFVerificationResponse[42];
+  typedef struct AVal
+  {
+    char *av_val;
+    int av_len;
+  } AVal;
+
 static const int packetSize[] = { 12, 8, 4, 1 };
 #define RTMP_PACKET_SIZE_LARGE    0
 #define RTMP_PACKET_SIZE_MEDIUM   1
@@ -272,7 +282,7 @@
       if (m_nBytesIn > m_nBytesInSent + (600*1024) ) // report every 600K
         SendBytesReceived();
     }
-    
+
     if (nBytes == 0)
     {
       CLog::Log(LOGDEBUG,"%s, RTMP socket closed by server", __FUNCTION__);
@@ -336,7 +346,7 @@
     if( pos_slash != CStdString::npos )
       app = app.Left(pos_slash);
   }
-  
+
   CStdString tcURL;
   if (m_strTcUrl.empty())
   {
@@ -347,8 +357,7 @@
   {
     tcURL = m_strTcUrl;
   }
-  
-	
+
   RTMPPacket packet;
   packet.m_nChannel = 0x03;   // control channel (invoke)
   packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
@@ -564,7 +573,7 @@
       // or use last piece of URL, if there's more than one level
       CStdString::size_type pos_slash = url.GetFileName().find_last_of("/");
       if ( pos_slash != CStdString::npos )
-        strPlay = url.GetFileName().Mid(pos_slash+1);
+      strPlay = url.GetFileName().Mid(pos_slash+1);
     }
 
     if (strPlay.IsEmpty())
@@ -598,17 +607,28 @@
   packet.m_nInfoField1 = CTimeUtils::GetTimeMS();
 
   int nSize = (nType==0x03?10:6); // type 3 is the buffer time and requires all 3 parameters. all in all 10 bytes.
+  if (nType == 0x1B)
+    nSize = 44;
+  
   packet.AllocPacket(nSize);
   packet.m_nBodySize = nSize;
 
   char *buf = packet.m_body;
   buf += EncodeInt16(buf, nType);
 
-  if (nSize > 2)
-    buf += EncodeInt32(buf, nObject);
+  if (nType == 0x1B)
+  {
+    memcpy(buf, SWFVerificationResponse, 42);
+    CLog::Log(LOGERROR,"%s, attempting to send SWF ping: %s", __FUNCTION__, packet.m_body);
+  }
+  else
+  {
+    if (nSize > 2)
+      buf += EncodeInt32(buf, nObject);
 
-  if (nSize > 6)
-    buf += EncodeInt32(buf, nTime);
+    if (nSize > 6)
+      buf += EncodeInt32(buf, nTime);
+  }
 
   return SendRTMP(packet);
 }
@@ -725,6 +745,11 @@
     unsigned int nTime = ReadInt32(packet.m_body + 2);
     SendPing(0x07, nTime);
   }
+  
+  if (nType == 0x1A)
+  {
+    SendPing(0x1B, 0, 0);
+  }
 }
 
 bool CRTMP::ReadPacket(RTMPPacket &packet)
@@ -846,11 +871,12 @@
 }
 
 // little-endian 32bit integer
+// TODO: this is wrong on big-endian processors
 int  CRTMP::ReadInt32LE(const char *data)
 {
   int val;
   memcpy(&val, data, sizeof(int));
-  return Endian_SwapLE32(val);
+  return val;
 }
 
 std::string CRTMP::ReadString(const char *data)
@@ -876,16 +902,12 @@
 double CRTMP::ReadNumber(const char *data)
 {
   double val;
-#ifndef WORDS_BIGENDIAN
   char *dPtr = (char *)&val;
   for (int i=7;i>=0;i--)
   {
     *dPtr = data[i];
     dPtr++;
   }
-#else
-  memcpy(&val, data, 8);
-#endif
 
   return val;
 }
@@ -928,10 +950,23 @@
   return sizeof(int);
 }
 
+char *
+AMF_EncodeInt32(char *output, char *outend, int nVal)
+{
+  if (output+4 > outend)
+    return NULL;
+
+  output[3] = nVal & 0xff;
+  output[2] = nVal >> 8;
+  output[1] = nVal >> 16;
+  output[0] = nVal >> 24;
+  return output+4;
+}
+
 // little-endian 32bit integer
+// TODO: this is wrong on big-endian processors
 int CRTMP::EncodeInt32LE(char *output, int nVal)
 {
-  nVal = Endian_SwapLE32(nVal);
   memcpy(output, &nVal, sizeof(int));
   return sizeof(int);
 }
@@ -988,16 +1023,12 @@
   *buf = 0x00; // type: Number
   buf++;
 
-#ifndef WORDS_BIGENDIAN
   char *dPtr = (char *)&dVal;
   for (int i=7;i>=0;i--)
   {
     buf[i] = *dPtr;
     dPtr++;
   }
-#else
-  memcpy(buf, &dVal, 8);
-#endif
 
   buf += 8;
 
@@ -1017,10 +1048,94 @@
   return buf - output;
 }
 
+// Added by JS
+static void
+HMACsha256(const char *message, size_t messageLen, const char *key,
+	   size_t keylen, char *digest)
+{
+  unsigned int digestLen;
+
+  HMAC_CTX ctx;
+  HMAC_CTX_init(&ctx);
+  HMAC_Init_ex(&ctx, (unsigned char *) key, keylen, EVP_sha256(), NULL);
+  HMAC_Update(&ctx, (unsigned char *) message, messageLen);
+  HMAC_Final(&ctx, (unsigned char *) digest, &digestLen);
+  HMAC_CTX_cleanup(&ctx);
+
+  assert(digestLen == 32);
+}
+
+char *str2lower(char *str, int len)
+{
+	char *res = (char *)malloc(len+1);
+	char *p;
+
+	for(p=res; p<res+len; p++, str++) {
+		*p = tolower(*str);
+	}
+
+	*p = 0;
+
+	return res;
+}
+
+int chr2hex(char c)
+{
+	if(c <= 57 && c >= 48)
+        	return c-48;
+        else if(c <= 102 && c >= 97)
+                return c-97+10;
+        return -1;
+}
+
+int hex2bin(char *str, char **hex)
+{
+	if(!str || !hex)
+		return 0;
+
+	int len = strlen(str);
+
+	if(len % 2 != 0)
+		return 0;
+
+	int ret = len/2;
+
+	*hex = (char *)malloc(ret);
+	if((*hex)==0)
+		return 0;
+
+	char *hexptr = *hex;
+	char *lwo = str2lower(str, len);
+	char *lw = lwo;
+
+	len /= 2;
+
+	while(len) {
+		int d1 = chr2hex(*lw); lw++;
+		int d2 = chr2hex(*lw); lw++;
+
+		if(d1<0 || d2<0) {
+			free(*hex);
+			free(lwo);
+			*hex=NULL;
+			return -1;
+		}
+
+		*hexptr = (unsigned char)(d1*16+d2);
+		hexptr++;
+		len--;
+	}
+
+	free(lwo);
+	return ret;
+}
+// Finished additions
+
 bool CRTMP::HandShake()
 {
   char clientsig[RTMP_SIG_SIZE+1];
-  char serversig[RTMP_SIG_SIZE];
+  //char serversig[RTMP_SIG_SIZE];
+  char serverbuf[RTMP_SIG_SIZE + 4], *serversig = serverbuf+4;
 
   clientsig[0] = 0x3;
   DWORD uptime = htonl(CTimeUtils::GetTimeMS());
@@ -1029,6 +1144,11 @@
 
   for (int i=9; i<=RTMP_SIG_SIZE; i++)
     clientsig[i] = (char)(rand() % 256);
+  
+  char type = 3; //Is 3 for non-encrypted stream, 6 for encrypted
+  serversig[-1] = type;
+
+  memcpy(serversig, &uptime, 4);
 
   if (!WriteN(clientsig, RTMP_SIG_SIZE + 1))
     return false;
@@ -1053,7 +1173,37 @@
 
   if (!WriteN(serversig, RTMP_SIG_SIZE))
     return false;
+  
+   /* generate SWFVerification token (SHA256 HMAC hash of decompressed SWF, key are the last 32 bytes of the server handshake) */
+  AVal SWFHash;
+  uint32_t SWFSize; //Need to set this!
+  CLog::Log(LOGWARNING,"%s, Server Signature: %s",__FUNCTION__, serversig);
+  
+  SWFSize = 1774;
+  char tempSWFHash[] = "a3eddcc12a96169882f99522a0835e629ae544f2f0bbeb1de4a6ed72754ac965";
+  hex2bin(tempSWFHash, &SWFHash.av_val);
+  //SWFHash.av_val = tempSWFHash;
+  SWFHash.av_len = strlen(SWFHash.av_val);
+  
+  const char swfVerify[] = { 0x01, 0x01 };
+  char *vend = SWFVerificationResponse+sizeof(SWFVerificationResponse);
+
+  memcpy(SWFVerificationResponse, swfVerify, 2);
+  CLog::Log(LOGWARNING,"%s, SWFVerificationResponse 1: %x",__FUNCTION__, SWFVerificationResponse);
+  
+  AMF_EncodeInt32(&SWFVerificationResponse[2], vend, SWFSize);
+  AMF_EncodeInt32(&SWFVerificationResponse[6], vend, SWFSize);
+  
+  
+  CLog::Log(LOGWARNING,"%s, SWFHash.av_val: %i",__FUNCTION__, SWFHash.av_val);
+  CLog::Log(LOGWARNING,"%s, SHA256_DIGEST_LENGTH: %i",__FUNCTION__, SHA256_DIGEST_LENGTH);
+  CLog::Log(LOGWARNING,"%s, sigserv: %x",__FUNCTION__, serversig);
+  
+  HMACsha256(SWFHash.av_val, SHA256_DIGEST_LENGTH,
+	      &serversig[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH],
+	      SHA256_DIGEST_LENGTH, &SWFVerificationResponse[10]);
 
+  CLog::Log(LOGWARNING,"%s, The SWFVerificationResponse has been setup!: %x",__FUNCTION__, SWFVerificationResponse);
   return true;
 }
 
