forked from cory/tildefriends
		
	Message IDs are apparently generated from the latin1 encoding of a message. Added a command to check/fix that.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3833 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										98
									
								
								src/ssb.db.c
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								src/ssb.db.c
									
									
									
									
									
								
							| @@ -507,3 +507,101 @@ void tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds | ||||
| 	} | ||||
| 	sqlite3_set_authorizer(db, NULL, NULL); | ||||
| } | ||||
|  | ||||
| static JSValue _tf_ssb_format_message(JSContext* context, const char* previous, const char* author, int64_t sequence, int64_t timestamp, const char* hash, const char* content, const char* signature, bool sequence_before_author) | ||||
| { | ||||
| 	JSValue value = JS_NewObject(context); | ||||
| 	JS_SetPropertyStr(context, value, "previous", previous ? JS_NewString(context, previous) : JS_NULL); | ||||
| 	if (sequence_before_author) | ||||
| 	{ | ||||
| 		JS_SetPropertyStr(context, value, "sequence", JS_NewInt64(context, sequence)); | ||||
| 		JS_SetPropertyStr(context, value, "author", JS_NewString(context, author)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		JS_SetPropertyStr(context, value, "author", JS_NewString(context, author)); | ||||
| 		JS_SetPropertyStr(context, value, "sequence", JS_NewInt64(context, sequence)); | ||||
| 	} | ||||
| 	JS_SetPropertyStr(context, value, "timestamp", JS_NewInt64(context, timestamp)); | ||||
| 	JS_SetPropertyStr(context, value, "hash", JS_NewString(context, hash)); | ||||
| 	JS_SetPropertyStr(context, value, "content", JS_ParseJSON(context, content, strlen(content), NULL)); | ||||
| 	JS_SetPropertyStr(context, value, "signature", JS_NewString(context, signature)); | ||||
| 	return value; | ||||
| } | ||||
|  | ||||
| bool _tf_ssb_update_message_id(sqlite3* db, const char* old_id, const char* new_id) | ||||
| { | ||||
| 	bool success = false; | ||||
| 	sqlite3_stmt* statement = NULL; | ||||
| 	if (sqlite3_prepare(db, "UPDATE messages SET id = ? WHERE id = ?", -1, &statement, NULL) == SQLITE_OK) | ||||
| 	{ | ||||
| 		if (sqlite3_bind_text(statement, 1, new_id, -1, NULL) == SQLITE_OK && | ||||
| 			sqlite3_bind_text(statement, 2, old_id, -1, NULL) == SQLITE_OK) | ||||
| 		{ | ||||
| 			success = sqlite3_step(statement) == SQLITE_DONE; | ||||
| 		} | ||||
| 		sqlite3_finalize(statement); | ||||
| 	} | ||||
| 	return success; | ||||
| } | ||||
|  | ||||
| bool tf_ssb_db_check(sqlite3* db) | ||||
| { | ||||
| 	JSRuntime* runtime = JS_NewRuntime(); | ||||
| 	JSContext* context = JS_NewContext(runtime); | ||||
|  | ||||
| 	sqlite3_stmt* statement = NULL; | ||||
| 	if (sqlite3_prepare(db, "SELECT id, previous, author, sequence, timestamp, hash, content, signature, sequence_before_author FROM messages ORDER BY author, sequence", -1, &statement, NULL) == SQLITE_OK) | ||||
| 	{ | ||||
| 		char previous_id[k_id_base64_len]; | ||||
| 		while (sqlite3_step(statement) == SQLITE_ROW) | ||||
| 		{ | ||||
| 			const char* id = (const char*)sqlite3_column_text(statement, 0); | ||||
| 			const char* previous = (const char*)sqlite3_column_text(statement, 1); | ||||
| 			const char* author = (const char*)sqlite3_column_text(statement, 2); | ||||
| 			int64_t sequence = sqlite3_column_int64(statement, 3); | ||||
| 			int64_t timestamp = sqlite3_column_int64(statement, 4); | ||||
| 			const char* hash = (const char*)sqlite3_column_text(statement, 5); | ||||
| 			const char* content = (const char*)sqlite3_column_text(statement, 6); | ||||
| 			const char* signature = (const char*)sqlite3_column_text(statement, 7); | ||||
| 			bool sequence_before_author = sqlite3_column_int(statement, 8); | ||||
| 			JSValue message = _tf_ssb_format_message(context, previous, author, sequence, timestamp, hash, content, signature, sequence_before_author); | ||||
| 			char out_signature[512]; | ||||
| 			char actual_id[k_id_base64_len]; | ||||
| 			bool actual_sequence_before_author = false; | ||||
| 			JSValue j = JS_JSONStringify(context, message, JS_NULL, JS_NewInt32(context, 2)); | ||||
| 			const char* jv = JS_ToCString(context, j); | ||||
| 			if (tf_ssb_verify_and_strip_signature(context, message, actual_id, sizeof(actual_id), out_signature, sizeof(out_signature), &actual_sequence_before_author)) | ||||
| 			{ | ||||
| 				/*if (previous && strcmp(previous, previous_id)) | ||||
| 				{ | ||||
| 					printf("%s:%d previous was %s should be %s\n", id, (int)sequence, previous_id, previous); | ||||
| 				}*/ | ||||
| 				if (strcmp(id, actual_id)) | ||||
| 				{ | ||||
| 					if (_tf_ssb_update_message_id(db, id, actual_id)) | ||||
| 					{ | ||||
| 						printf("updated %s to %s\n", id, actual_id); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						printf("failed to update %s to %s\n", id, actual_id); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				printf("unable to verify signature for %s\n", id); | ||||
| 			} | ||||
| 			JS_FreeCString(context, jv); | ||||
| 			JS_FreeValue(context, j); | ||||
| 			snprintf(previous_id, sizeof(previous_id), "%s", id); | ||||
| 			JS_FreeValue(context, message); | ||||
| 		} | ||||
| 		sqlite3_finalize(statement); | ||||
| 	} | ||||
|  | ||||
| 	JS_FreeContext(context); | ||||
| 	JS_FreeRuntime(runtime); | ||||
| 	return false; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user