From 2a84e34fb0feff085dcf43eae5de1bf6f8d35d53 Mon Sep 17 00:00:00 2001
From: cbdev <cb@cbcdn.com>
Date: Sun, 9 Jul 2023 13:57:01 +0200
Subject: Sanitize tag data, pass dynamic data to commands

---
 command.c | 20 +++++++++++---------
 reader.c  | 19 +++++++++++++++++++
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/command.c b/command.c
index 3dc07e6..869c0a6 100644
--- a/command.c
+++ b/command.c
@@ -153,12 +153,12 @@ void command_reap(){
 	} while(status);
 }
 
-static int command_spawn(command_t* cmd, char* command_name, char* command_static, size_t arg_length){
+static int command_spawn(command_t* cmd, char* command_name, char* command_static){
 	char* workdir = config_get("command", "chdir");
 	char* handler = config_get("command", "handler");
+	char tag_uid[12] = "", dynsize[10] = "";
 	size_t bytes;
-	char tag_uid[12] = "";
-	char dynsize[10] = "";
+	char* dynamic = (cmd->tag->dynamic_length) ? calloc(cmd->tag->dynamic_length + 1, sizeof(uint8_t)) : NULL;
 
 	printf("Starting command %s, static %s\n", command_name, command_static);
 	if(pipe(cmd->iopipe)){
@@ -203,12 +203,16 @@ static int command_spawn(command_t* cmd, char* command_name, char* command_stati
 			setenv("TAG_UID", tag_uid, 1);
 			setenv("MAX_DATA_LENGTH", dynsize, 1);
 
+			if(dynamic){
+				memcpy(dynamic, cmd->tag->dynamic_data, cmd->tag->dynamic_length);
+			}
+
 			//run actual command
 			if(handler){
-				execl(handler, handler, command_name, command_static, NULL);
+				execl(handler, handler, command_name, command_static, dynamic, NULL);
 			}
 			else{
-				execl(command_name, command_name, command_static, NULL);
+				execl(command_name, command_name, command_static, dynamic, NULL);
 			}
 			perror("child/exec");
 			_exit(1);
@@ -223,7 +227,7 @@ static int command_spawn(command_t* cmd, char* command_name, char* command_stati
 }
 
 int command_start(nfc_tag_info_t* info){
-	size_t n = 0, p = ncommands, arg_length = 0;
+	size_t n = 0, p = ncommands;
 	uint8_t* command_name = NULL, *command_static = NULL;
 
 	for(n = 0; n < ncommands; n++){
@@ -257,7 +261,6 @@ int command_start(nfc_tag_info_t* info){
 			command_name[n] = 0;
 			if(info->static_length - n > 1){
 				command_static = command_name + n + 1;
-				arg_length = info->static_length - n - 1;
 			}
 			break;
 		}
@@ -268,7 +271,6 @@ int command_start(nfc_tag_info_t* info){
 		free(command_name);
 		return 1;
 	}
-	//FIXME might want to parse out any non-graphs
 
 	if(p == ncommands){
 		commands = realloc(commands, (p + 1) * sizeof(command_t));
@@ -284,7 +286,7 @@ int command_start(nfc_tag_info_t* info){
 
 	commands[p].tag = info;
 	commands[p].input_head = 0;
-	if(command_spawn(commands + p, (char*) command_name, (char*) command_static, arg_length)){
+	if(command_spawn(commands + p, (char*) command_name, (char*) command_static)){
 		//TODO clean up and free command instance
 	}
 
diff --git a/reader.c b/reader.c
index 2c3a06b..32b17f0 100644
--- a/reader.c
+++ b/reader.c
@@ -4,6 +4,7 @@
 #include <sys/timerfd.h>
 #include <unistd.h>
 #include <string.h>
+#include <ctype.h>
 
 #include "nfcommander.h"
 #include "reader.h"
@@ -38,6 +39,21 @@ static struct {
 	nfc_tag_info_t info;
 } tags[MAX_TAGS] = { 0 };
 
+static void tag_data_sanitize(nfc_tag_info_t* tag){
+	size_t n = 0;
+	for(n = 0; n < tag->static_length; n++){
+		if(tag->static_data[n] && !isprint(tag->static_data[n])){
+			tag->static_data[n] = ' ';
+		}
+	}
+
+	for(n = 0; n < tag->dynamic_length; n++){
+		if(tag->dynamic_data[n] && !isprint(tag->dynamic_data[n])){
+			tag->dynamic_data[n] = ' ';
+		}
+	}
+}
+
 static int reader_init_backend(){
 	char plugin[MAX_PLUGIN_PATH] = "";
 	char* reader = config_get("nfc", "reader");
@@ -201,6 +217,7 @@ int reader_tag_present(uint8_t flags, nfc_tag_info_t* tag){
 				if(flags & TAG_STATUS_FLAGS){
 					memcpy(&(tags[n].info), tag, sizeof(nfc_tag_info_t));
 					tags[n].flags |= flags;
+					tag_data_sanitize(&(tags[n].info));
 					return 0;
 				}
 				//if data has not yet been fully read, request a full read
@@ -209,7 +226,9 @@ int reader_tag_present(uint8_t flags, nfc_tag_info_t* tag){
 
 			if(tags[n].flags & (FLAG_WRITE_FULL | FLAG_WRITE_DYNAMIC)){
 				flags = tags[n].flags;
+				printf("Requesting %s data write on tag %lu\n", (flags & FLAG_WRITE_FULL) ? "full" : "partial", n);
 				tags[n].flags &= ~(FLAG_WRITE_FULL | FLAG_WRITE_DYNAMIC);
+				tag_data_sanitize(&(tags[n].info));
 				//this is kinda dangerous as we hand the reader backend our pointers
 				memcpy(tag, &(tags[n].info), sizeof(nfc_tag_info_t));
 
-- 
cgit v1.2.3