📄 ms_license.c
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2005. All rights reserved. * */#define ALLOW_OS_CODE 1#include "rmdef/rmdef.h"#include "../include/ms_upnp.h"#include "ms_cardea.h"#include "ms_cardea_types.h"#include "wmdrmndcoreapi.h"#include "ms_tcp.h"#include "rmcore/include/rmascii.h"#include <stdio.h>static RMascii request_template[] = "POST %s HTTP/1.0\r\n" "Accept: */*\r\n" "Supported: com.microsoft.wmdrm-nd\r\n" "Content-Type: application/vnd.ms-wmdrm-license-request\r\n" "Content-Length: %ld\r\n" "\r\n";/* Maximum number of digit required to represent an unsigned 32 bits */#define MAX_U32_STR 10/* Timeout in s waiting for HTTP answer */#define LICENSE_TIMEOUT 50/* String to identify the session header in the HTTP answer */#define HEADER_SESSION "WMDRM-ND: SessionId="/* String to identify error status */#define WMDRM_ND_STATUS "WMDRM-ND-Status:" /** * Get next http header * * @param http - pointer to the message to parse (will be modified after each call) * @param http_size - size of the message (will be modified also) * @return RMascii * - pointer to the next header, NULL terminated */static RMascii * get_header(RMuint8 **http, RMuint32 *http_size){ RMuint32 i=0; RMuint8 *header = *http; for (i=0; (i+1)<(*http_size); i++){ if ( ((*http)[i] == '\r') && ((*http)[i+1] == '\n') ){ (*http)[i] = 0; *http += (i+2); if (*http_size >= (i+2)){ *http_size -= (i+2); } else { *http_size = 0; } return (RMascii *) header; } } return NULL;} /** * Parse a HTTP response, returns a pointer to the content * * @param ms_upnp - MS UPnP extension for the server we are working for * @param http - http response to parse * @param http_size - size of the http response * @param ms_error - MS error code returned in case of failure (see ms_cardea_types.h) * @return RM_OK on success */static RMstatus parse_http(struct ms_url_context_s *url_ctx, RMuint8 **http, RMuint32 *http_size, RMuint32 *ms_error){ RMascii *header; if (ms_error == NULL) return RM_ERROR; *ms_error = 0; while (*http_size > 0){ header = get_header(http, http_size); if (header == NULL) /* Error */ return RM_ERROR; if (header[0] == 0) /* End of headers, data is next */ break; RMDBGLOG((ENABLE,"Got header : %s\n", header)); if (RMNCompareAscii(header, HEADER_SESSION, RMasciiLength(HEADER_SESSION))){ /* DRM Session ID, keep it for later */ url_ctx->session_header = RMMallocAndDuplicateAscii(header); RMDBGLOG((ENABLE,"adding session header... 0x%08x\n", url_ctx->session_header)); RMDBGLOG((ENABLE,"first bytes are: %c%c%c%c%c\n", url_ctx->session_header[0], url_ctx->session_header[1], url_ctx->session_header[2], url_ctx->session_header[3], url_ctx->session_header[4])); RMDBGLOG((ENABLE," Saved session ID\n")); }else if (RMNCompareAscii(header, WMDRM_ND_STATUS, RMasciiLength(WMDRM_ND_STATUS))){ if (RMasciiLength(header) > (RMasciiLength(WMDRM_ND_STATUS)+4)){ header[RMasciiLength(WMDRM_ND_STATUS)+4] = 0; RMasciiToUInt32(header+RMasciiLength(WMDRM_ND_STATUS)+1, ms_error); } } } RMDBGLOG((ENABLE,"HTTP content : %ld bytes\n", *http_size)); if (*ms_error) return RM_ERROR; return RM_OK;}/** * Get a license for a given URL, on the given device * @param ms_upnp - MS UPnP server * @param uri - URL to get * @param session_header - returns the session header for this URL, should not * be freed or modified. * @return 0 on success, < 0 on error */RMint32 get_ms_license(ms_upnp_extension *ms_upnp, RMascii *url, RMascii **session_header){ ms_tcp_socket_t *ms_socket = NULL; RMstatus status; RMint32 rc = 0; RMuint8 *message=NULL; RMuint32 message_size; RMuint8 *answer=NULL; RMuint32 answer_size; RMuint8 *http_request = NULL; RMuint32 http_request_size; RMint32 written; RMuint32 ms_error = 0; struct ms_url_context_s *url_ctx;#if 1 #include <sys/time.h> struct timeval time0, time1; gettimeofday( &time0, NULL );#endif RMDBGLOG((ENABLE, "%s:%d - ms_upnp = %08x ms_upnp->drm_context = %08x, url = %08x\n", __FILE__, __LINE__, ms_upnp, (ms_upnp!=0)?ms_upnp->drm_context:0, url )); if (ms_upnp == NULL || ms_upnp->drm_context == NULL || url == NULL){ rc = -1; goto error; } if( find_cardea_url(url) != NULL) { RMDBGLOG((ENABLE,"We already have this license... and key to decrypt\n")); goto error; } else RMDBGLOG((ENABLE,"apparently we don't have this license... and key to decrypt\n")); RMDBGLOG((ENABLE, "Trying to create new cardea url struct...\n")); url_ctx = init_cardea_url(ms_upnp, url, NULL);// url_ctx->url = RMMallocAndDuplicateAscii(url); RMDBGLOG((ENABLE, "new url struct: 0x%08x\n", url_ctx)); RMDBGLOG((ENABLE, "new url: 0x%08x\n", url_ctx->url)); /* Get license request message */ status = get_license_request_message( ms_upnp->drm_context, url_ctx->url_hash, &message, &message_size); if (RMFAILED(status)){ RMDBGLOG((ENABLE,"Error getting license request message\n")); rc = -1; destroy_cardea_license_data(url_ctx); goto error; } else { RMDBGLOG((ENABLE,"Got %ld bytes license request message.\n", message_size)); } /* Create HTTP request */ http_request_size = RMasciiLength(request_template)+RMasciiLength(url)+MAX_U32_STR+message_size; http_request = (RMuint8 *)RMMalloc(http_request_size); if (http_request == NULL){ RMDBGLOG((ENABLE,"Error, cannot allocate http_request\n")); rc = -1; destroy_cardea_license_data(url_ctx); goto error; } written = snprintf((RMascii *)http_request, (size_t) http_request_size, request_template, url, message_size); if ((unsigned)written >= http_request_size){ RMDBGLOG((ENABLE,"Error, HTTP request too big.\n")); rc = -1; destroy_cardea_license_data(url_ctx); goto error; } RMMemcpy(http_request+written,message,message_size); /* Open the connection */ ms_socket = open_ms_tcp_socket(url); if (ms_socket == NULL){ RMDBGLOG((ENABLE,"Error opening MS socket\n")); rc = -1; destroy_cardea_license_data(url_ctx); goto error; } else { RMDBGLOG((ENABLE,"Opened MS socket\n")); } /* Send the request, receive the answer */ status = ms_tcp_send_receive(ms_socket, http_request, written+message_size, &answer, &answer_size, LICENSE_TIMEOUT); if (RMFAILED(status)){ RMDBGLOG((ENABLE,"Error sending license request\n")); rc = -1; destroy_cardea_license_data(url_ctx); goto error; } status = parse_http(url_ctx, &answer, &answer_size, &ms_error); if (RMFAILED(status)){ RMDBGLOG((ENABLE,"Error parsing HTTP : %ld\n", ms_error)); rc = -ms_error; destroy_cardea_license_data(url_ctx); goto error; } RMDBGLOG((ENABLE,"parsed http... processing license\n")); status = process_license(ms_upnp->drm_context, answer, answer_size, (RMuint8*)url, RMasciiLength(url)); if (RMFAILED(status)){ RMDBGLOG((ENABLE,"Error processing license\n")); rc = -1; url_ctx->license_present = FALSE; goto error; } url_ctx->license_present = TRUE; RMDBGLOG((ENABLE,"License OK\n"));error: if (ms_socket) close_ms_tcp_socket(ms_socket); if (http_request) RMFree(http_request); if ( message != NULL ) RMFree(message); #if 1 gettimeofday( &time1, NULL ); fprintf( stderr, "%s:%d - License rc = %d Time = %d(mS)\n", __FILE__, __LINE__, (int) rc, (int) (1000*(time1.tv_sec - time0.tv_sec) + (time1.tv_usec - time0.tv_usec) / 1000) );#endif return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -