Adds an alternative startup, that eliminates the need for Perl.
Requires airport.pem to load the airplay key.
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEA59dE8qLieItsH1WgjrcFRKj6eUWqi+bGLOX1HL3U3GhC/j0Qg90u3sG/1CUt
|
||||
wC5vOYvfDmFI6oSFXi5ELabWJmT2dKHzBJKa3k9ok+8t9ucRqMd6DZHJ2YCCLlDRKSKv6kDqnw4U
|
||||
wPdpOMXziC/AMj3Z/lUVX1G7WSHCAWKf1zNS1eLvqr+boEjXuBOitnZ/bDzPHrTOZz0Dew0uowxf
|
||||
/+sG+NCK3eQJVxqcaJ/vEHKIVd2M+5qL71yJQ+87X6oV3eaYvt3zWZYD6z5vYTcrtij2VZ9Zmni/
|
||||
UAaHqn9JdsBWLUEpVviYnhimNVvYFZeCXg/IdTQ+x4IRdiXNv5hEewIDAQABAoIBAQDl8Axy9XfW
|
||||
BLmkzkEiqoSwF0PsmVrPzH9KsnwLGH+QZlvjWd8SWYGN7u1507HvhF5N3drJoVU3O14nDY4TFQAa
|
||||
LlJ9VM35AApXaLyY1ERrN7u9ALKd2LUwYhM7Km539O4yUFYikE2nIPscEsA5ltpxOgUGCY7b7ez5
|
||||
NtD6nL1ZKauw7aNXmVAvmJTcuPxWmoktF3gDJKK2wxZuNGcJE0uFQEG4Z3BrWP7yoNuSK3dii2jm
|
||||
lpPHr0O/KnPQtzI3eguhe0TwUem/eYSdyzMyVx/YpwkzwtYL3sR5k0o9rKQLtvLzfAqdBxBurciz
|
||||
aaA/L0HIgAmOit1GJA2saMxTVPNhAoGBAPfgv1oeZxgxmotiCcMXFEQEWflzhWYTsXrhUIuz5jFu
|
||||
a39GLS99ZEErhLdrwj8rDDViRVJ5skOp9zFvlYAHs0xh92ji1E7V/ysnKBfsMrPkk5KSKPrnjndM
|
||||
oPdevWnVkgJ5jxFuNgxkOLMuG9i53B4yMvDTCRiIPMQ++N2iLDaRAoGBAO9v//mU8eVkQaoANf0Z
|
||||
oMjW8CN4xwWA2cSEIHkd9AfFkftuv8oyLDCG3ZAf0vrhrrtkrfa7ef+AUb69DNggq4mHQAYBp7L+
|
||||
k5DKzJrKuO0r+R0YbY9pZD1+/g9dVt91d6LQNepUE/yY2PP5CNoFmjedpLHMOPFdVgqDzDFxU8hL
|
||||
AoGBANDrr7xAJbqBjHVwIzQ4To9pb4BNeqDndk5Qe7fT3+/H1njGaC0/rXE0Qb7q5ySgnsCb3DvA
|
||||
cJyRM9SJ7OKlGt0FMSdJD5KG0XPIpAVNwgpXXH5MDJg09KHeh0kXo+QA6viFBi21y340NonnEfdf
|
||||
54PX4ZGS/Xac1UK+pLkBB+zRAoGAf0AY3H3qKS2lMEI4bzEFoHeK3G895pDaK3TFBVmD7fV0Zhov
|
||||
17fegFPMwOII8MisYm9ZfT2Z0s5Ro3s5rkt+nvLAdfC/PYPKzTLalpGSwomSNYJcB9HNMlmhkGzc
|
||||
1JnLYT4iyUyx6pcZBmCd8bD0iwY/FzcgNDaUmbX9+XDvRA0CgYEAkE7pIPlE71qvfJQgoA9em0gI
|
||||
LAuE4Pu13aKiJnfft7hIjbK+5kyb3TysZvoyDnb3HOKvInK7vXbKuU4ISgxB2bB3HcYzQMGsz1qJ
|
||||
2gG0N5hvJpzwwhbhXqFKA4zaaSrw622wDniAK5MlIE0tIAKKP4yxNGjoD2QYjhBGuhvkWKaXTyY=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
+1141
File diff suppressed because it is too large
Load Diff
+79
@@ -0,0 +1,79 @@
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "unistd.h"
|
||||
#include "openssl/bio.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include "openssl/err.h"
|
||||
#include "socketlib.h"
|
||||
#include "regex.h"
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
|
||||
#define DONT_USE_HAIRTUNES_MAIN
|
||||
#define HWID_SIZE 6
|
||||
#define SHAIRPORT_LOG 1
|
||||
#define LOG_INFO 1
|
||||
#define LOG_DEBUG 5
|
||||
#define LOG_DEBUG_V 6
|
||||
#define LOG_DEBUG_VV 7
|
||||
|
||||
struct shairbuffer
|
||||
{
|
||||
char *data;
|
||||
int current;
|
||||
int maxsize;
|
||||
int marker;
|
||||
};
|
||||
|
||||
struct keyring
|
||||
{
|
||||
char *aeskey;
|
||||
char *aesiv;
|
||||
char *fmt;
|
||||
};
|
||||
|
||||
struct comms
|
||||
{
|
||||
int in[2];
|
||||
int out[2];
|
||||
};
|
||||
|
||||
struct connection
|
||||
{
|
||||
struct shairbuffer recv;
|
||||
struct shairbuffer resp;
|
||||
struct keyring *keys; // Does not point to malloc'd memory.
|
||||
struct comms *hairtunes;
|
||||
int clientSocket;
|
||||
char *password;
|
||||
};
|
||||
|
||||
RSA *loadKey();
|
||||
int startAvahi(const char *pHwAddr, const char *pServerName, int pPort);
|
||||
void cleanupBuffers(struct connection *pConnection);
|
||||
void cleanup(struct connection *pConnection);
|
||||
void handleClient(int pSock, char *pPassword, char *pHWADDR);
|
||||
int getAvailChars(struct shairbuffer *pBuf);
|
||||
|
||||
char *getTrimmedMalloc(char *pChar, int pSize, int pEndStr, int pAddNL);
|
||||
char *getTrimmed(char *pChar, int pSize, int pEndStr, int pAddNL, char *pTrimDest);
|
||||
void initBuffer(struct shairbuffer *pBuf, int pNumChars);
|
||||
void printBufferInfo(struct shairbuffer *pBuf, int pLevel);
|
||||
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);
|
||||
|
||||
void closePipe(int *pPipe);
|
||||
void setKeys(struct keyring *pKeys, char *pIV, char* pAESKey, char *pFmtp);
|
||||
void initConnection(struct connection *pConn, struct keyring *pKeys,
|
||||
struct comms *pComms, int pSocket, char *pPassword);
|
||||
|
||||
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);
|
||||
void sim(int pLevel, char *pValue1, char *pValue2);
|
||||
void slog(int pLevel, char *pFormat, ...);
|
||||
int isLogEnabledFor(int pLevel);
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Socket Library - Common socket functions, based on stevens networking book.
|
||||
* Copyright (c) M. Andrew Webster 2011
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "socketlib.h"
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
|
||||
int common_setup(struct addrinfo *pAddrInfo)
|
||||
{
|
||||
int tSock;
|
||||
//printAddrs(pAddrInfo);
|
||||
tSock = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, 0);
|
||||
|
||||
return tSock;
|
||||
}
|
||||
|
||||
int setup_client(struct addrinfo *server_host)
|
||||
{
|
||||
int tSockDesc = -1;
|
||||
int tIdx = 0;
|
||||
|
||||
while(tIdx++ < RETRY_COUNT)
|
||||
{
|
||||
tSockDesc = common_setup(server_host);
|
||||
if (tSockDesc < 0 && tIdx >= RETRY_COUNT)
|
||||
{
|
||||
perror("Error: Could not create socket");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (connect(tSockDesc, server_host->ai_addr, server_host->ai_addrlen) >= 0)
|
||||
{
|
||||
return tSockDesc;
|
||||
}
|
||||
else
|
||||
{
|
||||
close(tSockDesc);
|
||||
perror("Error: Could not connect to server");
|
||||
struct timeval tRes;
|
||||
delay(RETRY_DELAY, &tRes);
|
||||
}
|
||||
}
|
||||
printf("%d Retry attempts exceeded\n", RETRY_COUNT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
int getAddr(char *pHostname, char *pService, int pFamily, int pSockType, struct addrinfo **pAddrInfo)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
int tError = 0;
|
||||
memset(&hints, 0 , sizeof(hints));
|
||||
|
||||
hints.ai_family = pFamily;
|
||||
hints.ai_socktype = pSockType;
|
||||
if(pHostname == NULL)
|
||||
{
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
}
|
||||
|
||||
tError = getaddrinfo(pHostname, pService, &hints, pAddrInfo);
|
||||
if(tError != 0)
|
||||
{
|
||||
printf("Error getting address info\n");
|
||||
}
|
||||
return tError;
|
||||
}
|
||||
|
||||
int setup_server(struct addrinfo *server_addr)
|
||||
{
|
||||
int tSock = common_setup(server_addr);
|
||||
if (tSock < 0)
|
||||
{
|
||||
perror("Error: Could not create server socket");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
int tEnable = 1;
|
||||
setsockopt(tSock, SOL_SOCKET, SO_REUSEADDR, &tEnable, sizeof (tEnable));
|
||||
if (bind(tSock, server_addr->ai_addr, server_addr->ai_addrlen) < 0)
|
||||
{
|
||||
close(tSock);
|
||||
perror("Error: Could not bind socket");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (listen(tSock, 5) < 0)
|
||||
{
|
||||
close(tSock);
|
||||
perror("Error: Unable to listen on server socket");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return tSock;
|
||||
}
|
||||
|
||||
|
||||
int acceptClient(int pSock, struct addrinfo *server_addr)
|
||||
{
|
||||
int tAccept = accept(pSock, server_addr->ai_addr, &server_addr->ai_addrlen);
|
||||
// close the listen socket. Not expecting any more clients.
|
||||
if (tAccept < 0)
|
||||
{
|
||||
perror("Error: Unable to accept connection to server socket");
|
||||
return ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("..Accepted on socket: %d\n", tAccept);
|
||||
}
|
||||
return tAccept;
|
||||
}
|
||||
|
||||
int setupListenServer(struct addrinfo **pAddrInfo, int pPort)
|
||||
{
|
||||
char tService[SERVLEN];
|
||||
sprintf(tService, "%d", pPort); // copies port to string
|
||||
int tFamily = AF_INET;
|
||||
#ifdef AF_INET6
|
||||
//printf("Listening on IPv6 Socket\n");
|
||||
tFamily = AF_INET6;
|
||||
#else
|
||||
//printf("Listening on IPv4 Socket");
|
||||
#endif
|
||||
if(getAddr(NULL, tService, tFamily, SOCK_STREAM, pAddrInfo))
|
||||
{
|
||||
return ERROR; // getAddr prints out error message
|
||||
}
|
||||
|
||||
int tSocketDescriptor = setup_server(*pAddrInfo);
|
||||
char tAddr[INET6_ADDRSTRLEN];
|
||||
socklen_t tSize = INET6_ADDRSTRLEN;
|
||||
inet_ntop((*pAddrInfo)->ai_family, (*pAddrInfo)->ai_addr, tAddr, tSize);
|
||||
//printf("Size is: %d\n", tSize);
|
||||
return tSocketDescriptor;
|
||||
}
|
||||
|
||||
void delay(long pMillisecs, struct timeval *pRes)
|
||||
{
|
||||
pRes->tv_sec = pMillisecs / 1000;
|
||||
pRes->tv_usec = (pMillisecs - (pRes->tv_sec * 1000)) * 1000;
|
||||
select(0,NULL,NULL,NULL,pRes);
|
||||
}
|
||||
|
||||
// From http://www.ioncannon.net/programming/34/howto-base64-encode-with-cc-and-openssl/
|
||||
|
||||
//int main(int argc, char **argv)
|
||||
//{
|
||||
// char *output = decode_base64("WU9ZTyEA\n\0", strlen("WU9ZTyEA\n\0"));
|
||||
// printf("Unbase64: *%s*\n", output);
|
||||
// free(output);/
|
||||
//}
|
||||
|
||||
char *decode_base64(unsigned char *input, int length, int *pActualLength)
|
||||
{
|
||||
// Needs All no_no flags for proper RSA AES KEY Descrypt
|
||||
BIO *b64, *bmem;
|
||||
|
||||
char *buffer = (char *)malloc(length);
|
||||
memset(buffer, 0, length);
|
||||
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
bmem = BIO_new_mem_buf(input, length);
|
||||
BIO_set_flags(bmem, BIO_FLAGS_BASE64_NO_NL);
|
||||
bmem = BIO_push(b64, bmem);
|
||||
|
||||
BIO_set_flags(bmem, BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
*pActualLength = BIO_read(bmem, buffer, length);
|
||||
|
||||
BIO_free_all(bmem);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *encode_base64(unsigned char *input, int length)
|
||||
{
|
||||
BIO *bmem, *b64;
|
||||
BUF_MEM *bptr;
|
||||
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
// This enables/disables nls
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
bmem = BIO_new(BIO_s_mem());
|
||||
|
||||
b64 = BIO_push(b64, bmem);
|
||||
|
||||
BIO_write(b64, input, length);
|
||||
BIO_flush(b64);
|
||||
BIO_get_mem_ptr(b64, &bptr);
|
||||
|
||||
char *buff = (char *)malloc(bptr->length);
|
||||
memcpy(buff, bptr->data, bptr->length-1);
|
||||
buff[bptr->length-1] = 0;
|
||||
|
||||
BIO_free_all(b64);
|
||||
|
||||
return buff;
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/* Name: M. Andrew Webster
|
||||
* Based on stevens networking book
|
||||
* Description: function prototypes for socket library
|
||||
*/
|
||||
|
||||
#ifndef _SOCKETLIB_H
|
||||
#define _SOCKETLIB_H
|
||||
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#define MAX_SIZE 8192
|
||||
#define PORT 5000
|
||||
#define RETRY_COUNT 7
|
||||
#define SERVLEN 80
|
||||
#define RETRY_DELAY 1000
|
||||
|
||||
#define ERROR -1
|
||||
#define DEFAULT_IP "127.0.0.1"
|
||||
#define DEFAULT_UNIX "/unix"
|
||||
|
||||
int setup_client(struct addrinfo *server_info);
|
||||
int setup_server(struct addrinfo *server_address);
|
||||
int setupListenServer(struct addrinfo **pAddrInfo, int pPort);
|
||||
int acceptClient(int pSock, struct addrinfo *server_addr);
|
||||
void delay(long pMillisecs, struct timeval *pRes);
|
||||
int getAddr(char *pHostname, char *pService, int pFamily, int pSockType, struct addrinfo **pAddrInfo);
|
||||
|
||||
// All calls to decode and encode need to be freed
|
||||
char *decode_base64(unsigned char *input, int length, int *tActualLength);
|
||||
// All calls to decode and encode need to be freed
|
||||
char *encode_base64(unsigned char *input, int length);
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user