1 /* This file contains common process functions. */
2 #include    "tx_api.h"
3 #include    "nx_api.h"
4 
5 #if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN)
6 #include    "nx_websocket_client.h"
7 
8 #define TEST_CONNECT_GUID         "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
9 #define TEST_CONNECT_GUID_SIZE    (sizeof(TEST_CONNECT_GUID) - 1)
10 #define TEST_CONNECT_DIGEST_SIZE  20 /* The length of SHA-1 hash is 20 bytes */
11 #define TEST_CONNECT_KEY_SIZE     32 /* Make it larger than the minimum length (28 bytes )for the encoded key */
12 
13 static UCHAR   connect_key[TEST_CONNECT_KEY_SIZE];
14 static UINT    connect_key_size;
15 
_server_connect_response_process(NX_PACKET * packet_ptr)16 UINT  _server_connect_response_process(NX_PACKET *packet_ptr)
17 {
18 UCHAR  *buffer_ptr;
19 UINT    offset = 0;
20 UCHAR  *field_name;
21 UINT    field_name_length;
22 UCHAR  *field_value;
23 UINT    field_value_length;
24 NX_SHA1 SH;
25 UCHAR   digest[TEST_CONNECT_DIGEST_SIZE];
26 
27     buffer_ptr = packet_ptr -> nx_packet_prepend_ptr;
28 
29     /* Skip over the first Command line (GET /xxx HTTP/1.1\r\n).  */
30     while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) &&
31           (*buffer_ptr != '\r') && (*(buffer_ptr + 1) != '\n'))
32     {
33         buffer_ptr++;
34         offset++;
35     }
36 
37     /* Skip over the CR,LF. */
38     buffer_ptr += 2;
39     offset += 2;
40 
41     /* Skip over the first Host line (Host: xxx\r\n).  */
42     while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) &&
43           (*buffer_ptr != '\r') && (*(buffer_ptr + 1) != '\n'))
44     {
45         buffer_ptr++;
46         offset++;
47     }
48 
49     /* Skip over the CR,LF. */
50     buffer_ptr += 2;
51     offset += 2;
52 
53     /* Loop until we find the "cr,lf,cr,lf" token.  */
54     while (((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != 0))
55     {
56 
57         /* Check for the <cr,lf,cr,lf> token.  This signals a blank line, which also
58            specifies the start of the content.  */
59         if ((*buffer_ptr == '\r') &&
60             (*(buffer_ptr + 1) ==  '\n'))
61         {
62 
63             /* Adjust the offset.  */
64             offset = offset + 2;
65             break;
66         }
67 
68         /* We haven't seen the <cr,lf,cr,lf> so we are still processing header data.
69            Extract the field name and it's value.  */
70         field_name = buffer_ptr;
71         field_name_length = 0;
72 
73         /* Look for the ':' that separates the field name from its value. */
74         while(*buffer_ptr != ':')
75         {
76             buffer_ptr++;
77             field_name_length++;
78         }
79         offset += field_name_length;
80 
81         /* Skip ':'.  */
82         buffer_ptr++;
83         offset++;
84 
85         /* Now skip over white space. */
86         while ((buffer_ptr < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
87         {
88             buffer_ptr++;
89             offset++;
90         }
91 
92         /* Now get the field value. */
93         field_value = buffer_ptr;
94         field_value_length = 0;
95 
96         /* Loop until we see a <CR, LF>. */
97         while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '\r') && (*(buffer_ptr+1) != '\n'))
98         {
99             buffer_ptr++;
100             field_value_length++;
101         }
102         offset += field_value_length;
103 
104         /* Skip over the CR,LF. */
105         buffer_ptr += 2;
106         offset += 2;
107 
108         /* Check the upgrade.  */
109         if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Upgrade", sizeof("Upgrade") - 1) == NX_SUCCESS)
110         {
111             if (_nx_websocket_client_name_compare((UCHAR *)field_value, field_value_length, (UCHAR *)"websocket", sizeof("websocket") - 1))
112             {
113                 return(NX_WEBSOCKET_INVALID_PACKET);
114             }
115         }
116         else if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Connection", sizeof("Connection") - 1) == NX_SUCCESS)
117         {
118             if (_nx_websocket_client_name_compare((UCHAR *)field_value, field_value_length, (UCHAR *)"Upgrade", sizeof("Upgrade") - 1))
119             {
120                 return(NX_WEBSOCKET_INVALID_PACKET);
121             }
122         }
123         else if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Sec-WebSocket-Key", sizeof("Sec-WebSocket-Key") - 1) == NX_SUCCESS)
124         {
125 
126             /* Calculate the SHA-1 hash of the concatenation of the client key and the Globally Unique Identifier (GUID)
127                Referenced in RFC 6455, Section 1.3, Page 6 */
128             _nx_sha1_initialize(&SH);
129             _nx_sha1_update(&SH, field_value, field_value_length);
130             _nx_sha1_update(&SH, (UCHAR*)TEST_CONNECT_GUID, TEST_CONNECT_GUID_SIZE);
131             _nx_sha1_digest_calculate(&SH, digest);
132 
133             /* Encode the hash and compare it with the field value from the server.  */
134             _nx_utility_base64_encode(digest, TEST_CONNECT_DIGEST_SIZE, connect_key, TEST_CONNECT_KEY_SIZE, &connect_key_size);
135         }
136     }
137 
138     /* Check if the all fields are processed.  */
139     if (offset != packet_ptr -> nx_packet_length)
140     {
141         return(NX_WEBSOCKET_INVALID_PACKET);
142     }
143 
144     return(NX_SUCCESS);
145 }
146 
147 #endif
148 
SET_ERROR_COUNTER(ULONG * error_counter,CHAR * filename,int line_number)149 void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number)
150 {
151     *error_counter = (*error_counter) + 1;
152 
153     printf("Error: File %s:%d\n", filename, line_number);
154 }
155 
156