@@ -1005,58 +1005,92 @@ static flb_sds_t clean_token_string(flb_sds_t input)
10051005 return input ;
10061006}
10071007
1008-
10091008static int parse_federation_response (flb_sds_t response ,
10101009 struct oci_security_token * token )
10111010{
1012- cJSON * json = NULL ;
1013- cJSON * token_item = NULL ;
1011+ jsmn_parser parser ;
1012+ jsmntok_t * tokens ;
1013+ int tok_size = 32 ;
1014+ int ret , i ;
1015+ char * key ;
1016+ char * val ;
1017+ int key_len ;
1018+ int val_len ;
10141019
10151020 if (!response || !token ) {
10161021 return -1 ;
10171022 }
10181023
1019- json = cJSON_Parse (response );
1020- if (!json ) {
1021- return -1 ;
1022- }
1024+ jsmn_init (& parser );
10231025
1024- token_item = cJSON_GetObjectItem (json , "token" );
1025- if (!token_item || !cJSON_IsString (token_item )) {
1026- cJSON_Delete (json );
1026+ tokens = flb_calloc (1 , sizeof (jsmntok_t ) * tok_size );
1027+ if (!tokens ) {
10271028 return -1 ;
10281029 }
10291030
1030- const char * token_str = cJSON_GetStringValue (token_item );
1031- if (!token_str ) {
1032- cJSON_Delete (json );
1033- return -1 ;
1034- }
1031+ ret =
1032+ jsmn_parse (& parser , response , flb_sds_len (response ), tokens ,
1033+ tok_size );
10351034
1036- flb_sds_t raw_token = flb_sds_create (token_str );
1037- if (!raw_token ) {
1038- cJSON_Delete (json );
1035+ if (ret == JSMN_ERROR_INVAL || ret == JSMN_ERROR_PART ) {
1036+ flb_free (tokens );
10391037 return -1 ;
10401038 }
1039+ tok_size = ret ;
1040+ for (i = 1 ; i < tok_size ; i ++ ) {
1041+ if (tokens [i ].type != JSMN_STRING ) {
1042+ continue ;
1043+ }
10411044
1042- if (!clean_token_string (raw_token )) {
1043- flb_sds_destroy (raw_token );
1044- cJSON_Delete (json );
1045- return -1 ;
1046- }
1045+ key = response + tokens [i ].start ;
1046+ key_len = tokens [i ].end - tokens [i ].start ;
1047+
1048+ if (key_len == 5 && strncmp (key , "token" , 5 ) == 0 ) {
1049+ i ++ ;
1050+ if (i >= tok_size || tokens [i ].type != JSMN_STRING ) {
1051+ flb_free (tokens );
1052+ return -1 ;
1053+ }
1054+
1055+ val = response + tokens [i ].start ;
1056+ val_len = tokens [i ].end - tokens [i ].start ;
10471057
1048- if (token ) {
1049- flb_sds_destroy (token -> token );
1058+ flb_sds_t raw_token = flb_sds_create_len (val , val_len );
1059+ if (!raw_token ) {
1060+ flb_free (tokens );
1061+ return -1 ;
1062+ }
1063+
1064+ if (!clean_token_string (raw_token )) {
1065+ flb_sds_destroy (raw_token );
1066+ flb_free (tokens );
1067+ return -1 ;
1068+ }
1069+
1070+ if (token -> token ) {
1071+ flb_sds_destroy (token -> token );
1072+ }
1073+ token -> token = raw_token ;
1074+
1075+ flb_free (tokens );
1076+ return 0 ;
1077+ }
10501078 }
1051- token -> token = raw_token ;
10521079
1053- cJSON_Delete ( json );
1054- return 0 ;
1080+ flb_free ( tokens );
1081+ return -1 ;
10551082}
10561083
10571084// extract jwt and its expiration time
10581085static int decode_jwt_and_set_expires (struct flb_oci_logan * ctx )
10591086{
1087+ jsmn_parser parser ;
1088+ jsmntok_t * tokens ;
1089+ int tok_size = 32 ;
1090+ int ret , i ;
1091+ char * key ;
1092+ int key_len ;
1093+
10601094 if (!ctx || !ctx -> security_token .token ) {
10611095 flb_plg_error (ctx -> ins , "Invalid context or token" );
10621096 return -1 ;
@@ -1080,11 +1114,11 @@ static int decode_jwt_and_set_expires(struct flb_oci_logan *ctx)
10801114 memcpy (payload_b64url , dot1 + 1 , payload_b64url_len );
10811115 payload_b64url [payload_b64url_len ] = '\0' ;
10821116
1083- for (int i = 0 ; i < payload_b64url_len ; i ++ ) {
1084- if (payload_b64url [i ] == '-' )
1085- payload_b64url [i ] = '+' ;
1086- else if (payload_b64url [i ] == '_' )
1087- payload_b64url [i ] = '/' ;
1117+ for (int j = 0 ; j < payload_b64url_len ; j ++ ) {
1118+ if (payload_b64url [j ] == '-' )
1119+ payload_b64url [j ] = '+' ;
1120+ else if (payload_b64url [j ] == '_' )
1121+ payload_b64url [j ] = '/' ;
10881122 }
10891123
10901124 int padding = (4 - (payload_b64url_len % 4 )) % 4 ;
@@ -1107,10 +1141,9 @@ static int decode_jwt_and_set_expires(struct flb_oci_logan *ctx)
11071141 return -1 ;
11081142 }
11091143
1110- int ret =
1111- flb_base64_decode ((unsigned char * ) decoded_payload , decoded_len ,
1112- & decoded_len , (unsigned char * ) payload_b64 ,
1113- b64_len );
1144+ ret = flb_base64_decode ((unsigned char * ) decoded_payload , decoded_len ,
1145+ & decoded_len , (unsigned char * ) payload_b64 ,
1146+ b64_len );
11141147 if (ret != 0 ) {
11151148 flb_plg_error (ctx -> ins , "Base64 decode failed" );
11161149 flb_free (payload_b64url );
@@ -1120,40 +1153,79 @@ static int decode_jwt_and_set_expires(struct flb_oci_logan *ctx)
11201153 }
11211154
11221155 decoded_payload [decoded_len ] = '\0' ;
1123- cJSON * json = cJSON_Parse (decoded_payload );
1124- if (json == NULL ) {
1125- const char * error_ptr = cJSON_GetErrorPtr ();
1126- if (error_ptr != NULL ) {
1127- flb_plg_error (ctx -> ins , "JSON parse error before: %s" , error_ptr );
1128- }
1129- else {
1130- flb_plg_error (ctx -> ins , "JSON parse error" );
1131- }
1156+
1157+ jsmn_init (& parser );
1158+
1159+ tokens = flb_calloc (1 , sizeof (jsmntok_t ) * tok_size );
1160+ if (!tokens ) {
11321161 flb_free (payload_b64url );
11331162 flb_free (payload_b64 );
11341163 flb_free (decoded_payload );
11351164 return -1 ;
11361165 }
11371166
1138- cJSON * exp_item = cJSON_GetObjectItem (json , "exp" );
1139- if (!exp_item || !cJSON_IsNumber (exp_item )) {
1140- flb_plg_error (ctx -> ins , "Missing or invalid 'exp' in JWT" );
1141- cJSON_Delete (json );
1167+ ret = jsmn_parse (& parser , decoded_payload , decoded_len , tokens , tok_size );
1168+
1169+ if (ret == JSMN_ERROR_INVAL || ret == JSMN_ERROR_PART ) {
1170+ flb_plg_error (ctx -> ins , "JSON parse error" );
1171+ flb_free (tokens );
11421172 flb_free (payload_b64url );
11431173 flb_free (payload_b64 );
11441174 flb_free (decoded_payload );
11451175 return -1 ;
11461176 }
11471177
1148- time_t exp_value = (time_t ) exp_item -> valuedouble ;
1149- char * json_str = cJSON_Print (json );
1150- if (json_str ) {
1151- flb_free (json_str );
1178+ tok_size = ret ;
1179+
1180+ // Find "exp" key
1181+ time_t exp_value = 0 ;
1182+ for (i = 1 ; i < tok_size ; i ++ ) {
1183+ if (tokens [i ].type != JSMN_STRING ) {
1184+ continue ;
1185+ }
1186+
1187+ key = decoded_payload + tokens [i ].start ;
1188+ key_len = tokens [i ].end - tokens [i ].start ;
1189+
1190+ if (key_len == 3 && strncmp (key , "exp" , 3 ) == 0 ) {
1191+ i ++ ;
1192+ if (i >= tok_size || tokens [i ].type != JSMN_PRIMITIVE ) {
1193+ flb_plg_error (ctx -> ins , "Missing or invalid 'exp' in JWT" );
1194+ flb_free (tokens );
1195+ flb_free (payload_b64url );
1196+ flb_free (payload_b64 );
1197+ flb_free (decoded_payload );
1198+ return -1 ;
1199+ }
1200+
1201+ // Extract numeric value
1202+ char * exp_str = decoded_payload + tokens [i ].start ;
1203+ int exp_len = tokens [i ].end - tokens [i ].start ;
1204+ char exp_buf [32 ];
1205+
1206+ if (exp_len >= sizeof (exp_buf )) {
1207+ exp_len = sizeof (exp_buf ) - 1 ;
1208+ }
1209+
1210+ strncpy (exp_buf , exp_str , exp_len );
1211+ exp_buf [exp_len ] = '\0' ;
1212+
1213+ exp_value = (time_t ) atoll (exp_buf );
1214+ break ;
1215+ }
1216+ }
1217+
1218+ if (exp_value == 0 ) {
1219+ flb_free (tokens );
1220+ flb_free (payload_b64url );
1221+ flb_free (payload_b64 );
1222+ flb_free (decoded_payload );
1223+ return -1 ;
11521224 }
11531225
11541226 ctx -> security_token .expires_at = exp_value ;
11551227
1156- cJSON_Delete ( json );
1228+ flb_free ( tokens );
11571229 flb_free (payload_b64url );
11581230 flb_free (payload_b64 );
11591231 flb_free (decoded_payload );
0 commit comments