mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-18 20:29:44 -07:00
Merge branch '420' of https://github.com/RogueMaster/flipperzero-firmware-wPlugins into Dev
This commit is contained in:
+2
-2
@@ -61,7 +61,7 @@ PVS-Studio.log
|
||||
|
||||
.gdbinit
|
||||
|
||||
PATREONbuildRelease.sh
|
||||
RM*-*.tgz
|
||||
RM*-*.zip
|
||||
RM*-*-*/
|
||||
RM*-*-*/
|
||||
PATREONbuildRelease.sh
|
||||
|
||||
@@ -16,7 +16,13 @@ ___________________________________________________________________________
|
||||
В настройках задается минимальный размер нагрузки (payload)<br>
|
||||
После принятия, пакет сдвигается побитно и валидируется. Побитный сдвиг сильно увеличивает вероятность отлова пакета, но так же увеличивается количество мусорных пакетов.<br>
|
||||
Количество уникальных адресов запоминается (просмотр - стрелка вниз в режиме просмотра адресов)<br>
|
||||
После поиска можно переключиться в режим сканирования по найденным адресам или сканировать адрес конкретного пакета - нажать ОК в режиме просмотра адресов<br>
|
||||
После поиска можно переключиться в режим сканирования по найденным адресам или сканировать адрес конкретного пакета или группы адресов с различным LSB в адресе<br>
|
||||
<br>
|
||||
<img src="https://raw.githubusercontent.com/vad7/nrf24scan/master/Screenshot-6.png">
|
||||
<br>
|
||||
Адреса, которые попались дважды и более раз отображаются списком:<br>
|
||||
<img src="https://raw.githubusercontent.com/vad7/nrf24scan/master/Screenshot-7.png">
|
||||
<br><br>
|
||||
Изменение режима sniff/scan - стрелками на пункте Scan.<br><br>
|
||||
Режим сканирования (scan) - просто чтение пакетов по заданным в настройках мак адресам и виду пакета - ESB/DPL.<br>
|
||||
На начальном экране в режиме чтения можно загрузить файл настроек (по умолчанию загружается settings.txt из папки nrf24_scanner на SD карте).<br>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
@@ -14,11 +14,11 @@
|
||||
#include <u8g2.h>
|
||||
|
||||
#define TAG "nrf24scan"
|
||||
#define VERSION "2.0"
|
||||
#define VERSION "2.1"
|
||||
#define MAX_CHANNEL 125
|
||||
#define MAX_ADDR 6
|
||||
|
||||
#define SCAN_APP_PATH_FOLDER "/ext/apps_data/nrf24scan"
|
||||
#define SCAN_APP_PATH_FOLDER "/ext/nrf24scan"
|
||||
#define SETTINGS_FILENAME "addresses.txt" // Settings file format (1 parameter per line):
|
||||
// SNIFF - if present then sniff mode
|
||||
// Rate: 0/1/2 - rate in Mbps (=0.25/1/2)
|
||||
@@ -41,7 +41,7 @@
|
||||
#define LOG_FILENAME "log"
|
||||
#define LOG_FILEEXT ".txt"
|
||||
#define MAX_LOG_RECORDS 200
|
||||
#define MAX_FOUND_RECORDS 100
|
||||
#define MAX_FOUND_RECORDS 70
|
||||
#define LOG_REC_SIZE 34 // max packet size
|
||||
#define VIEW_LOG_MAX_X 22
|
||||
#define VIEW_LOG_WIDTH_B 10 // bytes
|
||||
@@ -87,7 +87,7 @@ struct ADDRS addrs;
|
||||
struct ADDRS addrs_sniff;
|
||||
bool sniff_loaded = 0;
|
||||
int16_t found_total;
|
||||
int16_t view_found = -1;
|
||||
int16_t view_found;
|
||||
|
||||
int8_t log_to_file = 0; // 0 - no, 1 - yes(new), 2 - append, -1 - only clear
|
||||
uint16_t log_arr_idx;
|
||||
@@ -165,7 +165,7 @@ void clear_log() {
|
||||
view_log_arr_idx = 0;
|
||||
last_packet_send = -1;
|
||||
found_total = 0;
|
||||
view_found = 0;
|
||||
view_found = -1;
|
||||
}
|
||||
|
||||
void write_to_log_file(Storage* storage, bool f_settings) {
|
||||
@@ -455,6 +455,28 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
|
||||
furi_message_queue_put(event_queue, &event, FuriWaitForever);
|
||||
}
|
||||
|
||||
void check_add_addr(uint8_t* pkt) {
|
||||
if(addrs.addr_count > 0 && memcmp(addrs.addr_P0, pkt, addrs.addr_len) == 0) return;
|
||||
if(addrs.addr_count > 1 && memcmp(addrs.addr_P1, pkt, addrs.addr_len - 1) == 0) {
|
||||
if(addrs.addr_P1[addrs.addr_len - 1] == pkt[addrs.addr_len - 1]) return;
|
||||
if(addrs.addr_count > 2 && addrs.addr_P2 == pkt[addrs.addr_len - 1]) return;
|
||||
if(addrs.addr_count > 3 && addrs.addr_P3 == pkt[addrs.addr_len - 1]) return;
|
||||
if(addrs.addr_count > 4 && addrs.addr_P4 == pkt[addrs.addr_len - 1]) return;
|
||||
if(addrs.addr_count > 5 && addrs.addr_P5 == pkt[addrs.addr_len - 1]) return;
|
||||
}
|
||||
if(addrs.addr_count == 1)
|
||||
memcpy(addrs.addr_P1, pkt, addrs.addr_len);
|
||||
else if(addrs.addr_count == 2)
|
||||
addrs.addr_P2 = pkt[addrs.addr_len - 1];
|
||||
else if(addrs.addr_count == 3)
|
||||
addrs.addr_P3 = pkt[addrs.addr_len - 1];
|
||||
else if(addrs.addr_count == 4)
|
||||
addrs.addr_P4 = pkt[addrs.addr_len - 1];
|
||||
else if(addrs.addr_count == 5)
|
||||
addrs.addr_P5 = pkt[addrs.addr_len - 1];
|
||||
addrs.addr_count++;
|
||||
}
|
||||
|
||||
static void prepare_nrf24(bool fsend_packet) {
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_STATUS, 0x70); // clear interrupts
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_RF_SETUP, NRF_rate);
|
||||
@@ -462,11 +484,32 @@ static void prepare_nrf24(bool fsend_packet) {
|
||||
struct ADDRS* adr = what_to_do == 1 ? &addrs_sniff : &addrs;
|
||||
if(!fsend_packet) {
|
||||
uint8_t payload = NRF_Payload;
|
||||
uint8_t* rec = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE;
|
||||
uint8_t addr_size = (*(rec + 1) & 0b11) + 2;
|
||||
bool setup_from_log = false;
|
||||
if(what_to_do >= 2) {
|
||||
if(log_arr_idx && (*rec & 0x80)) {
|
||||
setup_from_log = true;
|
||||
memcpy(addrs.addr_P0, rec + 2, addr_size);
|
||||
addrs.addr_count = 1;
|
||||
addrs.addr_len = addr_size;
|
||||
payload = *(rec + 1) >> 3;
|
||||
if(what_to_do == 2) {
|
||||
uint8_t* p = APP->log_arr + 2;
|
||||
int16_t i = 0;
|
||||
for(i = 0; i < log_arr_idx; i++, p += LOG_REC_SIZE) {
|
||||
if((*(p - 2) & 0x80) && (*(p - 1) & 0b11) + 2 == addr_size &&
|
||||
rec + 2 != p) {
|
||||
if(memcmp(p, addrs.addr_P0, addr_size - 1) == 0) {
|
||||
check_add_addr(rec + 2);
|
||||
if(addrs.addr_count >= 6) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(what_to_do == 1) { // SNIFF
|
||||
if(adr->addr_count == 0) return;
|
||||
//payload += 5 + NRF_CRC; // + addr_max + CRC
|
||||
//if(NRF_ESB) payload += 2;
|
||||
//if(payload > 32) payload = 32;
|
||||
payload = 32;
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70); // Mask all interrupts
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission
|
||||
@@ -475,8 +518,28 @@ static void prepare_nrf24(bool fsend_packet) {
|
||||
nrf24_HANDLE,
|
||||
REG_FEATURE,
|
||||
0); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload
|
||||
} else if(what_to_do == 2) {
|
||||
if(adr->addr_count == 0) return;
|
||||
} else if(setup_from_log) { // Scan
|
||||
nrf24_write_reg(
|
||||
nrf24_HANDLE,
|
||||
REG_CONFIG,
|
||||
0x70 | ((NRF_CRC == 1 ? 0b1000 :
|
||||
NRF_CRC == 2 ? 0b1100 :
|
||||
0))); // Mask all interrupts
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, *rec & 0x7F);
|
||||
nrf24_write_reg(
|
||||
nrf24_HANDLE,
|
||||
REG_FEATURE,
|
||||
*(rec + 2 + addr_size) >> 2 != 0x33 ?
|
||||
4 + 1 :
|
||||
1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload
|
||||
if(*(rec + 1) & 0b100) { // ESB
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0x01); // Automatic Retransmission
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x3F); // Auto acknowledgement
|
||||
} else {
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // Auto acknowledgement
|
||||
}
|
||||
} else {
|
||||
nrf24_write_reg(
|
||||
nrf24_HANDLE,
|
||||
REG_CONFIG,
|
||||
@@ -495,85 +558,55 @@ static void prepare_nrf24(bool fsend_packet) {
|
||||
NRF_DPL ?
|
||||
4 + 1 :
|
||||
1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload
|
||||
}
|
||||
if(what_to_do == 3) {
|
||||
uint8_t* p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE;
|
||||
uint8_t addr_size = (*(p + 1) & 0b11) + 2;
|
||||
nrf24_set_maclen(nrf24_HANDLE, addr_size);
|
||||
nrf24_set_mac(REG_RX_ADDR_P0, p + 2, addr_size);
|
||||
memcpy(addrs.addr_P0, p + 2, addr_size);
|
||||
addrs.addr_count = 1;
|
||||
addrs.addr_len = addr_size;
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, *(p + 1) >> 3);
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, erx_addr);
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, *p & 0x7F);
|
||||
nrf24_write_reg(
|
||||
nrf24_HANDLE,
|
||||
REG_CONFIG,
|
||||
0x70 | ((NRF_CRC == 1 ? 0b1000 :
|
||||
NRF_CRC == 2 ? 0b1100 :
|
||||
0))); // Mask all interrupts
|
||||
if(*(p + 1) & 0b100) { // ESB
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0x01); // Automatic Retransmission
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x3F); // Auto acknowledgement
|
||||
nrf24_write_reg(
|
||||
nrf24_HANDLE,
|
||||
REG_FEATURE,
|
||||
*(p + 2 + addr_size) >> 2 != 0x33 ?
|
||||
4 + 1 :
|
||||
1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload
|
||||
} else {
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // Auto acknowledgement
|
||||
}
|
||||
} else {
|
||||
nrf24_set_maclen(nrf24_HANDLE, adr->addr_len);
|
||||
nrf24_set_mac(REG_RX_ADDR_P0, adr->addr_P0, adr->addr_len);
|
||||
uint8_t tmp[5] = {0};
|
||||
nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, adr->addr_len);
|
||||
for(uint8_t i = 0; i < adr->addr_len / 2; i++) {
|
||||
uint8_t tb = tmp[i];
|
||||
tmp[i] = tmp[adr->addr_len - i - 1];
|
||||
tmp[adr->addr_len - i - 1] = tb;
|
||||
}
|
||||
NRF_ERROR = memcmp(adr->addr_P0, tmp, adr->addr_len) != 0;
|
||||
FURI_LOG_D(TAG, "Payload: %d", payload);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload);
|
||||
if(adr->addr_count > 1) {
|
||||
nrf24_set_mac(REG_RX_ADDR_P1, adr->addr_P1, adr->addr_len);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, payload);
|
||||
erx_addr |= (1 << 1); // Enable RX_P1
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, 0);
|
||||
if(adr->addr_count > 2) {
|
||||
nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P2, &adr->addr_P2, 1);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, payload);
|
||||
erx_addr |= (1 << 2); // Enable RX_P2
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, 0);
|
||||
if(adr->addr_count > 3) {
|
||||
nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P3, &adr->addr_P3, 1);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, payload);
|
||||
erx_addr |= (1 << 3); // Enable RX_P3
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, 0);
|
||||
if(adr->addr_count > 4) {
|
||||
nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P4, &adr->addr_P4, 1);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, payload);
|
||||
erx_addr |= (1 << 4); // Enable RX_P4
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, 0);
|
||||
if(adr->addr_count > 5) {
|
||||
nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P5, &adr->addr_P5, 1);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, payload);
|
||||
erx_addr |= (1 << 5); // Enable RX_P5
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, 0);
|
||||
nrf24_write_reg(
|
||||
nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, erx_addr);
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel);
|
||||
}
|
||||
if(adr->addr_count == 0) return;
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload);
|
||||
nrf24_set_maclen(nrf24_HANDLE, adr->addr_len);
|
||||
nrf24_set_mac(REG_RX_ADDR_P0, adr->addr_P0, adr->addr_len);
|
||||
uint8_t tmp[5] = {0};
|
||||
nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, adr->addr_len);
|
||||
for(uint8_t i = 0; i < adr->addr_len / 2; i++) {
|
||||
uint8_t tb = tmp[i];
|
||||
tmp[i] = tmp[adr->addr_len - i - 1];
|
||||
tmp[adr->addr_len - i - 1] = tb;
|
||||
}
|
||||
NRF_ERROR = memcmp(adr->addr_P0, tmp, adr->addr_len) != 0;
|
||||
FURI_LOG_D(TAG, "Payload: %d", payload);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload);
|
||||
if(adr->addr_count > 1) {
|
||||
nrf24_set_mac(REG_RX_ADDR_P1, adr->addr_P1, adr->addr_len);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, payload);
|
||||
erx_addr |= (1 << 1); // Enable RX_P1
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, 0);
|
||||
if(adr->addr_count > 2) {
|
||||
nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P2, &adr->addr_P2, 1);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, payload);
|
||||
erx_addr |= (1 << 2); // Enable RX_P2
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, 0);
|
||||
if(adr->addr_count > 3) {
|
||||
nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P3, &adr->addr_P3, 1);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, payload);
|
||||
erx_addr |= (1 << 3); // Enable RX_P3
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, 0);
|
||||
if(adr->addr_count > 4) {
|
||||
nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P4, &adr->addr_P4, 1);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, payload);
|
||||
erx_addr |= (1 << 4); // Enable RX_P4
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, 0);
|
||||
if(adr->addr_count > 5) {
|
||||
nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P5, &adr->addr_P5, 1);
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, payload);
|
||||
erx_addr |= (1 << 5); // Enable RX_P5
|
||||
} else
|
||||
nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, 0);
|
||||
nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, erx_addr);
|
||||
}
|
||||
nrf24_flush_rx(nrf24_HANDLE);
|
||||
nrf24_flush_tx(nrf24_HANDLE);
|
||||
@@ -602,26 +635,6 @@ static void start_scanning() {
|
||||
start_time = furi_get_tick();
|
||||
}
|
||||
|
||||
/*
|
||||
bool check_addr_found(uint8_t *pkt)
|
||||
{
|
||||
uint8_t idx = 255;
|
||||
if(addrs_found.addr_count > 0 && memcmp(addrs_found.addr_P0, pkt, addrs_found.addr_len) == 0) { idx = 0; goto x_end; }
|
||||
if(addrs_found.addr_count > 1 && memcmp(addrs_found.addr_P1, pkt, addrs_found.addr_len - 1) == 0) {
|
||||
if(addrs_found.addr_P1[addrs_found.addr_len - 1] == pkt[addrs_found.addr_len - 1]) { idx = 1; goto x_end; }
|
||||
if(addrs_found.addr_count > 2 && addrs_found.addr_P2 == pkt[addrs_found.addr_len - 1]) { idx = 2; goto x_end; }
|
||||
if(addrs_found.addr_count > 3 && addrs_found.addr_P3 == pkt[addrs_found.addr_len - 1]) { idx = 3; goto x_end; }
|
||||
if(addrs_found.addr_count > 4 && addrs_found.addr_P4 == pkt[addrs_found.addr_len - 1]) { idx = 4; goto x_end; }
|
||||
if(addrs_found.addr_count > 5 && addrs_found.addr_P5 == pkt[addrs_found.addr_len - 1]) { idx = 5; goto x_end; }
|
||||
}
|
||||
x_end:
|
||||
if(idx < sizeof(found_total) / sizeof(found_total[0])) {
|
||||
found_total[idx]++;
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
*/
|
||||
|
||||
// start bitnum = 7
|
||||
uint32_t calc_crc(uint32_t crc, uint8_t* ptr, uint8_t bitnum, uint16_t bits) {
|
||||
//uint8_t bitnum = 7;
|
||||
@@ -775,55 +788,6 @@ bool check_packet(uint8_t* pkt, uint16_t size) {
|
||||
found_total++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if(addrs_found.addr_count == 0) {
|
||||
memcpy(addrs_found.addr_P0, pkt, addr_size);
|
||||
addrs_found.addr_len = addr_size;
|
||||
found_total[0]++;
|
||||
addrs_found.addr_count++;
|
||||
} else if(addr_size == addrs_found.addr_len) {
|
||||
if(!check_addr_found(pkt)) {
|
||||
if(addrs_found.addr_count == 1) {
|
||||
memcpy(addrs_found.addr_P1, pkt, addr_size);
|
||||
found_total[1]++;
|
||||
addrs_found.addr_count++;
|
||||
} else if(addrs_found.addr_count == 2) {
|
||||
if(memcmp(addrs_found.addr_P1, pkt, addr_size - 1) == 0) {
|
||||
addrs_found.addr_P2 = pkt[addr_size - 1];
|
||||
found_total[2]++;
|
||||
addrs_found.addr_count++;
|
||||
} else if(memcmp(addrs_found.addr_P0, pkt, addr_size - 1) == 0) {
|
||||
uint8_t tmp[5];
|
||||
memcpy(tmp, addrs_found.addr_P1, addr_size); // swap P0-P1
|
||||
memcpy(addrs_found.addr_P1, addrs_found.addr_P0, addr_size);
|
||||
memcpy(addrs_found.addr_P0, tmp, addr_size);
|
||||
uint32_t n = found_total[0];
|
||||
found_total[0] = found_total[1];
|
||||
found_total[1] = n;
|
||||
addrs_found.addr_P2 = pkt[addr_size - 1];
|
||||
found_total[2]++;
|
||||
addrs_found.addr_count++;
|
||||
}
|
||||
} else if(addrs_found.addr_count >= 3) {
|
||||
if(memcmp(addrs_found.addr_P1, pkt, addr_size - 1) == 0) {
|
||||
if(addrs_found.addr_count == 3) {
|
||||
addrs_found.addr_P3 = pkt[addr_size - 1];
|
||||
found_total[3]++;
|
||||
addrs_found.addr_count++;
|
||||
} else if(addrs_found.addr_count == 4) {
|
||||
addrs_found.addr_P4 = pkt[addr_size - 1];
|
||||
found_total[4]++;
|
||||
addrs_found.addr_count++;
|
||||
} else if(addrs_found.addr_count == 5) {
|
||||
addrs_found.addr_P5 = pkt[addr_size - 1];
|
||||
found_total[5]++;
|
||||
addrs_found.addr_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return found;
|
||||
@@ -1008,7 +972,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
canvas_draw_str(canvas, 10, 30, screen_buf);
|
||||
if(what_to_do == 1)
|
||||
snprintf(screen_buf, sizeof(screen_buf), "Min Payl: %d", NRF_Payload_sniff_min);
|
||||
else if(what_to_do == 3) {
|
||||
else if(what_to_do >= 2) {
|
||||
uint8_t* p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE;
|
||||
snprintf(
|
||||
screen_buf,
|
||||
@@ -1045,11 +1009,11 @@ static void render_callback(Canvas* const canvas, void* ctx) {
|
||||
if(what_to_do == 1)
|
||||
snprintf(screen_buf, sizeof(screen_buf), "Start sniff");
|
||||
else {
|
||||
uint8_t* p;
|
||||
if(what_to_do == 3 && log_arr_idx &&
|
||||
*(p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE) & 0x80) { // +RAW
|
||||
uint8_t* p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE;
|
||||
if(log_arr_idx && (*p & 0x80)) { // +RAW
|
||||
snprintf(screen_buf, sizeof(screen_buf), "Start read: ");
|
||||
add_to_str_hex_bytes(screen_buf, (char*)p + 2, (*(p + 1) & 0b11) + 2);
|
||||
if(what_to_do == 3) strcpy(screen_buf + strlen(screen_buf) - 2, "* ");
|
||||
} else
|
||||
snprintf(
|
||||
screen_buf,
|
||||
@@ -1585,7 +1549,7 @@ int32_t nrf24scan_app(void* p) {
|
||||
case Menu_ok:
|
||||
if(what_to_do) {
|
||||
if((addrs.addr_count ||
|
||||
(what_to_do == 3 && log_arr_idx &&
|
||||
(what_to_do >= 2 && log_arr_idx &&
|
||||
*(APP->log_arr + view_log_arr_idx * LOG_REC_SIZE) &
|
||||
0x80)) ||
|
||||
what_to_do == 1) {
|
||||
@@ -1667,4 +1631,4 @@ int32_t nrf24scan_app(void* p) {
|
||||
if(APP->found) free(APP->found);
|
||||
free(APP);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
TOTP_CLI_PRINTF( \
|
||||
"Invalid command arguments. use \"help\" command to get list of available commands")
|
||||
|
||||
#define TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE() \
|
||||
TOTP_CLI_PRINTF("An error has occurred during updating config file\r\n")
|
||||
|
||||
/**
|
||||
* @brief Checks whether user is authenticated and entered correct PIN.
|
||||
* If user is not authenticated it prompts user to enter correct PIN to authenticate.
|
||||
|
||||
@@ -206,11 +206,13 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
|
||||
|
||||
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, token_info, furi_check);
|
||||
plugin_state->tokens_count++;
|
||||
totp_config_file_save_new_token(token_info);
|
||||
if(totp_config_file_save_new_token(token_info) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF("Token \"%s\" has been successfully added\r\n", token_info->name);
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
|
||||
if(load_generate_token_scene) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
||||
}
|
||||
|
||||
TOTP_CLI_PRINTF("Token \"%s\" has been successfully added\r\n", token_info->name);
|
||||
}
|
||||
@@ -93,14 +93,17 @@ void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args,
|
||||
plugin_state->tokens_list = list_remove(plugin_state->tokens_list, list_node);
|
||||
plugin_state->tokens_count--;
|
||||
|
||||
totp_full_save_config_file(plugin_state);
|
||||
if(totp_full_save_config_file(plugin_state) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF("Token \"%s\" has been successfully deleted\r\n", token_info->name);
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
|
||||
token_info_free(token_info);
|
||||
|
||||
if(activate_generate_token_scene) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
||||
}
|
||||
|
||||
TOTP_CLI_PRINTF("Token \"%s\" has been successfully deleted\r\n", token_info->name);
|
||||
token_info_free(token_info);
|
||||
} else {
|
||||
TOTP_CLI_PRINTF("User not confirmed\r\n");
|
||||
}
|
||||
|
||||
@@ -147,18 +147,18 @@ void totp_cli_command_move_handle(PluginState* plugin_state, FuriString* args, C
|
||||
}
|
||||
|
||||
if(token_updated) {
|
||||
totp_full_save_config_file(plugin_state);
|
||||
if(totp_full_save_config_file(plugin_state) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF("Token \"%s\" has been successfully updated\r\n", token_info->name);
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
} else {
|
||||
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
|
||||
}
|
||||
|
||||
if(activate_generate_token_scene) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
||||
}
|
||||
|
||||
if(token_updated) {
|
||||
TOTP_CLI_PRINTF("Token \"%s\" has been successfully updated\r\n", token_info->name);
|
||||
} else {
|
||||
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
|
||||
}
|
||||
|
||||
furi_string_free(temp_str);
|
||||
}
|
||||
@@ -86,15 +86,18 @@ void totp_cli_command_notification_handle(PluginState* plugin_state, FuriString*
|
||||
}
|
||||
|
||||
plugin_state->notification_method = new_method;
|
||||
totp_config_file_update_notification_method(new_method);
|
||||
if(totp_config_file_update_notification_method(new_method) ==
|
||||
TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF("Notification method is set to ");
|
||||
totp_cli_command_notification_print_method(new_method);
|
||||
cli_nl();
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
|
||||
if(previous_scene != TotpSceneNone) {
|
||||
totp_scene_director_activate_scene(plugin_state, previous_scene, NULL);
|
||||
}
|
||||
|
||||
TOTP_CLI_PRINTF("Notification method is set to ");
|
||||
totp_cli_command_notification_print_method(new_method);
|
||||
cli_nl();
|
||||
} else {
|
||||
TOTP_CLI_PRINTF("Current notification method is ");
|
||||
totp_cli_command_notification_print_method(plugin_state->notification_method);
|
||||
|
||||
@@ -134,8 +134,14 @@ void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cl
|
||||
plugin_state->crypto_verify_data = NULL;
|
||||
}
|
||||
|
||||
totp_crypto_seed_iv(
|
||||
plugin_state, new_pin_length > 0 ? &new_pin[0] : NULL, new_pin_length);
|
||||
if(!totp_crypto_seed_iv(
|
||||
plugin_state, new_pin_length > 0 ? &new_pin[0] : NULL, new_pin_length)) {
|
||||
memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE);
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
break;
|
||||
}
|
||||
|
||||
memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE);
|
||||
|
||||
TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
|
||||
TokenInfo* token_info = node->data;
|
||||
@@ -152,15 +158,18 @@ void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cl
|
||||
free(plain_token);
|
||||
});
|
||||
|
||||
totp_full_save_config_file(plugin_state);
|
||||
|
||||
TOTP_CLI_DELETE_LAST_LINE();
|
||||
|
||||
if(do_change) {
|
||||
TOTP_CLI_PRINTF("PIN has been successfully changed\r\n");
|
||||
} else if(do_remove) {
|
||||
TOTP_CLI_PRINTF("PIN has been successfully removed\r\n");
|
||||
if(totp_full_save_config_file(plugin_state) == TotpConfigFileUpdateSuccess) {
|
||||
if(do_change) {
|
||||
TOTP_CLI_PRINTF("PIN has been successfully changed\r\n");
|
||||
} else if(do_remove) {
|
||||
TOTP_CLI_PRINTF("PIN has been successfully removed\r\n");
|
||||
}
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
|
||||
} while(false);
|
||||
|
||||
if(load_generate_token_scene) {
|
||||
|
||||
@@ -33,8 +33,11 @@ void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* arg
|
||||
float tz = strtof(furi_string_get_cstr(temp_str), NULL);
|
||||
if(tz >= -12.75f && tz <= 12.75f) {
|
||||
plugin_state->timezone_offset = tz;
|
||||
totp_config_file_update_timezone_offset(tz);
|
||||
TOTP_CLI_PRINTF("Timezone is set to %f\r\n", tz);
|
||||
if(totp_config_file_update_timezone_offset(tz) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF("Timezone is set to %f\r\n", tz);
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
if(plugin_state->current_scene == TotpSceneGenerateToken) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/authenticator")
|
||||
#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf"
|
||||
#define CONFIG_FILE_BACKUP_PATH CONFIG_FILE_PATH ".backup"
|
||||
#define CONFIG_FILE_TEMP_PATH CONFIG_FILE_PATH ".tmp"
|
||||
#define CONFIG_FILE_ORIG_PATH CONFIG_FILE_PATH ".orig"
|
||||
#define CONFIG_FILE_PATH_PREVIOUS EXT_PATH("apps/Misc") "/totp.conf"
|
||||
|
||||
static char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
||||
@@ -36,15 +38,38 @@ static void token_info_set_algo_from_str(TokenInfo* token_info, const FuriString
|
||||
}
|
||||
}
|
||||
|
||||
Storage* totp_open_storage() {
|
||||
/**
|
||||
* @brief Opens storage record
|
||||
* @return Storage record
|
||||
*/
|
||||
static Storage* totp_open_storage() {
|
||||
return furi_record_open(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
void totp_close_storage() {
|
||||
/**
|
||||
* @brief Closes storage record
|
||||
*/
|
||||
static void totp_close_storage() {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
FlipperFormat* totp_open_config_file(Storage* storage) {
|
||||
/**
|
||||
* @brief Closes config file
|
||||
* @param file config file reference
|
||||
*/
|
||||
static void totp_close_config_file(FlipperFormat* file) {
|
||||
if(file == NULL) return;
|
||||
flipper_format_file_close(file);
|
||||
flipper_format_free(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Opens or creates TOTP application standard config file
|
||||
* @param storage storage record to use
|
||||
* @param[out] file opened config file
|
||||
* @return Config file open result
|
||||
*/
|
||||
static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperFormat** file) {
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
|
||||
if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK) {
|
||||
@@ -52,7 +77,7 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
|
||||
if(!flipper_format_file_open_existing(fff_data_file, CONFIG_FILE_PATH)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Error opening existing file %s", CONFIG_FILE_PATH);
|
||||
totp_close_config_file(fff_data_file);
|
||||
return NULL;
|
||||
return TotpConfigFileOpenError;
|
||||
}
|
||||
} else if(storage_common_stat(storage, CONFIG_FILE_PATH_PREVIOUS, NULL) == FSE_OK) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Old config file %s found", CONFIG_FILE_PATH_PREVIOUS);
|
||||
@@ -63,15 +88,17 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
|
||||
CONFIG_FILE_DIRECTORY_PATH);
|
||||
if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
|
||||
return NULL;
|
||||
totp_close_config_file(fff_data_file);
|
||||
return TotpConfigFileOpenError;
|
||||
}
|
||||
}
|
||||
if(storage_common_rename(storage, CONFIG_FILE_PATH_PREVIOUS, CONFIG_FILE_PATH) != FSE_OK) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Error moving config to %s", CONFIG_FILE_PATH);
|
||||
return NULL;
|
||||
totp_close_config_file(fff_data_file);
|
||||
return TotpConfigFileOpenError;
|
||||
}
|
||||
FURI_LOG_I(LOGGING_TAG, "Applied config file path migration");
|
||||
return totp_open_config_file(storage);
|
||||
return totp_open_config_file(storage, file);
|
||||
} else {
|
||||
FURI_LOG_D(LOGGING_TAG, "Config file %s is not found. Will create new.", CONFIG_FILE_PATH);
|
||||
if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) {
|
||||
@@ -81,14 +108,14 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
|
||||
CONFIG_FILE_DIRECTORY_PATH);
|
||||
if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
|
||||
return NULL;
|
||||
return TotpConfigFileOpenError;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_file_open_new(fff_data_file, CONFIG_FILE_PATH)) {
|
||||
totp_close_config_file(fff_data_file);
|
||||
FURI_LOG_E(LOGGING_TAG, "Error creating new file %s", CONFIG_FILE_PATH);
|
||||
return NULL;
|
||||
return TotpConfigFileOpenError;
|
||||
}
|
||||
|
||||
flipper_format_write_header_cstr(
|
||||
@@ -153,228 +180,415 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
|
||||
if(!flipper_format_rewind(fff_data_file)) {
|
||||
totp_close_config_file(fff_data_file);
|
||||
FURI_LOG_E(LOGGING_TAG, "Rewind error");
|
||||
return NULL;
|
||||
return TotpConfigFileOpenError;
|
||||
}
|
||||
}
|
||||
|
||||
return fff_data_file;
|
||||
*file = fff_data_file;
|
||||
return TotpConfigFileOpenSuccess;
|
||||
}
|
||||
|
||||
void totp_config_file_save_new_token_i(FlipperFormat* file, const TokenInfo* token_info) {
|
||||
flipper_format_seek_to_end(file);
|
||||
flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_NAME, token_info->name);
|
||||
bool token_is_valid = token_info->token != NULL && token_info->token_length > 0;
|
||||
if(!token_is_valid) {
|
||||
flipper_format_write_comment_cstr(file, "!!! WARNING BEGIN: INVALID TOKEN !!!");
|
||||
TotpConfigFileUpdateResult
|
||||
totp_config_file_save_new_token_i(FlipperFormat* file, const TokenInfo* token_info) {
|
||||
TotpConfigFileUpdateResult update_result;
|
||||
do {
|
||||
if(!flipper_format_seek_to_end(file)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_NAME, token_info->name)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
bool token_is_valid = token_info->token != NULL && token_info->token_length > 0;
|
||||
if(!token_is_valid &&
|
||||
!flipper_format_write_comment_cstr(file, "!!! WARNING BEGIN: INVALID TOKEN !!!")) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_write_hex(
|
||||
file, TOTP_CONFIG_KEY_TOKEN_SECRET, token_info->token, token_info->token_length)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!token_is_valid && !flipper_format_write_comment_cstr(file, "!!! WARNING END !!!")) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_write_string_cstr(
|
||||
file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info))) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t tmp_uint32 = token_info->digits;
|
||||
if(!flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &tmp_uint32, 1)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = TotpConfigFileUpdateSuccess;
|
||||
} while(false);
|
||||
|
||||
return update_result;
|
||||
}
|
||||
|
||||
TotpConfigFileUpdateResult totp_config_file_save_new_token(const TokenInfo* token_info) {
|
||||
Storage* cfg_storage = totp_open_storage();
|
||||
FlipperFormat* file;
|
||||
TotpConfigFileUpdateResult update_result;
|
||||
|
||||
if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
||||
do {
|
||||
if(totp_config_file_save_new_token_i(file, token_info) !=
|
||||
TotpConfigFileUpdateSuccess) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = TotpConfigFileUpdateSuccess;
|
||||
} while(false);
|
||||
|
||||
totp_close_config_file(file);
|
||||
} else {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
}
|
||||
flipper_format_write_hex(
|
||||
file, TOTP_CONFIG_KEY_TOKEN_SECRET, token_info->token, token_info->token_length);
|
||||
if(!token_is_valid) {
|
||||
flipper_format_write_comment_cstr(file, "!!! WARNING END !!!");
|
||||
|
||||
totp_close_storage();
|
||||
return update_result;
|
||||
}
|
||||
|
||||
TotpConfigFileUpdateResult totp_config_file_update_timezone_offset(float new_timezone_offset) {
|
||||
Storage* cfg_storage = totp_open_storage();
|
||||
FlipperFormat* file;
|
||||
TotpConfigFileUpdateResult update_result;
|
||||
|
||||
if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
||||
do {
|
||||
if(!flipper_format_insert_or_update_float(
|
||||
file, TOTP_CONFIG_KEY_TIMEZONE, &new_timezone_offset, 1)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = TotpConfigFileUpdateSuccess;
|
||||
} while(false);
|
||||
|
||||
totp_close_config_file(file);
|
||||
} else {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
}
|
||||
flipper_format_write_string_cstr(
|
||||
file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info));
|
||||
uint32_t tmp_uint32 = token_info->digits;
|
||||
flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &tmp_uint32, 1);
|
||||
}
|
||||
|
||||
void totp_config_file_save_new_token(const TokenInfo* token_info) {
|
||||
Storage* cfg_storage = totp_open_storage();
|
||||
FlipperFormat* file = totp_open_config_file(cfg_storage);
|
||||
|
||||
totp_config_file_save_new_token_i(file, token_info);
|
||||
|
||||
totp_close_config_file(file);
|
||||
totp_close_storage();
|
||||
return update_result;
|
||||
}
|
||||
|
||||
void totp_config_file_update_timezone_offset(float new_timezone_offset) {
|
||||
TotpConfigFileUpdateResult
|
||||
totp_config_file_update_notification_method(NotificationMethod new_notification_method) {
|
||||
Storage* cfg_storage = totp_open_storage();
|
||||
FlipperFormat* file = totp_open_config_file(cfg_storage);
|
||||
FlipperFormat* file;
|
||||
TotpConfigFileUpdateResult update_result;
|
||||
|
||||
flipper_format_insert_or_update_float(file, TOTP_CONFIG_KEY_TIMEZONE, &new_timezone_offset, 1);
|
||||
if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
||||
do {
|
||||
uint32_t tmp_uint32 = new_notification_method;
|
||||
if(!flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = TotpConfigFileUpdateSuccess;
|
||||
} while(false);
|
||||
|
||||
totp_close_config_file(file);
|
||||
} else {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
}
|
||||
|
||||
totp_close_config_file(file);
|
||||
totp_close_storage();
|
||||
return update_result;
|
||||
}
|
||||
|
||||
void totp_config_file_update_notification_method(NotificationMethod new_notification_method) {
|
||||
TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
||||
Storage* cfg_storage = totp_open_storage();
|
||||
FlipperFormat* file = totp_open_config_file(cfg_storage);
|
||||
FlipperFormat* file;
|
||||
TotpConfigFileUpdateResult update_result;
|
||||
if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
||||
do {
|
||||
if(!flipper_format_insert_or_update_float(
|
||||
file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
uint32_t tmp_uint32 = plugin_state->notification_method;
|
||||
if(!flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t tmp_uint32 = new_notification_method;
|
||||
flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
|
||||
update_result = TotpConfigFileUpdateSuccess;
|
||||
} while(false);
|
||||
|
||||
totp_close_config_file(file);
|
||||
} else {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
}
|
||||
|
||||
totp_close_config_file(file);
|
||||
totp_close_storage();
|
||||
return update_result;
|
||||
}
|
||||
|
||||
void totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
||||
Storage* cfg_storage = totp_open_storage();
|
||||
FlipperFormat* file = totp_open_config_file(cfg_storage);
|
||||
|
||||
flipper_format_insert_or_update_float(
|
||||
file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1);
|
||||
uint32_t tmp_uint32 = plugin_state->notification_method;
|
||||
flipper_format_insert_or_update_uint32(
|
||||
file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
|
||||
|
||||
totp_close_config_file(file);
|
||||
totp_close_storage();
|
||||
}
|
||||
|
||||
void totp_full_save_config_file(const PluginState* const plugin_state) {
|
||||
TotpConfigFileUpdateResult totp_full_save_config_file(const PluginState* const plugin_state) {
|
||||
Storage* storage = totp_open_storage();
|
||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||
TotpConfigFileUpdateResult result = TotpConfigFileUpdateSuccess;
|
||||
|
||||
flipper_format_file_open_always(fff_data_file, CONFIG_FILE_PATH);
|
||||
flipper_format_write_header_cstr(
|
||||
fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION);
|
||||
flipper_format_write_hex(
|
||||
fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE);
|
||||
flipper_format_write_hex(
|
||||
fff_data_file,
|
||||
TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
||||
plugin_state->crypto_verify_data,
|
||||
plugin_state->crypto_verify_data_length);
|
||||
flipper_format_write_float(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1);
|
||||
flipper_format_write_bool(fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
|
||||
uint32_t tmp_uint32 = plugin_state->notification_method;
|
||||
flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
|
||||
do {
|
||||
if(!flipper_format_file_open_always(fff_data_file, CONFIG_FILE_TEMP_PATH)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
|
||||
const TokenInfo* token_info = node->data;
|
||||
totp_config_file_save_new_token_i(fff_data_file, token_info);
|
||||
});
|
||||
if(!flipper_format_write_header_cstr(
|
||||
fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_write_hex(
|
||||
fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_write_hex(
|
||||
fff_data_file,
|
||||
TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
||||
plugin_state->crypto_verify_data,
|
||||
plugin_state->crypto_verify_data_length)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_write_float(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_write_bool(
|
||||
fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
uint32_t tmp_uint32 = plugin_state->notification_method;
|
||||
if(!flipper_format_write_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
bool tokens_written = true;
|
||||
TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
|
||||
const TokenInfo* token_info = node->data;
|
||||
tokens_written = tokens_written &&
|
||||
totp_config_file_save_new_token_i(fff_data_file, token_info) ==
|
||||
TotpConfigFileUpdateSuccess;
|
||||
});
|
||||
|
||||
if(!tokens_written) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
totp_close_config_file(fff_data_file);
|
||||
|
||||
if(result == TotpConfigFileUpdateSuccess) {
|
||||
if(storage_file_exists(storage, CONFIG_FILE_ORIG_PATH)) {
|
||||
storage_simply_remove(storage, CONFIG_FILE_ORIG_PATH);
|
||||
}
|
||||
|
||||
if(storage_common_rename(storage, CONFIG_FILE_PATH, CONFIG_FILE_ORIG_PATH) != FSE_OK) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
} else if(storage_common_rename(storage, CONFIG_FILE_TEMP_PATH, CONFIG_FILE_PATH) != FSE_OK) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
} else if(!storage_simply_remove(storage, CONFIG_FILE_ORIG_PATH)) {
|
||||
result = TotpConfigFileUpdateError;
|
||||
}
|
||||
}
|
||||
|
||||
totp_close_storage();
|
||||
return result;
|
||||
}
|
||||
|
||||
void totp_config_file_load_base(PluginState* const plugin_state) {
|
||||
TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_state) {
|
||||
Storage* storage = totp_open_storage();
|
||||
FlipperFormat* fff_data_file = totp_open_config_file(storage);
|
||||
FlipperFormat* fff_data_file;
|
||||
|
||||
TotpConfigFileOpenResult result;
|
||||
if((result = totp_open_config_file(storage, &fff_data_file)) != TotpConfigFileOpenSuccess) {
|
||||
totp_close_storage();
|
||||
return result;
|
||||
}
|
||||
|
||||
plugin_state->timezone_offset = 0;
|
||||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
|
||||
uint32_t file_version;
|
||||
if(!flipper_format_read_header(fff_data_file, temp_str, &file_version)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
|
||||
furi_string_free(temp_str);
|
||||
return;
|
||||
}
|
||||
|
||||
if(file_version < CONFIG_FILE_ACTUAL_VERSION) {
|
||||
FURI_LOG_I(
|
||||
LOGGING_TAG,
|
||||
"Obsolete config file version detected. Current version: %" PRIu32
|
||||
"; Actual version: %" PRId16,
|
||||
file_version,
|
||||
CONFIG_FILE_ACTUAL_VERSION);
|
||||
totp_close_config_file(fff_data_file);
|
||||
|
||||
if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) {
|
||||
storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH);
|
||||
do {
|
||||
uint32_t file_version;
|
||||
if(!flipper_format_read_header(fff_data_file, temp_str, &file_version)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
|
||||
result = TotpConfigFileOpenError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) {
|
||||
FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", CONFIG_FILE_BACKUP_PATH);
|
||||
fff_data_file = totp_open_config_file(storage);
|
||||
FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage);
|
||||
flipper_format_file_open_existing(fff_backup_data_file, CONFIG_FILE_BACKUP_PATH);
|
||||
if(file_version < CONFIG_FILE_ACTUAL_VERSION) {
|
||||
FURI_LOG_I(
|
||||
LOGGING_TAG,
|
||||
"Obsolete config file version detected. Current version: %" PRIu32
|
||||
"; Actual version: %" PRId16,
|
||||
file_version,
|
||||
CONFIG_FILE_ACTUAL_VERSION);
|
||||
totp_close_config_file(fff_data_file);
|
||||
|
||||
if(file_version == 1) {
|
||||
if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) {
|
||||
FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2");
|
||||
} else {
|
||||
FURI_LOG_W(LOGGING_TAG, "An error occurred during migration from v1 to v2");
|
||||
}
|
||||
if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) {
|
||||
storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH);
|
||||
}
|
||||
|
||||
flipper_format_file_close(fff_backup_data_file);
|
||||
flipper_format_free(fff_backup_data_file);
|
||||
flipper_format_rewind(fff_data_file);
|
||||
} else {
|
||||
FURI_LOG_E(
|
||||
LOGGING_TAG,
|
||||
"An error occurred during taking backup of %s into %s before migration",
|
||||
CONFIG_FILE_PATH,
|
||||
CONFIG_FILE_BACKUP_PATH);
|
||||
if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) {
|
||||
FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", CONFIG_FILE_BACKUP_PATH);
|
||||
if(totp_open_config_file(storage, &fff_data_file) != TotpConfigFileOpenSuccess) {
|
||||
result = TotpConfigFileOpenError;
|
||||
break;
|
||||
}
|
||||
|
||||
FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage);
|
||||
if(!flipper_format_file_open_existing(
|
||||
fff_backup_data_file, CONFIG_FILE_BACKUP_PATH)) {
|
||||
flipper_format_file_close(fff_backup_data_file);
|
||||
flipper_format_free(fff_backup_data_file);
|
||||
result = TotpConfigFileOpenError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(file_version == 1) {
|
||||
if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) {
|
||||
FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2");
|
||||
} else {
|
||||
FURI_LOG_W(
|
||||
LOGGING_TAG, "An error occurred during migration from v1 to v2");
|
||||
result = TotpConfigFileOpenError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flipper_format_file_close(fff_backup_data_file);
|
||||
flipper_format_free(fff_backup_data_file);
|
||||
flipper_format_rewind(fff_data_file);
|
||||
} else {
|
||||
FURI_LOG_E(
|
||||
LOGGING_TAG,
|
||||
"An error occurred during taking backup of %s into %s before migration",
|
||||
CONFIG_FILE_PATH,
|
||||
CONFIG_FILE_BACKUP_PATH);
|
||||
result = TotpConfigFileOpenError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_read_hex(
|
||||
fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Missing base IV");
|
||||
}
|
||||
|
||||
flipper_format_rewind(fff_data_file);
|
||||
|
||||
uint32_t crypto_size;
|
||||
if(flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size) &&
|
||||
crypto_size > 0) {
|
||||
plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size);
|
||||
furi_check(plugin_state->crypto_verify_data != NULL);
|
||||
plugin_state->crypto_verify_data_length = crypto_size;
|
||||
if(!flipper_format_read_hex(
|
||||
fff_data_file,
|
||||
TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
||||
plugin_state->crypto_verify_data,
|
||||
crypto_size)) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
|
||||
free(plugin_state->crypto_verify_data);
|
||||
fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Missing base IV");
|
||||
}
|
||||
|
||||
if(!flipper_format_rewind(fff_data_file)) {
|
||||
result = TotpConfigFileOpenError;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t crypto_size;
|
||||
if(flipper_format_get_value_count(
|
||||
fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size) &&
|
||||
crypto_size > 0) {
|
||||
plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size);
|
||||
furi_check(plugin_state->crypto_verify_data != NULL);
|
||||
plugin_state->crypto_verify_data_length = crypto_size;
|
||||
if(!flipper_format_read_hex(
|
||||
fff_data_file,
|
||||
TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
||||
plugin_state->crypto_verify_data,
|
||||
crypto_size)) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
|
||||
free(plugin_state->crypto_verify_data);
|
||||
plugin_state->crypto_verify_data = NULL;
|
||||
plugin_state->crypto_verify_data_length = 0;
|
||||
}
|
||||
} else {
|
||||
plugin_state->crypto_verify_data = NULL;
|
||||
plugin_state->crypto_verify_data_length = 0;
|
||||
}
|
||||
} else {
|
||||
plugin_state->crypto_verify_data = NULL;
|
||||
plugin_state->crypto_verify_data_length = 0;
|
||||
}
|
||||
|
||||
flipper_format_rewind(fff_data_file);
|
||||
if(!flipper_format_rewind(fff_data_file)) {
|
||||
result = TotpConfigFileOpenError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_float(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
|
||||
plugin_state->timezone_offset = 0;
|
||||
FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0");
|
||||
}
|
||||
if(!flipper_format_read_float(
|
||||
fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
|
||||
plugin_state->timezone_offset = 0;
|
||||
FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0");
|
||||
}
|
||||
|
||||
flipper_format_rewind(fff_data_file);
|
||||
if(!flipper_format_rewind(fff_data_file)) {
|
||||
result = TotpConfigFileOpenError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_bool(
|
||||
fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
||||
plugin_state->pin_set = true;
|
||||
}
|
||||
if(!flipper_format_read_bool(
|
||||
fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
||||
plugin_state->pin_set = true;
|
||||
}
|
||||
|
||||
flipper_format_rewind(fff_data_file);
|
||||
flipper_format_rewind(fff_data_file);
|
||||
|
||||
uint32_t tmp_uint32;
|
||||
if(!flipper_format_read_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
||||
tmp_uint32 = NotificationMethodSound | NotificationMethodVibro;
|
||||
}
|
||||
uint32_t tmp_uint32;
|
||||
if(!flipper_format_read_uint32(
|
||||
fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
||||
tmp_uint32 = NotificationMethodSound | NotificationMethodVibro;
|
||||
}
|
||||
|
||||
plugin_state->notification_method = tmp_uint32;
|
||||
plugin_state->notification_method = tmp_uint32;
|
||||
} while(false);
|
||||
|
||||
furi_string_free(temp_str);
|
||||
totp_close_config_file(fff_data_file);
|
||||
totp_close_storage();
|
||||
return result;
|
||||
}
|
||||
|
||||
TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) {
|
||||
Storage* storage = totp_open_storage();
|
||||
FlipperFormat* fff_data_file = totp_open_config_file(storage);
|
||||
FlipperFormat* fff_data_file;
|
||||
if(totp_open_config_file(storage, &fff_data_file) != TotpConfigFileOpenSuccess) {
|
||||
totp_close_storage();
|
||||
return TokenLoadingResultError;
|
||||
}
|
||||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
uint32_t temp_data32;
|
||||
|
||||
if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
|
||||
totp_close_storage();
|
||||
furi_string_free(temp_str);
|
||||
return TokenLoadingResultError;
|
||||
}
|
||||
@@ -478,8 +692,42 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state)
|
||||
return result;
|
||||
}
|
||||
|
||||
void totp_close_config_file(FlipperFormat* file) {
|
||||
if(file == NULL) return;
|
||||
flipper_format_file_close(file);
|
||||
flipper_format_free(file);
|
||||
}
|
||||
TotpConfigFileUpdateResult
|
||||
totp_config_file_update_crypto_signatures(const PluginState* plugin_state) {
|
||||
Storage* storage = totp_open_storage();
|
||||
FlipperFormat* config_file;
|
||||
TotpConfigFileUpdateResult update_result;
|
||||
if(totp_open_config_file(storage, &config_file) == TotpConfigFileOpenSuccess) {
|
||||
do {
|
||||
if(!flipper_format_insert_or_update_hex(
|
||||
config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_insert_or_update_hex(
|
||||
config_file,
|
||||
TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
||||
plugin_state->crypto_verify_data,
|
||||
plugin_state->crypto_verify_data_length)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_insert_or_update_bool(
|
||||
config_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
break;
|
||||
}
|
||||
|
||||
update_result = TotpConfigFileUpdateSuccess;
|
||||
} while(false);
|
||||
|
||||
totp_close_config_file(config_file);
|
||||
} else {
|
||||
update_result = TotpConfigFileUpdateError;
|
||||
}
|
||||
|
||||
totp_close_storage();
|
||||
return update_result;
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "constants.h"
|
||||
|
||||
typedef uint8_t TokenLoadingResult;
|
||||
typedef uint8_t TotpConfigFileOpenResult;
|
||||
typedef uint8_t TotpConfigFileUpdateResult;
|
||||
|
||||
/**
|
||||
* @brief Token loading results
|
||||
@@ -29,40 +31,48 @@ enum TokenLoadingResults {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Opens storage record
|
||||
* @return Storage record
|
||||
* @brief Config file opening result
|
||||
*/
|
||||
Storage* totp_open_storage();
|
||||
enum TotpConfigFileOpenResults {
|
||||
/**
|
||||
* @brief Config file opened successfully
|
||||
*/
|
||||
TotpConfigFileOpenSuccess = 0,
|
||||
|
||||
/**
|
||||
* @brief An error has occurred during opening config file
|
||||
*/
|
||||
TotpConfigFileOpenError = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Closes storage record
|
||||
* @brief Config file updating result
|
||||
*/
|
||||
void totp_close_storage();
|
||||
enum TotpConfigFileUpdateResults {
|
||||
/**
|
||||
* @brief Config file updated successfully
|
||||
*/
|
||||
TotpConfigFileUpdateSuccess,
|
||||
|
||||
/**
|
||||
* @brief Opens or creates TOTP application standard config file
|
||||
* @param storage storage record to use
|
||||
* @return Config file reference
|
||||
*/
|
||||
FlipperFormat* totp_open_config_file(Storage* storage);
|
||||
|
||||
/**
|
||||
* @brief Closes config file
|
||||
* @param file config file reference
|
||||
*/
|
||||
void totp_close_config_file(FlipperFormat* file);
|
||||
/**
|
||||
* @brief An error has occurred during updating config file
|
||||
*/
|
||||
TotpConfigFileUpdateError
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Saves all the settings and tokens to an application config file
|
||||
* @param plugin_state application state
|
||||
* @return Config file update result
|
||||
*/
|
||||
void totp_full_save_config_file(const PluginState* const plugin_state);
|
||||
TotpConfigFileUpdateResult totp_full_save_config_file(const PluginState* const plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Loads basic information from an application config file into application state without loading all the tokens
|
||||
* @param plugin_state application state
|
||||
* @return Config file open result
|
||||
*/
|
||||
void totp_config_file_load_base(PluginState* const plugin_state);
|
||||
TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Loads tokens from an application config file into application state
|
||||
@@ -74,23 +84,36 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state)
|
||||
/**
|
||||
* @brief Add new token to the end of the application config file
|
||||
* @param token_info token information to be saved
|
||||
* @return Config file update result
|
||||
*/
|
||||
void totp_config_file_save_new_token(const TokenInfo* token_info);
|
||||
TotpConfigFileUpdateResult totp_config_file_save_new_token(const TokenInfo* token_info);
|
||||
|
||||
/**
|
||||
* @brief Updates timezone offset in an application config file
|
||||
* @param new_timezone_offset new timezone offset to be set
|
||||
* @return Config file update result
|
||||
*/
|
||||
void totp_config_file_update_timezone_offset(float new_timezone_offset);
|
||||
TotpConfigFileUpdateResult totp_config_file_update_timezone_offset(float new_timezone_offset);
|
||||
|
||||
/**
|
||||
* @brief Updates notification method in an application config file
|
||||
* @param new_notification_method new notification method to be set
|
||||
* @return Config file update result
|
||||
*/
|
||||
void totp_config_file_update_notification_method(NotificationMethod new_notification_method);
|
||||
TotpConfigFileUpdateResult
|
||||
totp_config_file_update_notification_method(NotificationMethod new_notification_method);
|
||||
|
||||
/**
|
||||
* @brief Updates application user settings
|
||||
* @param plugin_state application state
|
||||
* @return Config file update result
|
||||
*/
|
||||
void totp_config_file_update_user_settings(const PluginState* plugin_state);
|
||||
TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginState* plugin_state);
|
||||
|
||||
/**
|
||||
* @brief Updates crypto signatures information
|
||||
* @param plugin_state application state
|
||||
* @return Config file update result
|
||||
*/
|
||||
TotpConfigFileUpdateResult
|
||||
totp_config_file_update_crypto_signatures(const PluginState* plugin_state);
|
||||
@@ -61,7 +61,7 @@ uint8_t* totp_crypto_decrypt(
|
||||
return decrypted_data;
|
||||
}
|
||||
|
||||
void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length) {
|
||||
bool totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length) {
|
||||
if(plugin_state->crypto_verify_data == NULL) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Generating new IV");
|
||||
furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE);
|
||||
@@ -94,13 +94,12 @@ void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t
|
||||
}
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
if(plugin_state->crypto_verify_data == NULL) {
|
||||
FURI_LOG_D(LOGGING_TAG, "Generating crypto verify data");
|
||||
plugin_state->crypto_verify_data = malloc(CRYPTO_VERIFY_KEY_LENGTH);
|
||||
furi_check(plugin_state->crypto_verify_data != NULL);
|
||||
plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH;
|
||||
Storage* storage = totp_open_storage();
|
||||
FlipperFormat* config_file = totp_open_config_file(storage);
|
||||
|
||||
plugin_state->crypto_verify_data = totp_crypto_encrypt(
|
||||
(uint8_t*)CRYPTO_VERIFY_KEY,
|
||||
@@ -108,19 +107,13 @@ void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t
|
||||
&plugin_state->iv[0],
|
||||
&plugin_state->crypto_verify_data_length);
|
||||
|
||||
flipper_format_insert_or_update_hex(
|
||||
config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE);
|
||||
flipper_format_insert_or_update_hex(
|
||||
config_file,
|
||||
TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
||||
plugin_state->crypto_verify_data,
|
||||
CRYPTO_VERIFY_KEY_LENGTH);
|
||||
plugin_state->pin_set = pin != NULL && pin_length > 0;
|
||||
flipper_format_insert_or_update_bool(
|
||||
config_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
|
||||
totp_close_config_file(config_file);
|
||||
totp_close_storage();
|
||||
|
||||
result = totp_config_file_update_crypto_signatures(plugin_state) ==
|
||||
TotpConfigFileUpdateSuccess;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool totp_crypto_verify_key(const PluginState* plugin_state) {
|
||||
|
||||
@@ -35,8 +35,9 @@ uint8_t* totp_crypto_decrypt(
|
||||
* @param plugin_state application state
|
||||
* @param pin user's PIN
|
||||
* @param pin_length user's PIN length
|
||||
* @return \c true on success; \c false otherwise
|
||||
*/
|
||||
void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length);
|
||||
bool totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length);
|
||||
|
||||
/**
|
||||
* @brief Verifies whether cryptographic information (certificate + IV) is valid and can be used for encryption and decryption
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
/* Written by Simon Josefsson. The interface was inspired by memxor
|
||||
in Niels Möller's Nettle. */
|
||||
|
||||
/* #include <config.h> */
|
||||
|
||||
#include "memxor.h"
|
||||
|
||||
void* memxor(void* /*restrict*/ dest, const void* /*restrict*/ src, size_t n) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "types/common.h"
|
||||
#include "ui/scene_director.h"
|
||||
#include "ui/constants.h"
|
||||
#include "ui/common_dialogs.h"
|
||||
#include "services/crypto/crypto.h"
|
||||
#include "cli/cli.h"
|
||||
|
||||
@@ -36,17 +37,7 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
|
||||
furi_message_queue_put(event_queue, &event, FuriWaitForever);
|
||||
}
|
||||
|
||||
static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
||||
plugin_state->gui = furi_record_open(RECORD_GUI);
|
||||
plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
|
||||
plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS);
|
||||
|
||||
totp_config_file_load_base(plugin_state);
|
||||
|
||||
totp_cli_register_command_handler(plugin_state);
|
||||
|
||||
totp_scene_director_init_scenes(plugin_state);
|
||||
|
||||
static bool totp_activate_initial_scene(PluginState* const plugin_state) {
|
||||
if(plugin_state->crypto_verify_data == NULL) {
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_buttons(message, "No", NULL, "Yes");
|
||||
@@ -63,13 +54,19 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
||||
if(dialog_result == DialogMessageButtonRight) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
|
||||
} else {
|
||||
totp_crypto_seed_iv(plugin_state, NULL, 0);
|
||||
if(!totp_crypto_seed_iv(plugin_state, NULL, 0)) {
|
||||
totp_dialogs_config_loading_error(plugin_state);
|
||||
return false;
|
||||
}
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
||||
}
|
||||
} else if(plugin_state->pin_set) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
|
||||
} else {
|
||||
totp_crypto_seed_iv(plugin_state, NULL, 0);
|
||||
if(!totp_crypto_seed_iv(plugin_state, NULL, 0)) {
|
||||
totp_dialogs_config_loading_error(plugin_state);
|
||||
return false;
|
||||
}
|
||||
if(totp_crypto_verify_key(plugin_state)) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
||||
} else {
|
||||
@@ -94,13 +91,20 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
||||
plugin_state->gui = furi_record_open(RECORD_GUI);
|
||||
plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
|
||||
plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS);
|
||||
|
||||
if(totp_config_file_load_base(plugin_state) != TotpConfigFileOpenSuccess) {
|
||||
totp_dialogs_config_loading_error(plugin_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void totp_plugin_state_free(PluginState* plugin_state) {
|
||||
totp_cli_unregister_command_handler();
|
||||
|
||||
totp_scene_director_deactivate_active_scene(plugin_state);
|
||||
|
||||
totp_scene_director_dispose(plugin_state);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
@@ -139,6 +143,14 @@ int32_t totp_app() {
|
||||
return 255;
|
||||
}
|
||||
|
||||
totp_cli_register_command_handler(plugin_state);
|
||||
totp_scene_director_init_scenes(plugin_state);
|
||||
if(!totp_activate_initial_scene(plugin_state)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "An error ocurred during activating initial scene\r\n");
|
||||
totp_plugin_state_free(plugin_state);
|
||||
return 253;
|
||||
}
|
||||
|
||||
// Set system callbacks
|
||||
ViewPort* view_port = view_port_alloc();
|
||||
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
|
||||
@@ -171,6 +183,10 @@ int32_t totp_app() {
|
||||
release_mutex(&state_mutex, plugin_state_m);
|
||||
}
|
||||
|
||||
totp_cli_unregister_command_handler();
|
||||
totp_scene_director_deactivate_active_scene(plugin_state);
|
||||
totp_scene_director_dispose(plugin_state);
|
||||
|
||||
view_port_enabled_set(view_port, false);
|
||||
gui_remove_view_port(plugin_state->gui, view_port);
|
||||
view_port_free(view_port);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "common_dialogs.h"
|
||||
#include "constants.h"
|
||||
|
||||
static DialogMessageButton totp_dialogs_common(PluginState* plugin_state, const char* text) {
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_buttons(message, "Exit", NULL, NULL);
|
||||
dialog_message_set_text(
|
||||
message, text, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter);
|
||||
DialogMessageButton result = dialog_message_show(plugin_state->dialogs_app, message);
|
||||
dialog_message_free(message);
|
||||
return result;
|
||||
}
|
||||
|
||||
DialogMessageButton totp_dialogs_config_loading_error(PluginState* plugin_state) {
|
||||
return totp_dialogs_common(plugin_state, "An error has occurred\nduring loading config file");
|
||||
}
|
||||
|
||||
DialogMessageButton totp_dialogs_config_updating_error(PluginState* plugin_state) {
|
||||
return totp_dialogs_common(plugin_state, "An error has occurred\nduring updating config file");
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <dialogs/dialogs.h>
|
||||
#include "../types/plugin_state.h"
|
||||
|
||||
DialogMessageButton totp_dialogs_config_loading_error(PluginState* plugin_state);
|
||||
DialogMessageButton totp_dialogs_config_updating_error(PluginState* plugin_state);
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../../../lib/list/list.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../ui_controls.h"
|
||||
#include "../../common_dialogs.h"
|
||||
#include "../../../lib/roll_value/roll_value.h"
|
||||
#include "../../../types/nullable.h"
|
||||
#include "../generate_token/totp_scene_generate_token.h"
|
||||
@@ -248,7 +249,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check);
|
||||
plugin_state->tokens_count++;
|
||||
|
||||
totp_config_file_save_new_token(tokenInfo);
|
||||
if(totp_config_file_save_new_token(tokenInfo) != TotpConfigFileUpdateSuccess) {
|
||||
token_info_free(tokenInfo);
|
||||
totp_dialogs_config_updating_error(plugin_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
GenerateTokenSceneContext generate_scene_context = {
|
||||
.current_token_index = plugin_state->tokens_count - 1};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <math.h>
|
||||
#include <Authenticator_icons.h>
|
||||
#include "../../ui_controls.h"
|
||||
#include "../../common_dialogs.h"
|
||||
#include "../../scene_director.h"
|
||||
#include "../token_menu/totp_scene_token_menu.h"
|
||||
#include "../../constants.h"
|
||||
@@ -202,7 +203,12 @@ bool totp_scene_app_settings_handle_event(
|
||||
NotificationMethodNone) |
|
||||
(scene_state->notification_vibro ? NotificationMethodVibro :
|
||||
NotificationMethodNone);
|
||||
totp_config_file_update_user_settings(plugin_state);
|
||||
|
||||
if(totp_config_file_update_user_settings(plugin_state) !=
|
||||
TotpConfigFileUpdateSuccess) {
|
||||
totp_dialogs_config_updating_error(plugin_state);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!scene_state->current_token_index.is_null) {
|
||||
TokenMenuSceneContext generate_scene_context = {
|
||||
|
||||
@@ -128,7 +128,7 @@ static void int_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount
|
||||
str[len] = '\0';
|
||||
}
|
||||
|
||||
TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
|
||||
static TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
|
||||
switch(algo) {
|
||||
case SHA1:
|
||||
return TOTP_ALGO_SHA1;
|
||||
@@ -143,7 +143,7 @@ TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void update_totp_params(PluginState* const plugin_state) {
|
||||
static void update_totp_params(PluginState* const plugin_state) {
|
||||
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
||||
|
||||
if(scene_state->current_token_index < plugin_state->tokens_count) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <gui/gui.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
#include "../../ui_controls.h"
|
||||
#include "../../common_dialogs.h"
|
||||
#include "../../constants.h"
|
||||
#include "../../scene_director.h"
|
||||
#include "../../../services/config/config.h"
|
||||
@@ -156,7 +157,10 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
|
||||
furi_check(tokenInfo != NULL);
|
||||
token_info_free(tokenInfo);
|
||||
|
||||
totp_full_save_config_file(plugin_state);
|
||||
if(totp_full_save_config_file(plugin_state) != TotpConfigFileUpdateSuccess) {
|
||||
totp_dialogs_config_updating_error(plugin_state);
|
||||
return false;
|
||||
}
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
SNIFF
|
||||
ESB: 1
|
||||
CRC: 2
|
||||
P0: 00AA
|
||||
P1: 0055
|
||||
@@ -0,0 +1,6 @@
|
||||
SNIFF
|
||||
ESB: 1
|
||||
CRC: 2
|
||||
P0: FFAA
|
||||
P1: 0055
|
||||
P2: AA
|
||||
Reference in New Issue
Block a user