Benutzer-Werkzeuge

Webseiten-Werkzeuge


contiki:snmp_usm

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
contiki:snmp_usm [2013/02/21 07:24] – [Möglichkeit zur Versendung authentifizierter Reports (RFC konformer Discovery Prozess)] admincontiki:snmp_usm [2017/01/24 18:49] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 ====== Nötige Änderungen innerhalb des User Based Security Models ====== ====== Nötige Änderungen innerhalb des User Based Security Models ======
  
-Leider sind die Implementierungen für die 64Bit Integer Variable zur Generierung des IV und für die Sicherheitsvariable msgAuthoritativeEngineBoots nicht mit den zugehörigen RFCs konform. Außerdem fehlt in der original Contiki SNMP Implementierung die Überprüfung des Benutzersicherheitslevels und die Überprüfung der Variablen msgAuthoritativeEngineTime wurde nicht korrekt umgesetzt.+Leider sind die Implementierungen für die 64Bit Integer Variable zur Generierung des IV und für die Sicherheitsvariable ''msgAuthoritativeEngineBoots'' nicht mit den zugehörigen RFCs konform. Außerdem fehlt in der original Contiki SNMP Implementierung die Überprüfung des Benutzersicherheitslevels und die Überprüfung der Variablen ''msgAuthoritativeEngineTime'' wurde nicht korrekt umgesetzt.
  
 ===== 64Bit Integer Variable zur Generierung des IV ===== ===== 64Bit Integer Variable zur Generierung des IV =====
  
