TIA Anlage soll sich am Tag X automatisch sperren

Zuviel Werbung?
-> Hier kostenlos registrieren
Ein Pin reicht hier nicht aus. Man muss bei Problemen schnell mal freischalten können, so dass die Anlage wieder eine Zeit lang läuft.
Hier mein Code mit einer Pinliste!
Es gibt einen Kunden MasterPin und einen ServiceMasterPin, sowie eine Tabelle von Pins, die nach Zeit wieder ablaufen!

Achtung: Datum und Uhrzeit für Pineingabe so setzen, dass euer Servicebüro auch besetzt ist! Speziell wichtig bei Zeitverschiebung!

Das muss aber immer im Vertrag bzw. auch im Handbuch erklärt sein.
Nach vollständiger Bezahlung der Anlage erhalten Sie einen Masterpin, der die Anlage für unbestimmte Zeit freischaltet! Oder sowas!

Code:
 (*

DATA_BLOCK DB_PIN

    TITLE = ''
    VERSION : 0.1

(*  ======================================================================       
        ACHTUNG: DB_PIN muss vor FB PIN übersetzt werden, damit
        Deklarationen vorhanden sind
    ====================================================================== *)

 // KNOW_HOW_PROTECT

     STRUCT   
       DATA : ARRAY  [0 .. 20 ] OF STRUCT     
                DATUM : DATE ;   
                PIN : DINT ;   
            END_STRUCT ;
       ZEIT : TIME_OF_DAY  := TOD#7:0:0.000;   
       UserFinalPin : DINT  := L#00000000;   
       MasterPin : DINT  := L#99999999;   
      END_STRUCT ;   
    
    BEGIN
    
    // ACHTUNG: PIN[0] bei Inbetriebnahme eingeben
    // das ist die Start-PIN
    
    DATA[0].DATUM := D#2023-03-06;   // Mo
    DATA[0].PIN := 123450;
    DATA[1].DATUM := D#2023-04-03;   // Mo
    DATA[1].PIN := 123451;
    DATA[2].DATUM := D#2023-05-02;   // Di
    DATA[2].PIN := 123452;
    DATA[3].DATUM := D#2023-06-05;   // Mo
    DATA[3].PIN := 123453;
    DATA[4].DATUM := D#2023-07-03;   // Mo
    DATA[4].PIN := 123454;
    DATA[5].DATUM := D#2023-08-07;   // Mo
    DATA[5].PIN := 123455;
    DATA[6].DATUM := D#2023-09-04;   // Mo
    DATA[6].PIN := 123456;
    DATA[7].DATUM := D#2023-10-04;   // Mi
    DATA[7].PIN := 123457;
    DATA[8].DATUM := D#2023-11-06;   // Mo
    DATA[8].PIN := 123458;
    DATA[9].DATUM := D#2023-12-04;   // Mo
    DATA[9].PIN := 123459;
    DATA[10].DATUM := D#2024-01-08;  // Mo
    DATA[10].PIN := 123460;
    DATA[11].DATUM := D#2024-02-05;  // Mo
    DATA[11].PIN := 123451;
    DATA[12].DATUM := D#2024-03-05;  // Mo
    DATA[12].PIN := 123462;
    DATA[13].DATUM := D#2024-04-01;  // Mo
    DATA[13].PIN := 123463;
    DATA[14].DATUM := D#2024-05-06;  // Mo
    DATA[14].PIN := 123464;
    DATA[15].DATUM := D#2024-06-03;  // Mo
    DATA[15].PIN := 123465;
    DATA[16].DATUM := D#2024-07-01;  // Mo
    DATA[16].PIN := 123466;
    DATA[17].DATUM := D#2024-08-05;  // Mo
    DATA[17].PIN := 123467;
    DATA[18].DATUM := D#2025-09-02;  // Mo
    DATA[18].PIN := 123468;
    DATA[19].DATUM := D#2024-10-07;  // Mo
    DATA[19].PIN := 123469;
    DATA[20].DATUM := D#2024-11-04;  // Mo
    DATA[20].PIN := 123470;
  // Achtung noch nicht implementiert
    ZEIT := TOD#9:0:0.000; // PIN Expire-Time, d.h am Ablauftag ab Zeit wird PIN ungültig
        
    // diese PIN dem Kunden als Master-PIN für Dauerfreifschaltung rausgeben
    UserFinalPin := L#112345678;
    
    // Diese PIN ist die Hersteller MasterPin, wird diese eingeben, wird automatisch
    // die UserFinalPin aktiviert. Diese PIN ist nur für Servicetechniker, da diese
    // die Anlage für den Kunden auch freischalten können müssen, wenn sie die
    // Kunden-PIN nicht parat haben
    MasterPin := L#21436587;   

END_DATA_BLOCK


FUNCTION_BLOCK PIN
(*  ======================================================================
        PIN-CODE-Abfrage mit PIN[0..iBufferSize]
    ====================================================================== *)

TITLE=    'PIN'         
AUTHOR:   'S.Maag'   
FAMILY:   'Maagic7'     
NAME:     ''   
VERSION:  '1.0'

// KNOW_HOW_PROTECT

VAR_INPUT
    FRG_RES : BOOL;             // Freigabe RESET
END_VAR

VAR_OUTPUT
    outOK : BOOL;               // PIN-OK
    outMaster : BOOL;           // Master-PIN-OK
    outExpireWarn : BOOL;
    DSP_PIN : DINT;        // Show PIN INPUT by User
END_VAR

VAR
    PIN_INPUT  : DINT;          // User PIN Input (from HMI)
    DateExpire : DATE;          // Show PIN expire DATE
    DateExpireWarn : DATE;      // Show for Warning PIN will expire
    PIN_INDEX : DINT;           // Shows index of actual PIN
END_VAR

VAR_TEMP
    // temporäre Variablen
    SysTime : DATE_AND_TIME;
    SysDate   : DATE;
    SysDayTime : Time_Of_Day;
    
    MyDayTime : TIME_OF_DAY;

    I : DINT;
    RET : INT;
//    BLK : WORD;
    
    ThePin : DINT;
    PinOK : BOOL;
END_VAR

VAR
    // statische Variablen

END_VAR

CONST
    iBufferSize := 20;  // Size of BUFFER[0..iBufferSize]
END_CONST

 //   BLK := BLOCK_DB_TO_WORD(DB_PIN);
//    BLK := INT_TO_WORD(WORD_TO_INT(BLK) + WORD_TO_INT(BLK));
//    outMaster := (WORD_TO_BLOCK_DB(BLK).DW[134] = DINT_TO_WORD(PIN_INPUT));
  
    IF PIN_INPUT = DB_PIN.MasterPin THEN   // Master PIN durch UserFinal PIN ersetzen
        PIN_INPUT := DB_PIN.UserFinalPin;  // somit wird Hersteller MasterPIN niemals am Bildschirm angezeitgt
    END_IF;                                 // UserFinalPin ist bei jeder Anlage anders.
    
    outMaster := (PIN_INPUT = DB_PIN.UserFinalPin);   // Master-Pin oder UserFine - (don't expire)
    DSP_PIN := PIN_INPUT;

    outExpireWarn := FALSE;
    I:=iBufferSize;         // höchster Eintrag, Rückwärtssuche PIN bis akt. Datum

    IF outMaster THEN
        PinOK := TRUE;                  // If MasterOk THEN all OK
        DateExpire := D#2168-12-31;      // max. Datum S7 300/400
    ELSE
        
        PinOK := FALSE;   
        MyDayTime := TOD#7:30:00;       // Tageszeit ab der PIN aktiv
      
       (*
       // Wenn Datum Zeit direkt von der CPU-Uhr
        RET:=READ_CLK(CDT :=SysTime); // INT
        SysDate :=DT_DATE(IN := SysTime); // DATE
        SysDayTime := DT_TOD(IN := SysTime); // TIME_OF_DAY
        *)
        
        // Wenn akt Datum/Zeit aus Uhr-DB
        SysDate := "DB4_DateAndTime".aktDate;
        SysDayTime := "DB4_DateAndTime".aktTime;
        
        REPEAT
            ThePin := DB_PIN.DATA[I].PIN;
            DateExpire := DB_PIN.DATA[I].DATUM;
            
            PinOK := (ThePin = PIN_INPUT);
          
            IF PinOK THEN        // Check PIN expired and expired warning
                DateExpireWarn := DINT_TO_DATE(DATE_TO_DINT(DateExpire) -7);
                
                outExpireWarn := SysDate > DateExpireWarn;
                
                IF SysDate > DateExpire THEN
                    PinOK := FALSE;
                ELSIF SysDate = DateExpire THEN
                    PinOK := SysDayTime < MyDayTime;  // If same day? PIN expires at MyDayTime
                END_IF;
            END_IF;
            I := I - 1;  // nächster Eintrag
            
        UNTIL PinOK OR (I < 0) OR (SysDate >= DateExpire)   // Endbedingungen: PinOK, DATA[0] angelanngt, Datum unterschritten
        END_REPEAT;
     END_IF;
    
     PIN_INDEX := I +1;  // Display the actual PIN index
    
     // Wenn keine Freigabe für RESET, dann outOK nicht rücksetzen
     IF FRG_RES OR PinOk THEN
        outOK := PinOK;
     END_IF;         
      
  //   RET:= WORD_TO_INT(BLOCK_DB_TO_WORD(DB9));

END_FUNCTION_BLOCK


*)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hab gerade das Handbuch einer Xinje SPS in der Hand und musste an das Thema hier denken :D. Dort wird so ein vorgehen in einem Beispiel beschrieben...


