@@ -29,6 +29,11 @@ struct shared_ptr GUID;
2929int decryptCount = 1000 ;
3030char * device_infos [9 ];
3131
32+ // Account info cache
33+ static char * g_storefront_id = NULL ;
34+ static char * g_dev_token = NULL ;
35+ static char * g_music_token = NULL ;
36+
3237#ifndef MyRelease
3338int32_t CURLOPT_SSL_VERIFYPEER = 64 ;
3439int32_t CURLOPT_SSL_VERIFYHOST = 81 ;
@@ -714,6 +719,114 @@ static inline void *new_socket_m3u8(void *args) {
714719 }
715720}
716721
722+ void handle_account (const int connfd )
723+ {
724+ char buffer [4096 ];
725+ ssize_t n = read (connfd , buffer , sizeof (buffer ) - 1 );
726+ if (n <= 0 ) {
727+ return ;
728+ }
729+ buffer [n ] = '\0' ;
730+
731+ // Parse HTTP request (simple check for GET)
732+ if (strncmp (buffer , "GET" , 3 ) != 0 && strncmp (buffer , "POST" , 4 ) != 0 ) {
733+ const char * error_response = "HTTP/1.1 400 Bad Request\r\nContent-Type: application/json\r\nContent-Length: 0\r\n\r\n" ;
734+ writefull (connfd , (void * )error_response , strlen (error_response ));
735+ return ;
736+ }
737+
738+ // Format JSON response body
739+ size_t json_size = 1024 ;
740+ char * json_body = (char * )malloc (json_size );
741+ if (json_body == NULL )
742+ {
743+ fprintf (stderr , "[.] failed to allocate memory for account response\n" );
744+ const char * error_response = "HTTP/1.1 500 Internal Server Error\r\nContent-Type: application/json\r\nContent-Length: 0\r\n\r\n" ;
745+ writefull (connfd , (void * )error_response , strlen (error_response ));
746+ return ;
747+ }
748+
749+ snprintf (json_body , json_size , "{\"storefront_id\":\"%s\",\"dev_token\":\"%s\",\"music_token\":\"%s\"}" ,
750+ g_storefront_id , g_dev_token , g_music_token );
751+
752+ int json_len = strlen (json_body );
753+
754+ // Format HTTP response with headers
755+ size_t response_size = 512 ;
756+ char * http_response = (char * )malloc (response_size );
757+ if (http_response == NULL )
758+ {
759+ fprintf (stderr , "[.] failed to allocate memory for HTTP response\n" );
760+ free (json_body );
761+ const char * error_response = "HTTP/1.1 500 Internal Server Error\r\nContent-Type: application/json\r\nContent-Length: 0\r\n\r\n" ;
762+ writefull (connfd , (void * )error_response , strlen (error_response ));
763+ return ;
764+ }
765+
766+ snprintf (http_response , response_size , "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: %d\r\nConnection: close\r\n\r\n" ,
767+ json_len );
768+
769+ fprintf (stderr , "[.] returning account info, storefront: %s\n" , g_storefront_id );
770+ writefull (connfd , http_response , strlen (http_response ));
771+ writefull (connfd , json_body , json_len );
772+
773+ free (http_response );
774+ free (json_body );
775+ }
776+
777+ static inline void * new_socket_account (void * args )
778+ {
779+ const int fd = socket (AF_INET , SOCK_STREAM | SOCK_CLOEXEC , IPPROTO_TCP );
780+ if (fd == -1 )
781+ {
782+ perror ("socket" );
783+ return NULL ;
784+ }
785+ const int optval = 1 ;
786+ setsockopt (fd , SOL_SOCKET , SO_REUSEPORT , & optval , sizeof (optval ));
787+
788+ static struct sockaddr_in serv_addr = {.sin_family = AF_INET };
789+ inet_pton (AF_INET , args_info .host_arg , & serv_addr .sin_addr );
790+ serv_addr .sin_port = htons (args_info .account_port_arg );
791+ if (bind (fd , (struct sockaddr * )& serv_addr , sizeof (serv_addr )) == -1 )
792+ {
793+ perror ("bind" );
794+ return NULL ;
795+ }
796+
797+ if (listen (fd , 5 ) == -1 )
798+ {
799+ perror ("listen" );
800+ return NULL ;
801+ }
802+
803+ fprintf (stderr , "[!] listening account info request on %s:%d\n" , args_info .host_arg , args_info .account_port_arg );
804+
805+ static struct sockaddr_in peer_addr ;
806+ static socklen_t peer_addr_size = sizeof (peer_addr );
807+ while (1 )
808+ {
809+ const int connfd = accept4 (fd , (struct sockaddr * )& peer_addr ,
810+ & peer_addr_size , SOCK_CLOEXEC );
811+ if (connfd == -1 )
812+ {
813+ if (errno == ENETDOWN || errno == EPROTO || errno == ENOPROTOOPT ||
814+ errno == EHOSTDOWN || errno == ENONET ||
815+ errno == EHOSTUNREACH || errno == EOPNOTSUPP ||
816+ errno == ENETUNREACH )
817+ continue ;
818+ perror ("accept4" );
819+ }
820+
821+ handle_account (connfd );
822+
823+ if (close (connfd ) == -1 )
824+ {
825+ perror ("close" );
826+ }
827+ }
828+ }
829+
717830char * get_account_storefront_id (struct shared_ptr reqCtx ) {
718831 union std_string * region = malloc (sizeof (union std_string ));
719832 struct shared_ptr urlbag = {.obj = 0x0 , .ctrl_blk = 0x0 };
@@ -727,11 +840,10 @@ char* get_account_storefront_id(struct shared_ptr reqCtx) {
727840 return NULL ;
728841}
729842
730- void write_storefront_id (struct shared_ptr reqCtx ) {
843+ void write_storefront_id (void ) {
731844 FILE * fp = fopen (strcat_b (args_info .base_dir_arg , "/STOREFRONT_ID" ), "w" );
732- char * storefront_id = get_account_storefront_id (reqCtx );
733- printf ("[+] StoreFront ID: %s\n" , storefront_id );
734- fprintf (fp , "%s" , get_account_storefront_id (reqCtx ));
845+ printf ("[+] StoreFront ID: %s\n" , g_storefront_id );
846+ fprintf (fp , "%s" , g_storefront_id );
735847 fclose (fp );
736848}
737849
@@ -836,7 +948,7 @@ char* get_dev_token(struct shared_ptr reqCtx) {
836948 return result ;
837949}
838950
839- void write_music_token (struct shared_ptr reqCtx ) {
951+ void write_music_token (void ) {
840952 int token_file_available = 0 ;
841953 if (file_exists (strcat_b (args_info .base_dir_arg , "/MUSIC_TOKEN" ))) {
842954 FILE * fp = fopen (strcat_b (args_info .base_dir_arg , "/MUSIC_TOKEN" ), "r" );
@@ -857,11 +969,8 @@ void write_music_token(struct shared_ptr reqCtx) {
857969 return ;
858970 }
859971 FILE * fp = fopen (strcat_b (args_info .base_dir_arg , "/MUSIC_TOKEN" ), "w" );
860- char * guid = get_guid ();
861- char * dev_token = get_dev_token (reqCtx );
862- char * token = get_music_user_token (guid , dev_token , reqCtx );
863- printf ("[+] Music-Token: %.14s...\n" , token );
864- fprintf (fp , "%s" , token );
972+ printf ("[+] Music-Token: %.14s...\n" , g_music_token );
973+ fprintf (fp , "%s" , g_music_token );
865974 fclose (fp );
866975}
867976
@@ -895,12 +1004,22 @@ int main(int argc, char *argv[]) {
8951004 _ZN22SVPlaybackLeaseManager12requestLeaseERKb (leaseMgr , & autom );
8961005 FHinstance = _ZN21SVFootHillSessionCtrl8instanceEv ();
8971006
898- write_storefront_id (ctx );
899- write_music_token (ctx );
1007+ // Cache account info
1008+ g_storefront_id = get_account_storefront_id (ctx );
1009+ g_dev_token = get_dev_token (ctx );
1010+ g_music_token = get_music_user_token (get_guid (), g_dev_token , ctx );
1011+ fprintf (stderr , "[+] account info cached successfully\n" );
1012+
1013+ write_storefront_id ();
1014+ write_music_token ();
9001015
9011016 pthread_t m3u8_thread ;
9021017 pthread_create (& m3u8_thread , NULL , & new_socket_m3u8 , NULL );
9031018 pthread_detach (m3u8_thread );
9041019
1020+ pthread_t account_thread ;
1021+ pthread_create (& account_thread , NULL , & new_socket_account , NULL );
1022+ pthread_detach (account_thread );
1023+
9051024 return new_socket ();
9061025}
0 commit comments