From add3bd3949b9248edaacfb2f0c40f01c4e3bd9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Kelleter?= Date: Thu, 12 Jan 2017 16:58:35 +0100 Subject: [PATCH] session cookie/ID check Check confirmation MMEs for matching cookie/session-ID. --- plc/Attributes1.c | 3 +++ plc/Attributes2.c | 3 +++ plc/GetProperty.c | 3 +++ plc/ModuleCommit.c | 17 ++++++++++------- plc/ModuleSession.c | 15 +++++++++------ plc/ModuleWrite.c | 15 +++++++++------ plc/SetProperty.c | 3 +++ plc/VersionInfo2.c | 4 ++++ plc/WatchdogReport.c | 14 ++++++++------ plc/WriteExecuteApplet2.c | 12 +++++++----- plc/WriteExecuteFirmware1.c | 12 +++++++----- plc/WriteExecuteFirmware2.c | 12 +++++++----- plc/WriteExecutePIB.c | 12 +++++++----- plc/WriteExecuteParameters1.c | 12 +++++++----- plc/WriteExecuteParameters2.c | 12 +++++++----- 15 files changed, 94 insertions(+), 55 deletions(-) diff --git a/plc/Attributes1.c b/plc/Attributes1.c index d8a2e657..4b3454ed 100644 --- a/plc/Attributes1.c +++ b/plc/Attributes1.c @@ -155,6 +155,9 @@ signed Attributes1 (struct plc * plc) }; char string [512]; size_t length = 0; + if (confirm->COOKIE != HTOLE32 (plc->cookie)) { + continue; + } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/Attributes2.c b/plc/Attributes2.c index 5883d3da..edd87592 100644 --- a/plc/Attributes2.c +++ b/plc/Attributes2.c @@ -173,6 +173,9 @@ signed Attributes2 (struct plc * plc) char string [512]; size_t length = 0; + if (confirm->COOKIE != HTOLE32 (plc->cookie)) { + continue; + } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/GetProperty.c b/plc/GetProperty.c index 57b8927b..019cffb3 100644 --- a/plc/GetProperty.c +++ b/plc/GetProperty.c @@ -124,6 +124,9 @@ signed GetProperty (struct plc * plc, struct plcproperty * plcproperty) } while (ReadMME (plc, 0, (VS_GET_PROPERTY | MMTYPE_CNF)) > 0) { + if (confirm->COOKIE != HTOLE32 (plc->cookie)) { + continue; + } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/ModuleCommit.c b/plc/ModuleCommit.c index 38a187b0..3ed192eb 100644 --- a/plc/ModuleCommit.c +++ b/plc/ModuleCommit.c @@ -101,7 +101,7 @@ signed ModuleCommit (struct plc * plc, uint32_t options) uint32_t COMMIT_CODE; uint8_t NUM_MODULES; } - request; + confirm; struct __packed { uint16_t MOD_STATUS; @@ -132,12 +132,15 @@ signed ModuleCommit (struct plc * plc, uint32_t options) return (-1); } channel->timeout = PLC_MODULE_WRITE_TIMEOUT; - if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - channel->timeout = timer; - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + channel->timeout = timer; + return (-1); + } + } while (confirm->confirm.MOD_OP != HTOLE16 (PLC_MOD_OP_CLOSE_SESSION) || + confirm->confirm.MOD_OP_SESSION_ID != HTOLE32 (plc->cookie)); channel->timeout = timer; if (confirm->MSTATUS) { diff --git a/plc/ModuleSession.c b/plc/ModuleSession.c index 6a3d43b1..5bb56f39 100644 --- a/plc/ModuleSession.c +++ b/plc/ModuleSession.c @@ -145,12 +145,15 @@ signed ModuleSession (struct plc * plc, unsigned modules, struct vs_module_spec return (-1); } channel->timeout = PLC_MODULE_REQUEST_TIMEOUT; - if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - channel->timeout = timer; - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + channel->timeout = timer; + return (-1); + } + } while (confirm->MODULE_SPEC.MOD_OP != HTOLE16 (PLC_MOD_OP_START_SESSION) || + confirm->MODULE_SPEC.MOD_OP_SESSION_ID != HTOLE32 (plc->cookie)); channel->timeout = timer; if (confirm->MSTATUS) { diff --git a/plc/ModuleWrite.c b/plc/ModuleWrite.c index 18f03f78..b47f36dd 100644 --- a/plc/ModuleWrite.c +++ b/plc/ModuleWrite.c @@ -178,12 +178,15 @@ signed ModuleWrite (struct plc * plc, struct _file_ * file, unsigned index, stru return (-1); } channel->timeout = PLC_MODULE_WRITE_TIMEOUT; - if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - channel->timeout = timer; - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + channel->timeout = timer; + return (-1); + } + } while (confirm->MODULE_SPEC.MOD_OP != HTOLE16 (PLC_MOD_OP_WRITE_MODULE) || + confirm->MODULE_SPEC.MOD_OP_SESSION_ID != HTOLE32 (plc->cookie)); channel->timeout = timer; #if 1 diff --git a/plc/SetProperty.c b/plc/SetProperty.c index 81fa0f68..d97c3c85 100644 --- a/plc/SetProperty.c +++ b/plc/SetProperty.c @@ -112,6 +112,9 @@ signed SetProperty (struct plc * plc, struct plcproperty * plcproperty) } while (ReadMME (plc, 0, (VS_SET_PROPERTY | MMTYPE_CNF)) > 0) { + if (confirm->COOKIE != HTOLE32 (plc->cookie)) { + continue; + } if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/VersionInfo2.c b/plc/VersionInfo2.c index 745d63ad..fd36d6dd 100644 --- a/plc/VersionInfo2.c +++ b/plc/VersionInfo2.c @@ -126,6 +126,10 @@ signed VersionInfo2 (struct plc * plc) #endif + /* firmware doesn't fill confirm->COOKIE field at (confirm->MVERSION + confirm->MVERLENGTH + 9) + * (and IDENT, STEPPING_NUM) properly, so we don't check it. + */ + if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/WatchdogReport.c b/plc/WatchdogReport.c index acf7660e..a4c37498 100644 --- a/plc/WatchdogReport.c +++ b/plc/WatchdogReport.c @@ -112,7 +112,7 @@ signed WatchdogReport (struct plc * plc) memset (message, 0, sizeof (* message)); EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type); QualcommHeader (&request->qualcomm, 0, (VS_WD_RPT | MMTYPE_REQ)); - request->SESSIONID = HTOLE32 (plc->cookie); + request->SESSIONID = HTOLE16 (plc->cookie); request->CLR = plc->readaction; plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN); if (SendMME (plc) <= 0) @@ -122,11 +122,13 @@ signed WatchdogReport (struct plc * plc) } do { - if (ReadMME (plc, 0, (VS_WD_RPT | MMTYPE_IND)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_WD_RPT | MMTYPE_IND)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + return (-1); + } + } while (indicate->SESSIONID != HTOLE16 (plc->cookie)); if (indicate->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/WriteExecuteApplet2.c b/plc/WriteExecuteApplet2.c index fe61324e..0f09c500 100644 --- a/plc/WriteExecuteApplet2.c +++ b/plc/WriteExecuteApplet2.c @@ -157,11 +157,13 @@ signed WriteExecuteApplet2 (struct plc * plc, unsigned module, const struct nvm_ error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } - if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + return (-1); + } + } while (confirm->CLIENT_SESSION_ID != HTOLE32 (plc->cookie)); if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/WriteExecuteFirmware1.c b/plc/WriteExecuteFirmware1.c index 371e611a..d373d7f2 100644 --- a/plc/WriteExecuteFirmware1.c +++ b/plc/WriteExecuteFirmware1.c @@ -154,11 +154,13 @@ signed WriteExecuteFirmware1 (struct plc * plc, unsigned module, const struct nv error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } - if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + return (-1); + } + } while (confirm->CLIENT_SESSION_ID != HTOLE32 (plc->cookie)); if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/WriteExecuteFirmware2.c b/plc/WriteExecuteFirmware2.c index 1157cdaf..6b9949b7 100644 --- a/plc/WriteExecuteFirmware2.c +++ b/plc/WriteExecuteFirmware2.c @@ -154,11 +154,13 @@ signed WriteExecuteFirmware2 (struct plc * plc, unsigned module, const struct nv error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } - if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + return (-1); + } + } while (confirm->CLIENT_SESSION_ID != HTOLE32 (plc->cookie)); if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/WriteExecutePIB.c b/plc/WriteExecutePIB.c index 5701f16e..46d10e48 100644 --- a/plc/WriteExecutePIB.c +++ b/plc/WriteExecutePIB.c @@ -149,11 +149,13 @@ signed WriteExecutePIB (struct plc * plc, uint32_t offset, struct pib_header * h error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } - if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + return (-1); + } + } while (confirm->CLIENT_SESSION_ID != HTOLE32 (plc->cookie)); if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/WriteExecuteParameters1.c b/plc/WriteExecuteParameters1.c index 72b4b977..90a28342 100644 --- a/plc/WriteExecuteParameters1.c +++ b/plc/WriteExecuteParameters1.c @@ -181,11 +181,13 @@ signed WriteExecuteParameters1 (struct plc * plc, unsigned module, const struct error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } - if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + return (-1); + } + } while (confirm->CLIENT_SESSION_ID != HTOLE32 (plc->cookie)); if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT); diff --git a/plc/WriteExecuteParameters2.c b/plc/WriteExecuteParameters2.c index 3ad911be..fd8e1869 100644 --- a/plc/WriteExecuteParameters2.c +++ b/plc/WriteExecuteParameters2.c @@ -177,11 +177,13 @@ signed WriteExecuteParameters2 (struct plc * plc, unsigned module, const struct error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND); return (-1); } - if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) - { - error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); - return (-1); - } + do { + if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) + { + error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD); + return (-1); + } + } while (confirm->CLIENT_SESSION_ID != HTOLE32 (plc->cookie)); if (confirm->MSTATUS) { Failure (plc, PLC_WONTDOIT);