contiki:snmp_usm
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
contiki:snmp_usm [2012/12/06 11:43] – [Möglichkeit zur Versendung authentifizierter Reports (RFC konformer Discovery Prozess)] sven_zehl | contiki: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 |
===== 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 | + | Laut [[https:// |
- | (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 | ||
+ | '' | ||
+ | Um für diese Variablen nun zufällige Werte beim Bootvorgang zu generieren, | ||
+ | wird die Funktion | ||
+ | Diese wird zuerst mit einem Startwert (Seed) durch die Funktion srandom() gesetzt. | ||
+ | Zur Generierung | ||
+ | Die Funktion | ||
+ | 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 | ||
+ | zugehörigen Linker Skript definiert ist, markiert. | ||
+ | Das Ende des SRAMS wird über das Makro '' | ||
+ | Es wird nun der gesamte Speicherbereich zwischen | ||
+ | stückweise immer wieder mit einer XOR Verknüpfung durchwandert und der | ||
+ | Variable | ||
+ | den beiden Variablen | ||
+ | wodurch diese nun pseudozufällig sind. | ||
- | Funktion: get_seed(): | + | ->Die Variablen sowie die dazugehörigen get-Funktionen wurden von der |
+ | Datei '' | ||
+ | bzw. '' | ||
+ | |||
+ | **Funktion:** '' | ||
<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, | + | Die Variable |
+ | 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 '' | ||
+ | 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, | ||
+ | Damit nun bei jedem Neustart des SNMP Agenten | ||
+ | wird, kommt die Funktion | ||
<code c> | <code c> | ||
u8t incMsgAuthoritativeEngineBoots() | u8t incMsgAuthoritativeEngineBoots() | ||
Zeile 51: | Zeile 85: | ||
} | } | ||
</ | </ | ||
- | 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(), | + | Sie wird beim Starten des //snmpd_process// in der Datei '' |
+ | und erhöht die Variable um Eins. | ||
+ | Außerdem wurde die Ausgabe der Funktion | ||
+ | Zeit für die Variable | ||
+ | festgelegt, auf einen maximalen Wert von '' | ||
+ | Ist der Wert erreicht, so wird die Variable | ||
+ | auf Null gesetzt und '' | ||
+ | '' | ||
+ | Des Weiteren fordert | ||
+ | eines Wertes von '' | ||
+ | Zugriffs auf den SNMP Agenten. | ||
+ | Bei einem Zugriff muss als Fehler eine //notInTimeWindow// Fehlermeldung zurückgesendet werden. | ||
+ | Dies wurde innerhalb der Datei '' | ||
-> Der vollständige Quellcode mit allen Änderungen, | -> Der vollständige Quellcode mit allen Änderungen, | ||
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, | + | Laut [[https:// |
- | 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 | ||
+ | Die original Contiki SNMP Implementierung erfüllt diese Bedingung nicht. | ||
+ | Das USM Sicherheitsmodul antwortet immer mit dem Sicherheitslevel, | ||
+ | Lediglich der Benutzername wird überprüft. | ||
+ | Um dieses Problem zu lösen, wurden einige kleine Änderung innerhalb der Datei '' | ||
+ | Zuerst musste ein Objekt für die Fehlermeldung | ||
<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 86: | Zeile 141: | ||
-> Der vollständige Quellcode mit allen Änderungen, | -> Der vollständige Quellcode mit allen Änderungen, | ||
- | ===== Korrektur zur Überprüfung der msgAuthoritativeEnigineTime | + | ===== Korrektur zur Überprüfung der msgAuthoritativeEngineTime |
- | 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 |
+ | 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-> | if(request-> | ||
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 '' |
+ | der ankommenden Nachricht und der Funktion | ||
+ | Der Wert der Variablen msgAuthoritativeEngineTime der eingehenden Nachricht ist in Sekunden angegeben. | ||
+ | Und die Funktion | ||
+ | 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 '' | ||
<code c> | <code c> | ||
Zeile 104: | Zeile 165: | ||
===== Möglichkeit zur Versendung authentifizierter Reports (RFC konformer Discovery Prozess) ===== | ===== Möglichkeit zur Versendung authentifizierter Reports (RFC konformer Discovery Prozess) ===== | ||
- | Da laut RFC3414 innerhalb des Discovery Vorgangs der zweite Report authentifiziert sein muss, muss innerhalb | + | Da laut RFC3414 |
+ | |||
+ | In der originalen | ||
<code c> | <code c> | ||
Zeile 147: | 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.1354794224.txt.gz · Zuletzt geändert: 2017/01/24 18:49 (Externe Bearbeitung)