"Example: forbid the outputs when it reaches the certain time. In the below program, when the date is June 30th, 2012, all the outputs will be disabled. The password 1234 is stored in (D4000, D4001). When the password is correct, all the outputs are enabled."1699010236677.png
XD/XL series PLC User manual [Instruction] (D05 20201022 3.5)
 
Ja, super Schutz. Im Code steht dann auch gleich der Vergleich mit dem Passwort (y)
Die Lösung ist für die Tonne bzw. den Quatsch kann man auf jeder X-beliebigen Steuerung
mit ein paar Zeilen Code umsetzen.
 
Der Code in Beitrag #81 ist auch so für die Tonne. Der tut nur "hochintelligent für Dummies" ;) schützt aber nicht nachhaltig. Vermutlich braucht man da nur den IDB alles mit 16#FF oder 0 überschreiben (oder so ähnlich) und schon ist die Steuerung entsperrt. Also nicht nachmachen, oder wenigstens nicht so simpel...
 
schützt aber nicht nachhaltig.
Die Frage ist ja was man erreichen will. Ich fand es nur ulkig das so eine Funktion im SPS Handbuch erwähnt und implementiert wird...

Auch wenn es einfach ist, wenn die Anlage steht, und nicht klar ist das sie zeitlich gesperrt wurde, ist die Fehlersuche IHMO spannend.
 
Da hat das wohl wer umgesetzt:
Hierzu ist jetzt ein Vortrag der drei Hacker beim 37C3 online auf Youtube:
Hier auf Englisch:
Um diese Inhalte anzuzeigen, benötigen wir die Zustimmung zum Setzen von Drittanbieter-Cookies.
Für weitere Informationen siehe die Seite Verwendung von Cookies.
Und mit deutscher Übersetzung:
Um diese Inhalte anzuzeigen, benötigen wir die Zustimmung zum Setzen von Drittanbieter-Cookies.
Für weitere Informationen siehe die Seite Verwendung von Cookies.

Fand ich sehr interessant, ich hatte bei Zügen eher damit gerechnet das ähnlich zu einem PKW Steuergeräte verbaut sind, aber das ist eine "gewöhnliche" SPS mit CAN Bus Modul die in FUP und ST programmiert wird. Sehr spannend wie das innerhalb der Deadline alles "Reverse engineered" wurde und man ohne Softwareänderung die Züge wieder flott bekommen hat.
 
Zurück
Oben