File indexing completed on 2025-02-23 04:27:36

0001 /* Copyright (C) 2004 David Hammerton <david@crazney.net>
0002  *
0003  * Permission is hereby granted, free of charge, to any person
0004  * obtaining a copy of this software and associated documentation
0005  * files (the "Software"), to deal in the Software without
0006  * restriction, including without limitation the rights to use,
0007  * copy, modify, merge, publish, distribute, sublicense, and/or
0008  * sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be
0012  * included in all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0015  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
0016  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0017  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
0018  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
0019  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0021  * OTHER DEALINGS IN THE SOFTWARE.
0022  *
0023  */
0024 
0025 #include <stdio.h>
0026 #include <string.h>
0027 #include "hasher.h"
0028 #include "md5.h"
0029 
0030 static int staticHashDone = 0;
0031 static unsigned char staticHash_42[256*65] = {0};
0032 static unsigned char staticHash_45[256*65] = {0};
0033 
0034 static const unsigned char hexchars[] = "0123456789ABCDEF";
0035 static const char appleCopyright[] = "Copyright 2003 Apple Computer, Inc.";
0036 
0037 static size_t ustrlen(const unsigned char * str) {
0038 
0039     size_t i;
0040     for (i = 0; str[i] != '\0'; ++i) ;
0041     return i;
0042 }
0043 
0044 static void DigestToString(const unsigned char *digest, unsigned char *string)
0045 {
0046     int i;
0047     for (i = 0; i < 16; ++i)
0048     {
0049         unsigned char tmp = digest[i];
0050         string[i*2+1] = hexchars[tmp & 0x0f];
0051         string[i*2] = hexchars[(tmp >> 4) & 0x0f];
0052     }
0053 }
0054 
0055 static void GenerateStatic_42()
0056 {
0057     MD5_CTX ctx;
0058     unsigned char *p = staticHash_42;
0059     int i;
0060     unsigned char buf[16];
0061 
0062     for (i = 0; i < 256; ++i)
0063     {
0064         OpenDaap_MD5Init(&ctx, 0);
0065 
0066 #define MD5_STRUPDATE(str) OpenDaap_MD5Update(&ctx, (const unsigned char*) str, strlen(str))
0067 
0068         if ((i & 0x80) != 0)
0069             MD5_STRUPDATE("Accept-Language");
0070         else
0071             MD5_STRUPDATE("user-agent");
0072 
0073         if ((i & 0x40) != 0)
0074             MD5_STRUPDATE("max-age");
0075         else
0076             MD5_STRUPDATE("Authorization");
0077 
0078         if ((i & 0x20) != 0)
0079             MD5_STRUPDATE("Client-DAAP-Version");
0080         else
0081             MD5_STRUPDATE("Accept-Encoding");
0082 
0083         if ((i & 0x10) != 0)
0084             MD5_STRUPDATE("daap.protocolversion");
0085         else
0086             MD5_STRUPDATE("daap.songartist");
0087 
0088         if ((i & 0x08) != 0)
0089             MD5_STRUPDATE("daap.songcomposer");
0090         else
0091             MD5_STRUPDATE("daap.songdatemodified");
0092 
0093         if ((i & 0x04) != 0)
0094             MD5_STRUPDATE("daap.songdiscnumber");
0095         else
0096             MD5_STRUPDATE("daap.songdisabled");
0097 
0098         if ((i & 0x02) != 0)
0099             MD5_STRUPDATE("playlist-item-spec");
0100         else
0101             MD5_STRUPDATE("revision-number");
0102 
0103         if ((i & 0x01) != 0)
0104             MD5_STRUPDATE("session-id");
0105         else
0106             MD5_STRUPDATE("content-codes");
0107 #undef MD5_STRUPDATE
0108 
0109         OpenDaap_MD5Final(&ctx, buf);
0110         DigestToString(buf, p);
0111         p += 65;
0112     }
0113 }
0114 
0115 static void GenerateStatic_45()
0116 {
0117     MD5_CTX ctx;
0118     unsigned char *p = staticHash_45;
0119     int i;
0120     unsigned char buf[16];
0121 
0122     for (i = 0; i < 256; ++i)
0123     {
0124         OpenDaap_MD5Init(&ctx, 1);
0125 
0126 #define MD5_STRUPDATE(str) OpenDaap_MD5Update(&ctx, (const unsigned char*) str, strlen(str))
0127 
0128         if ((i & 0x40) != 0)
0129             MD5_STRUPDATE("eqwsdxcqwesdc");
0130         else
0131             MD5_STRUPDATE("op[;lm,piojkmn");
0132 
0133         if ((i & 0x20) != 0)
0134             MD5_STRUPDATE("876trfvb 34rtgbvc");
0135         else
0136             MD5_STRUPDATE("=-0ol.,m3ewrdfv");
0137 
0138         if ((i & 0x10) != 0)
0139             MD5_STRUPDATE("87654323e4rgbv ");
0140         else
0141             MD5_STRUPDATE("1535753690868867974342659792");
0142 
0143         if ((i & 0x08) != 0)
0144             MD5_STRUPDATE("Song Name");
0145         else
0146             MD5_STRUPDATE("DAAP-CLIENT-ID:");
0147 
0148         if ((i & 0x04) != 0)
0149             MD5_STRUPDATE("111222333444555");
0150         else
0151             MD5_STRUPDATE("4089961010");
0152 
0153         if ((i & 0x02) != 0)
0154             MD5_STRUPDATE("playlist-item-spec");
0155         else
0156             MD5_STRUPDATE("revision-number");
0157 
0158         if ((i & 0x01) != 0)
0159             MD5_STRUPDATE("session-id");
0160         else
0161             MD5_STRUPDATE("content-codes");
0162 
0163         if ((i & 0x80) != 0)
0164             MD5_STRUPDATE("IUYHGFDCXWEDFGHN");
0165         else
0166             MD5_STRUPDATE("iuytgfdxwerfghjm");
0167 
0168 #undef MD5_STRUPDATE
0169 
0170         OpenDaap_MD5Final(&ctx, buf);
0171         DigestToString(buf, p);
0172         p += 65;
0173     }
0174 }
0175 
0176 void GenerateHash(short version_major,
0177                   const unsigned char *url, unsigned char hashSelect,
0178                   unsigned char *outhash,
0179                   int request_id)
0180 {
0181     unsigned char buf[16];
0182     MD5_CTX ctx;
0183 
0184     unsigned char *hashTable = (version_major == 3) ?
0185                               staticHash_45 : staticHash_42;
0186 
0187     if (!staticHashDone)
0188     {
0189         GenerateStatic_42();
0190         GenerateStatic_45();
0191         staticHashDone = 1;
0192     }
0193 
0194     OpenDaap_MD5Init(&ctx, (version_major == 3) ? 1 : 0);
0195 
0196     OpenDaap_MD5Update(&ctx, url, ustrlen(url));
0197     OpenDaap_MD5Update(&ctx, (const unsigned char*) appleCopyright, strlen(appleCopyright));
0198 
0199     OpenDaap_MD5Update(&ctx, &hashTable[hashSelect * 65], 32);
0200 
0201     if (request_id && version_major == 3)
0202     {
0203         char scribble[20];
0204         sprintf(scribble, "%u", request_id);
0205         OpenDaap_MD5Update(&ctx, (unsigned char*) scribble, strlen(scribble));
0206     }
0207 
0208     OpenDaap_MD5Final(&ctx, buf);
0209     DigestToString(buf, outhash);
0210 }
0211