Add support for IPv6

This commit is contained in:
Yuval Tal
2011-05-29 08:30:03 +03:00
parent 88a5a4ee27
commit e0e8a09ccb
2 changed files with 25 additions and 68 deletions
+23 -65
View File
@@ -305,11 +305,13 @@ void handleClient(int pSock, char *pPassword, char *pHWADDR)
socklen_t len;
struct sockaddr_storage addr;
#ifdef AF_INET6
char ipstr[INET6_ADDRSTRLEN];
unsigned char ipbin[INET6_ADDRSTRLEN];
#else
char ipstr[INET_ADDRSTRLEN];
unsigned char ipbin[INET_ADDRSTRLEN];
#endif
unsigned int ipbinlen;
int port;
char ipstr[64];
len = sizeof addr;
getsockname(pSock, (struct sockaddr*)&addr, &len);
@@ -320,11 +322,15 @@ void handleClient(int pSock, char *pPassword, char *pHWADDR)
struct sockaddr_in *s = (struct sockaddr_in *)&addr;
port = ntohs(s->sin_port);
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
memcpy(ipbin, &s->sin_addr, 4);
ipbinlen = 4;
} else { // AF_INET6
slog(LOG_DEBUG_V, "Constructing ipv6 address\n");
struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
port = ntohs(s->sin6_port);
inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
memcpy(ipbin, &s->sin6_addr, 16);
ipbinlen = 16;
}
slog(LOG_DEBUG_V, "Peer IP address: %s\n", ipstr);
@@ -351,7 +357,7 @@ void handleClient(int pSock, char *pPassword, char *pHWADDR)
{
slog(LOG_DEBUG_VV, "Finished Reading some data from client\n");
// parse client request
tMoreDataNeeded = parseMessage(&tConn, ipstr, pHWADDR);
tMoreDataNeeded = parseMessage(&tConn, ipbin, ipbinlen, pHWADDR);
if(1 == tMoreDataNeeded)
{
slog(LOG_DEBUG_VV, "\n\nNeed to read more data\n");
@@ -391,43 +397,6 @@ void writeDataToClient(int pSock, struct shairbuffer *pResponse)
slog(LOG_DEBUG_VV, "----Send Response Header----\n");
}
void convertIpToBinary(char *tSockethost, int pIsIPv6, char* pIpBinary)
{
if(pIsIPv6)
{
// do something different
slog(LOG_INFO, " Must implement ipv6 signature portion in convertIpToBinary...sorry.\n");
}
else
{
// Takes care of ipv4 addresses like ::ffff:192.168.1.3
char *tStartOfV4 = strrchr(tSockethost, ':');
if(NULL == tStartOfV4)
{
tStartOfV4 = tSockethost;
}
else
{
tStartOfV4+=1;
}
char tIp[strlen(tStartOfV4)+1];
memset(tIp, 0, (strlen(tStartOfV4)+1));
strncpy(tIp, tStartOfV4, strlen(tStartOfV4));
char *tIpTokens = strtok (tIp, ".");
int tIdx = 0;
// if ipv4, discard prefill
while(tIpTokens != NULL)
{
slog(LOG_DEBUG_VV, "%s\n", tIpTokens);
pIpBinary[tIdx++] = atoi(tIpTokens);
tIpTokens = strtok(NULL, " .");
}
}
}
int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer)
{
char tReadBuf[MAX_SIZE];
@@ -466,7 +435,7 @@ int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer)
}
else
{
slog(LOG_DEBUG, "Error reading data from socket.\n");
slog(LOG_DEBUG, "Error reading data from socket, got: %d bytes", tRetval);
return tRetval;
}
}
@@ -533,53 +502,42 @@ char *getFromSetup(char *pContentPtr, const char* pField, int *pReturnSize)
// Handles compiling the Apple-Challenge, HWID, and Server IP Address
// Into the response the airplay client is expecting.
int buildAppleResponse(struct connection *pConn, char *pIpStr, char *pHWID)
int buildAppleResponse(struct connection *pConn, unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWID)
{
// Find Apple-Challenge
char *tResponse = NULL;
int tFoundSize = 0;
char* tFound = getFromHeader(pConn->recv.data, "Apple-Challenge", &tFoundSize);
if(tFound != NULL)
{
char tTrim[tFoundSize + 2];
getTrimmed(tFound, tFoundSize, TRUE, TRUE, tTrim);
slog(LOG_DEBUG_VV, "HeaderChallenge: [%s] len: %d sizeFound: %d\n", tTrim, strlen(tTrim), tFoundSize);
int tChallengeDecodeSize = 16;
char *tTmp = NULL;
char *tChallenge = decode_base64((unsigned char *)tTrim, tFoundSize, &tChallengeDecodeSize);
slog(LOG_DEBUG_VV, "Challenge Decode size: %d expected 16\n", tChallengeDecodeSize);
char tIpAddress[4];
convertIpToBinary(pIpStr, FALSE, tIpAddress);
int tIpSize = 4;
if(FALSE)
{
// TODO - Handle/Test on IPV6
tIpSize = 6; // IPV6
}
tTmp = encode_base64((unsigned char *) tIpAddress, tIpSize);
slog(LOG_DEBUG_VV, "IPDATA: %s => %s\n", pIpStr, tTmp);
free(tTmp);
int tCurSize = 0;
unsigned char tChalResp[32];
unsigned char tChalResp[38];
memcpy(tChalResp, tChallenge, tChallengeDecodeSize);
tCurSize += tChallengeDecodeSize;
memcpy(tChalResp+tCurSize, tIpAddress, tIpSize);
tCurSize += tIpSize;
memcpy(tChalResp+tCurSize, pIpBin, pIpBinLen);
tCurSize += pIpBinLen;
memcpy(tChalResp+tCurSize, pHWID, HWID_SIZE);
tCurSize += HWID_SIZE;
int tPad = 32 - tCurSize;
memset(tChalResp+tCurSize, 0, tPad);
if (tPad > 0)
{
memset(tChalResp+tCurSize, 0, tPad);
tCurSize += tPad;
}
tTmp = encode_base64((unsigned char *)tChalResp, 32);
char *tTmp = encode_base64((unsigned char *)tChalResp, tCurSize);
slog(LOG_DEBUG_VV, "Full sig: %s\n", tTmp);
free(tTmp);
@@ -587,7 +545,7 @@ int buildAppleResponse(struct connection *pConn, char *pIpStr, char *pHWID)
RSA *rsa = loadKey(); // Free RSA
int tSize = RSA_size(rsa);
unsigned char tTo[tSize];
RSA_private_encrypt(32, (unsigned char *)tChalResp, tTo, rsa, RSA_PKCS1_PADDING);
RSA_private_encrypt(tCurSize, (unsigned char *)tChalResp, tTo, rsa, RSA_PKCS1_PADDING);
// Wrap RSA Encrypted binary in Base64 encoding
tResponse = encode_base64(tTo, tSize);
@@ -613,7 +571,7 @@ int buildAppleResponse(struct connection *pConn, char *pIpStr, char *pHWID)
}
//parseMessage(tConn->recv.data, tConn->recv.mark, &tConn->resp, ipstr, pHWADDR, tConn->keys);
int parseMessage(struct connection *pConn, char *pIpStr, char *pHWID)
int parseMessage(struct connection *pConn, unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWID)
{
int tReturn = 0; // 0 = good, 1 = Needs More Data, -1 = close client socket.
if(pConn->resp.data == NULL)
@@ -663,7 +621,7 @@ int parseMessage(struct connection *pConn, char *pIpStr, char *pHWID)
}
if(buildAppleResponse(pConn, pIpStr, pHWID)) // need to free sig
if(buildAppleResponse(pConn, pIpBin, pIpBinLen, pHWID)) // need to free sig
{
slog(LOG_DEBUG_V, "Added AppleResponse to Apple-Challenge request\n");
}
+2 -3
View File
@@ -66,7 +66,7 @@ void addToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf);
void addNToShairBuffer(struct shairbuffer *pBuf, char *pNewBuf, int pNofNewBuf);
int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer);
int parseMessage(struct connection *pConn, char *pIpStr, char *pHWADDR);
int parseMessage(struct connection *pConn,unsigned char *pIpBin, unsigned int pIpBinLen, char *pHWADDR);
void closePipe(int *pPipe);
void setKeys(struct keyring *pKeys, char *pIV, char* pAESKey, char *pFmtp);
@@ -75,8 +75,7 @@ void initConnection(struct connection *pConn, struct keyring *pKeys,
void writeDataToClient(int pSock, struct shairbuffer *pResponse);
void propogateCSeq(struct connection *pConn);
void convertIpToBinary(char *pIpAddress, int pIsIPv6, char *pBinaryOutput);
int buildAppleResponse(struct connection *pConn, char *pIpStr, char *pHwAddr);
int buildAppleResponse(struct connection *pConn, unsigned char *pIpBin, unsigned int pIpBinLen, char *pHwAddr);
void sim(int pLevel, char *pValue1, char *pValue2);
void slog(int pLevel, char *pFormat, ...);
int isLogEnabledFor(int pLevel);