-Laut RFC 3826 muss die 64 Bit Integer Variable beim Bootvorgang pseudo zufällig generiert werden. In der momentanen Implementierung ist diese Variable durch zwei 32 Bit Integer u32t privacyLow und u32t privacyHigh in der Datei snmpd-conf.c mit festen Werten definiert. Um für diese Variablen nun zufällige Werte beim Bootvorgang zu generieren, wird die Funktion random() der AVR-GCC Library genutzt. Diese wird zuerst mit einem Startwert (Seed) durch die Funktion srandom() gesetzt. Zur Startwert Generierung wird die Funktion u32t get_seed() genutzt. Die Funktion u32t get_seed(), generiert aus dem Datenspeicher, genauer gesagt aus dem SRAM Bereich des Datenspeichers in dem sich der Heap und der Stack befindet, einen 32 Bit Anfangswert. Da dies beim Start geschieht, ist der Inhalt des SRAMs zufällig. Der Beginn des Heap Speichers wird über die Variable heap_start, welche im zugehörigen Linker Skript definiert ist, markiert. Das Ende des SRAMS wird über das Makro RAMEND +Laut [[https://tools.ietf.org/html/rfc3826|RFC3826]] muss die 64 Bit  
-(avr/io.h) gekennzeichnet. Es wird nun der gesamte Speicherbereich zwischen heap_start und RAMEND stückweise immer wieder mit einer XOR Verknüpfung durchwandert und der Variable seed zugewiesen. Die Funktion random() wird nun nacheinander den beiden Variablen u32t privacyLow und u32t privacyHigh zugewiesen, wodurch diese nun pseudozufällig sind+Integer Variable beim Bootvorgang pseudo zufällig generiert werden.  
-->Die Variablen sowie die dazugehörigen get-Funktionen wurden von der Datei snmpd-conf.c bzw. snmpd-conf.h in die Dateien snmpd.c bzw. snmpd.h verschoben, da diese beim Programmstart generiert werden müssen.+In der momentanen Implementierung ist diese Variable durch zwei 32 Bit  
 +Integer ''u32t privacyLow'' und ''u32t privacyHigh'' in der Datei  
 +''snmpd-conf.c'' mit festen Werten definiert.  
 +Um für diese Variablen nun zufällige Werte beim Bootvorgang zu generieren,  
 +wird die Funktion ''random()'' der AVR-GCC Library genutzt.  
 +Diese wird zuerst mit einem Startwert (Seed) durch die Funktion srandom() gesetzt.  
 +Zur Generierung eines Startwerts wird die Funktion ''u32t get_seed()'' genutzt.  
 +Die Funktion ''u32t get_seed()'', generiert aus dem Datenspeicher,  
 +genauer gesagt aus dem SRAM Bereich des Datenspeichers in dem sich der Heap  
 +und der Stack befindet, einen 32 Bit Anfangswert. Da dies beim Start geschieht,  
 +ist der Inhalt des SRAMs zufällig.  
 +Der Beginn des Heap Speichers wird über die Variable ''heap_start'', welche im  
 +zugehörigen Linker Skript definiert ist, markiert.  
 +Das Ende des SRAMS wird über das Makro ''RAMEND'' (''avr/io.h'') gekennzeichnet.  
 +Es wird nun der gesamte Speicherbereich zwischen ''heap_start'' und ''RAMEND''  
 +stückweise immer wieder mit einer XOR Verknüpfung durchwandert und der  
 +Variable ''seed'' zugewiesen. Die Funktion ''random()'' wird nun nacheinander  
 +den beiden Variablen ''u32t privacyLow'' und ''u32t privacyHigh'' zugewiesen,  
 +wodurch diese nun pseudozufällig sind.
  
-Funktion: get_seed():+->Die Variablen sowie die dazugehörigen get-Funktionen wurden von der  
 +Datei ''snmpd-conf.c'' bzw. ''snmpd-conf.h'' in die Dateien ''snmpd.c''  
 +bzw. ''snmpd.h'' verschoben, da diese beim Programmstart generiert werden müssen. 
 + 
 +**Funktion:** ''get_seed()'':
 <code c> <code c>
 u32t get_seed ( ) u32t get_seed ( )
Zeile 28: Zeile 50:
 ===== msgAuthoritativeEngineBoots ===== ===== msgAuthoritativeEngineBoots =====
  
-Die Variable msgAuthoritativeEngineBoots muss laut RFC3414 innerhalb einer nicht flüchtigen Variable gespeichert werden und enthält die Anzahl der Bootvorgänge seit der Installation des SNMP Agenten. Sie wird innerhalb des USM msgAuthoritativeEngineBoots zur Generierung des Initialisierungsvektors sowie innerhalb des Timliness Moduls verwendet. In der ursprünglichen Implementierung von Contiki SNMP wird diese Variable einfach immer mit dem Wert Null verwendet. Dies stellt natürlich ein erhebliches Sicherheitsrisko dar. Es wird deshalb eine 32Bit unsigned Integer Variable innerhalb des EEPROM, also im nicht flüchtigen Speicher, des ATmega1281 angelegt. Um auf den EEPROM zuzugreifen, muss die Datei <avr/eeprom.h> miteinbezogen werden. Damit nun bei jedem Neustart des SNMP Agenten msgAuthoritativeEngineBoots inkrementiert wird, kommt die Funktion incMsgAuthoritativeEngineBoots(), siehe folgenden Quellcode, zum Einsatz. +Die Variable ''msgAuthoritativeEngineBoots'' muss laut [[https://tools.ietf.org/html/rfc3414|RFC3414]]  
 +innerhalb einer nicht flüchtigen Variable gespeichert werden und enthält  
 +die Anzahl der Bootvorgänge seit der Installation des SNMP Agenten.  
 +Sie wird innerhalb des USM ''msgAuthoritativeEngineBoots'' zur Generierung des  
 +Initialisierungsvektors sowie innerhalb des Timliness Moduls verwendet.  
 +In der ursprünglichen Implementierung von Contiki SNMP wird diese Variable  
 +einfach immer mit dem Wert Null verwendet.  
 +Dies stellt natürlich ein erhebliches Sicherheitsrisko dar.  
 +Es wird deshalb eine 32Bit unsigned Integer Variable innerhalb des EEPROM,  
 +also im nicht flüchtigen Speicher, des ATmega1281 angelegt.  
 +Um auf den EEPROM zuzugreifen, muss die Datei ''<avr/eeprom.h>'' mit einbezogen werden.  
 +Damit nun bei jedem Neustart des SNMP Agenten ''msgAuthoritativeEngineBoots'' inkrementiert  
 +wird, kommt die Funktion ''incMsgAuthoritativeEngineBoots()'', siehe folgenden Quellcode, zum Einsatz. 
 <code c> <code c>
 u8t incMsgAuthoritativeEngineBoots() u8t incMsgAuthoritativeEngineBoots()
Zeile 51: Zeile 85:
 } }
 </code> </code>
-Sie wird beim Starten des snmpd_process in der Datei snmpd.c aufgerufen und erhöht die Variable um Eins. Außerdem wurde die Ausgabe der Funktion getSysUpTime(), welche die Zeit für die Variable snmpEngineTime liefert, wie in RFC3414 festgelegt, auf einen maximalen Wert von 2147482647 begrenzt. Ist der Wert erreicht, so wird die Variable seconds (Zeit in Sekunden seit Systemstart) auf Null gesetzt und msgAuthoritativeEngineBoots über die Funktion incMsgAuthoritativeEngineBoots() um Eins erhöht. Des Weiteren fordert RFC3414 bei Erreichen eines Wertes von 2147483647 für msgAuthoritativeEngineBoots eine Sperrung des Zugriffs auf den SNMP Agenten. Bei einem Zugriff muss als Fehler eine notInTimeWindow Fehlermeldung zurückgesendet werden. Dies wurde innerhalb der Datei usm.c realisiert.+Sie wird beim Starten des //snmpd_process// in der Datei ''snmpd.c'' aufgerufen  
 +und erhöht die Variable um Eins.  
 +Außerdem wurde die Ausgabe der Funktion ''getSysUpTime()'', welche die  
 +Zeit für die Variable ''snmpEngineTime'' liefert, wie in [[https://tools.ietf.org/html/rfc3414|RFC3414]]  
 +festgelegt, auf einen maximalen Wert von ''2147482647'' begrenzt.  
 +Ist der Wert erreicht, so wird die Variable ''seconds'' (Zeit in Sekunden seit Systemstart)  
 +auf Null gesetzt und ''msgAuthoritativeEngineBoots'' über die Funktion  
 +''incMsgAuthoritativeEngineBoots()'' um Eins erhöht.  
 +Des Weiteren fordert [[https://tools.ietf.org/html/rfc3414|RFC3414]] bei Erreichen  
 +eines Wertes von ''2147483647'' für ''msgAuthoritativeEngineBoots'' eine Sperrung des  
 +Zugriffs auf den SNMP Agenten.  
 +Bei einem Zugriff muss als Fehler eine //notInTimeWindow// Fehlermeldung zurückgesendet werden.  
 +Dies wurde innerhalb der Datei ''usm.c'' realisiert.
  
 -> Der vollständige Quellcode mit allen Änderungen, kann am Ende dieser Seite heruntergeladen werden. -> Der vollständige Quellcode mit allen Änderungen, kann am Ende dieser Seite heruntergeladen werden.
Zeile 57: Zeile 103:
 ===== Überprüfung des Benutzersicherheitslevels ===== ===== Überprüfung des Benutzersicherheitslevels =====
  
-Laut RFC3414 muss vor dem Verarbeiten einer eingehenden SNMP Nachricht überprüft werden ob das Sicherheitslevel der eingehenden Nachricht mit dem Sicherheitslevel des dazugehörigen Benutzernamens übereinstimmt. Ist dies nicht der Fall, so soll die Nachricht verworfen werden und eine Meldung mit dem Inhalt unsupportedSecurityLevel an den Sender zurückgesendet werden. Die original Contiki SNMP Implementierung erfüllt diese Bedingung nicht. Das USM Sicherheitsmodul antwortet immer mit dem Sicherheitslevel, das in der eingehenden Nachricht angegeben ist. Lediglich der Benutzername wird überprüft. Um dieses Problem zu lösen, wurden einige kleine Änderung innerhalb der Datei usm.c vorgenommen.  +Laut [[https://tools.ietf.org/html/rfc3414|RFC3414]] muss vor dem Verarbeiten  
-Zuerst musste ein Objekt für die Fehlermeldung unsupportedSecurityLevel angelegt werden.+einer eingehenden SNMP Nachricht überprüft werden ob das Sicherheitslevel der  
 +eingehenden Nachricht mit dem Sicherheitslevel des dazugehörigen Benutzernamens  
 +übereinstimmt.  
 +Ist dies nicht der Fall, so soll die Nachricht verworfen werden und eine Meldung mit  
 +dem Inhalt //unsupportedSecurityLevel// an den Sender zurückgesendet werden.  
 +Die original Contiki SNMP Implementierung erfüllt diese Bedingung nicht.  
 +Das USM Sicherheitsmodul antwortet immer mit dem Sicherheitslevel, das in der eingehenden Nachricht angegeben ist.  
 +Lediglich der Benutzername wird überprüft.  
 +Um dieses Problem zu lösen, wurden einige kleine Änderung innerhalb der Datei ''usm.c'' vorgenommen.  
 +Zuerst musste ein Objekt für die Fehlermeldung //unsupportedSecurityLevel// angelegt werden.
 <code c> <code c>
 /** \brief The total number of packets received by the SNMP /** \brief The total number of packets received by the SNMP
Zeile 88: Zeile 143:
 ===== Korrektur zur Überprüfung der msgAuthoritativeEngineTime des Timliness Moduls ===== ===== Korrektur zur Überprüfung der msgAuthoritativeEngineTime des Timliness Moduls =====
  
-Innerhalb des USM Moduls befindet sich das Timeliness Modul, dieses dient zur Überprüfung der Authentizität der Nachricht. Dazu muss laut RFC3414 die ankommende msgAuthoritativeEngineTime mit der lokalen AuthoritativeEngineTime des Agenten verglichen werden. Der Unterschied zwischen beiden Zeiten darf 150 Sekunden nicht überschreiten. Dies wurde im original Contiki SNMP mit der folgenden if-Abfrage umgesetzt.+Innerhalb des USM Moduls befindet sich das Timeliness Modul, dieses dient zur Überprüfung der Authentizität der Nachricht. Dazu muss laut RFC3414 die ankommende ''msgAuthoritativeEngineTime'' mit der lokalen ''AuthoritativeEngineTime'' des Agenten verglichen werden.  
 +Der Unterschied zwischen beiden Zeiten darf 150 Sekunden nicht überschreiten.  
 +Dies wurde im original Contiki SNMP mit der folgenden if-Abfrage umgesetzt.
 <code c> <code c>
 if(request->msgAuthor i tat iveEngineBoots != getMsgAuthoritativeEngineBoots()|| abs(request->msgAuthoritativeEngineTime - getSysUpTime() ) < TIME_WINDOW) { if(request->msgAuthor i tat iveEngineBoots != getMsgAuthoritativeEngineBoots()|| abs(request->msgAuthoritativeEngineTime - getSysUpTime() ) < TIME_WINDOW) {
Zeile 97: Zeile 154:
  
  
-Es wird also eine Absolutwertbildung der Subtraktion der msgAuthoritativeEngineTime der ankommenden Nachricht und der Funktion getSysUpTime() durchgeführt. Der Wert der Variablen msgAuthoritativeEngineTime der eingehenden Nachricht ist in Sekunden angegeben. Und die Funktion getSysUpTime() liefert die Zeit seit dem letzten Systemstart in Millisekunden zurück. Dies führt natürlich grundsätzlich zu einem Problem, sodass dieser Wert scheinbar immer größer als 150 Sekunden ist. Dies hat zur Folge, dass die Überprüfung innerhalb der if-Abfrage also immer null ist. Es wird also immer angenommen dass der Wert von msgAuthoritativeEngineTime der eingehenden Nachricht innerhalb des Zeitfensters liegt. Dies wurde durch die folgende Quellcodeänderung korrigiert.+Es wird also eine Absolutwertbildung der Subtraktion der ''msgAuthoritativeEngineTime''  
 +der ankommenden Nachricht und der Funktion ''getSysUpTime()'' durchgeführt.  
 +Der Wert der Variablen msgAuthoritativeEngineTime der eingehenden Nachricht ist in Sekunden angegeben.  
 +Und die Funktion ''getSysUpTime()'' liefert die Zeit seit dem letzten Systemstart in Millisekunden zurück.  
 +Dies führt natürlich grundsätzlich zu einem Problem, sodass dieser Wert scheinbar immer größer als 150 Sekunden ist. Dies hat zur Folge, dass die Überprüfung innerhalb der if-Abfrage also immer null ist. Es wird also immer angenommen dass der Wert von ''msgAuthoritativeEngineTime'' der eingehenden Nachricht innerhalb des Zeitfensters liegt. Dies wurde durch die folgende Quellcodeänderung korrigiert.
  
 <code c> <code c>
Zeile 149: Zeile 210:
  
 Hier kann der komplette Quellcode des geänderten Contiki SNMP heruntergeladen werden: Hier kann der komplette Quellcode des geänderten Contiki SNMP heruntergeladen werden:
-{{:contiki:snmpd.zip|}}+{{:contiki:snmpd13.zip|}}
contiki/snmp_usm.1361431499.txt.gz · Zuletzt geändert: 2017/01/24 18:49 (Externe Bearbeitung)