ePUAP - jaka piękna katastrofa sie szykuje.

Ponownie w dziejach ludzkości zamiast skorzystać ze sprawdzonych metod wymyśla się koło od początku. Mądre głowy wymyśliły, że powstanie centralny rejestr, wyszukiwarka spraw, które można w urzędach załatwić. Gdyby na tym przestano to pomysł był by super! (abstrahując od obecnej czytelności tego serwisu).

Jak można zepsuć tak piękna idee? Wystarczy wyszukiwarkę połączyć z narzędziem przeprowadzającym "AAA" (Authentication, Authorization, Accounting).
- Identyfikacja: Przedstawiamy się, twierdząc, że my to my!
- Uwierzytelnianie: Serwer na to: sprawdzam!
- Autoryzacja: Jeśli wszystko do tej pory się zgadza i Jan Kowalski jest uwierzytelnionym Janem K. to serwer może dać prawa do pewnych czynności (autoryzację) - jeśli te prawa sie należą.
Te trzy elementy są mocno powiązane - pominięcie choćby jednego z nich może osłabić cały system zabezpieczeń.

Od tego momentu mamy do czynienia z pojedynczym systemem, prowadzonym przez państwowy urząd, ale oprogramowanie zostało kupione od firmy zewnętrznej. Nasuwają mi się pytania:
1) Czy oprogramowanie przeszło audyt bezpieczeństwa?
2) Czy osoby zaangażowane w tworzenie oprogramowania były objęte nadzorem ABW?
3) Czy osoby rozbudowujące, konserwujące i w ogóle mające dostęp do systemu są objęte nadzorem ABW?
4) Czy ePULAP jest objęty nadzorem i ochroną ABW?
5) Czy wszelki dostęp do danych gromadzonych przez system, oraz dostęp do samego systemu, usług, konsol i serwerów, jest w sposób pewny i niezależny rejestrowany i kontrolowany?
6) Czy służby specjalne wykorzystują ten zintegrowany system informatyczny w celu kontroli obywateli?

Przecież ten pojedynczy system umożliwia wgląd w sprawy prowadzone przez obywateli z jednego miejsca. Nie raz są to sprawy o wymiernej wartości majątkowej. Mało tego, ten system odpowiada też za dodatkowe zabezpieczenia, typu potwierdzenia SMS'em. Czyli mając dostęp do tego systemu mogę zapewne ominąć te zabezpieczenia. Jak w takim razie mają  wierzyć w bezpieczeństwo tak przekazywanych danych kancelarie prawne, doradcy finansowi, itp. Co z danymi o zdrowiu, danymi finansowymi, danymi dotyczącymi inwestycji, a może i w przyszłości patentów?
Ten system ma docelowo objąć wszystkich obywateli...

Jeśli system ePULAP nie przechowuje wprost danych dotyczących załatwianych spraw, to i tak mając dostęp do systemu można sprawdzać postępy danej sprawy, sprawdzać historię spraw, itp., ponieważ system ePULAP umożliwia dostęp do innych systemów potwierdzając naszą tożsamość.

Sprawa jest jeszcze bardziej niepokojąca, gdy uzmysłowimy sobie, że systemy informatyczne w poszczególnych urzędach trzymają zapewne dane w formie jawnej na serwerach. Czyli mają do tych danych dostęp osoby bezpośrednio nie zaangażowane z mocy prawa w obsługę danej sprawy, jak informatycy zatrudnieni w urzędzie.
Nasuwa się jeszcze pytanie jak rozwiązano sprawę dostępu do systemu osób zatrudnionych w firmach zewnętrznych (producentach oprogramowania)? Testy nowych wersji, upgrade, rozwiązywanie problemów - czy dane są niewidoczne dla osób wykonujących takie prace konserwacyjne z ramienia twórcy oprogramowania, firmy zewnętrznej? Zawsze niewidoczne? Jak to jest kontrolowane i potwierdzone? Czy istnieje teoretyczna możliwość, że firma tworząca oprogramowanie dla urzędów może mieć dostęp do danych urzędowych i to nie tylko jednego urzędu?

Pomińmy sprawę zabezpieczenia sieci i serwerów, potwierdzenia wiedzy administratorów systemów informatycznych, ich kompetencji - a pomijam teraz w rozważaniach krytyczne punkty! Istnieją przecież urzędy duże, które może czasami są bardziej świadome zagrożeń i przeznaczają większe środki na zabezpieczenia i zatrudniają lepszych administratorów. Lecz co małymi urzędami mającymi małe budżety?

Gdyby od początku połączono dowód osobisty z parą asymetrycznych kluczy kryptograficznych, to cały proces AAA mógł by odbywać się na linii petent-urząd. W takim przypadku, w razie kompromitacji systemu, problem dotyczył by tylko jakiejś grupy osób, korzystających z danego urzędu.
Przez analogię: gdy korzystam z usług kilku banków, to włamanie do danego banku  nie stanowi problemu dla reszty moich pieniędzy w innych bankach. Co by było, gdyby wszystkie banki korzystały z jednego dostawcy potwierdzającego naszą tożsamość? Czy jakikolwiek bank zdecydował by sie na to?
Jak uczy historia każdy taki centralny system musi zostać skompromitowany. Jeśli prawdziwe są informacje, że np.: konsultanci ePULAP obsługujący cały kraj to maksimum dwie osoby, zatrudnione przez firmę pośredniczącą, to ciekawi mnie jak zatrudnieni są inni pracownicy i czy może to mieć implikacje dla bezpieczeństwa tego systemu.

Musiałem ostatnio wysłać jakiś wniosek do urzędu i okazało się, że mogę to zrobić zwykłym e-mailem - co mnie ucieszyło. Zastanowiłem się jednak nad tym, że wniosek ten jest przekazywany jako zwykły e-mail i oprócz osób wskazanych do zapoznania się z nim i jego obsługi mają do niego dostęp informatycy w urzędzie.
Ciekawe, czy włodarze miasta mają świadomość, że informatycy mają dostęp również do ich korespondencji e-mail. Pamiętajmy że SSL szyfruje dane pomiędzy: nadawca-serwer i serwer-odbiorca. Wiadomości na serwerze są przechowywane w postaci jawnej.



µC - Programatory mikrokontrolerów


Programator µC PSoC (PSoC 3 i PSoC 5; JTAG, SWD, SWW, ISSP).
Producent: CYPRESS, model MiniProg3.





Programator µC PIC.
Producent: Microchip, model PICkit3.



Programatory µC ARM.
Producent: Freddie Chopin, model: JTAG-lock-pick Tiny 2 (JTAG i SWD).

Model: BF-20, do 6MHz, dodatkowy RS232, zgodny z Wiggler.


Model: Wiggler.


Programator µC MSP430
Model:


Programatory µC AVR:

 Model AVR PROG.



Zdjęcie rodzinne programatorów.


Uzupełnienie dla programatorów JTAG i SWD:




Ponad 14 000 kondensatorów wygląda tak:


Poniżej na dwóch zdjęciach po 500 szt. kondensatorów elektrolitycznych SMD na 16V i 50V.
Kondensatory te, najczęściej wykorzystuję do zasilania układów. Uzupełniam je kondensatorami elektrolitycznymi o niskim ESR, oraz tantalowymi.

Ta sama pojemność, lecz mniejszy krążek to kondensatory na 16V a większy to kondensatory na 50V. Te o mniejszym napięciu stosuje za stabilizatorem, a za mostkiem prostowniczym te o większym napięciu.

1 000 kondensatorów elektrolitycznych SMD na 50V.


2 000 kondensatorów ceramicznych 100nF SMD 0805. Te kondensatory wykorzystuję najczęściej.

10 000 kondensatorów ceramicznych 100nF 50V THT.

 Pięć pudełek po dwa tysiące kondensatorów THT:



XBee (MaxStream; Digi International) - EEE 802.15.4

XBee to modem bezprzewodowy z interfejsem szeregowym. Pozwala przesyłać dane z prędkościami od 1200 do 230400 bitów na sekundę w paśmie 2.4 Ghz. Prostota implementacji gotowego modułu okupiona jest jego ceną, ale za to komunikacja i podłączenie fizyczne jest uproszczone do maksimum. Moduły pracują w standardzie IEEE 802.15.4, który to opisuje bezprzewodowe sieci osobiste o niskiej przepustowości.

Moduły Xbee XB24, które widać na poniższych zdjęciach, występują w odmianach zwykłej i PRO. W sprzedaży znajduje się wiele układów różniących się: rodzajem anteny, wersją modelu, zasięgiem, prędkością, itp.

 Płytki developerskie zapewniające interface RS232 i USB, oraz moduły XBee XB24.

 Płytka z interface USB: dane i zasilanie jednym przewodem. Widać diody sygnalizacyjne i przyciski, które można wykorzystać przy testach konfiguracji.

Płytka z interface RS232 i gniazdem zasilania.


Moduły występują z różnymi antenami, a co za tym idzie różnią się też zasięgiem:
 Płytka z anteną "chip antenna" - nie wiem czy istnieje jakieś dobre polskie tłumaczenie.

Antena z kawałka drutu, zapewne o długości zbliżonej do 31,2mm bo tyle wynosi 1/4 fali 2.4GHz.

Moduł ze złączem U.FL.

 ... i odpowiednia antena do modułu ze zdjęcia powyżej.

By uniknąć zwarcia warto zamocować płytki z modułami. Jeden moduł zasilam z USB, a drugi z akumulatorka. 


Moduły trzeba podłączyć pod firmowy program XCTU (X-CTU) by sprawdzić, czy wszystkie moduły posiadają jednakową, najlepiej najnowszą, wersję firmware. Wygląd starszej wersji programu był dla mnie czytelniejszy.

Wybór urządzenia XBee podłączonego do komputera.

Gdybym odzyskiwał komunikację z modułem to wybrał bym dla posiadanych modułów następująca konfigurację.

W modułach mam skonfigurowaną większą prędkość transmisji i taką też ustawiam. 

Część konfiguracji modułu XBee. 

Sprawdzam, czy każdy moduł ma identyczną wersję firmware. 

 Jeśli jakiś moduł - jak na zdjęciu powyżej - ma inną wersję to go uaktualniam.

 Proces uaktualnienia firmware. Z zasady przeprowadzam taką operację na laptopie lub na komputerze z UPS (jeden z modułów zasilam w tym wypadku z USB, a drugi z akumulatorka)


 Przykładowe ustawienia minicom ( xminicom -oD /dev/ttyUSB1)
.
Przykładowe ustawienia minicom, cdn.

Moduły mogą pracować w dwóch topologiach sieci IEEE 802.15.4: 
1) Gwiaździstej (mesh). Komunikacja odbywa się przez koordynatora, a sieci pracujące na danym obszarze są niezależne od siebie, dzięki stosowaniu unikalnych identyfikatorów sieci.
2) Partnerskiej (multipoint). Komunikacja może odbywać się bezpośrednio pomiędzy urządzeniami, z pominięciem koordynatora. Można budować skomplikowane sieci, a komunikaty przekazywać do urządzeń znajdujących się poza zasięgiem nadawcy, z wykorzystaniem innych urządzeń (realizuje się to w warstwie sieci, czyli poza 802.15.4)

Komunikację z modułami można zrealizować również na dwa sposoby:
1) Z użyciem trybu transparentnego (tryb domyślny).
2) Z użyciem trybu API.
Można zdalnie przekazywać zmianę stanu wejść i ADC. 


***


Poniżej zamieszczam konfigurację trybu transparentnego, multipoint, z uproszczonym adresowaniem i przekazywaniem danych pomiędzy portami UART. Urządzenia można skonfigurować np. takimi komendami (w dokumentacji XBee te opcje są dokładnie opisane):

Urządzenie 1:
ce=0
a1=0
id=100
ch=b
my=1
dh=0
dl=2

Urządzenie 2:
ce=0
a1=0
id=100
ch=b
my=2
dh=0
dl=1
I to wszystko :-)


***


Poniżej publikuję ważniejsze fragmenty aplikacji realizującej wyszukiwanie innych stacji i odczyt stanu portów wejściowych i ustawianie stanu portów wyjściowych (programy pod FreeBSD i Windows). Nie umieszczę całego kodu, ponieważ te moduły wykorzystywane są na niektórych uczelniach w celach dydaktycznych. By uszanować wykładowców podaję wędkę, nie rybę :-) Przestrzegam też przed bezmyślnym kopiowaniem - wykładowcy, przynajmniej znani mi, zorientują się natychmiast :-)
Zachęcam do dokładnego zapoznania się z dokumentacją układów , która jest wykonana na wysokim poziomie.

Wersja FreeBSD:
#include <fcntl.h>
#include <termios.h>
#include <iostream>


void czekaj(const int sekundy, const int setne);
void openPort(int &portCom, struct termios &optCom, const char *portx);
void ustawPort(const int &portCom, struct termios &optCom, const int ustawCzas);
void wewy_ppp(const int &portCom);
void wewy(const int &portCom, const char *komenda, const int kdl, char *wynik, const int wdl);
void wewy_nd(const int &portCom, char *wyborDL);
bool wewy_przycisk(const int &portCom);
bool wewy_wyswietl(const int &portCom, const bool test);



int main(int argc, char *argv[])
{
int portCom,
licznik;
bool przycisk = false,
dioda = false,
dioda_znacznik = false;
char wyborDL[22] = {0};
struct termios optCom;
const int   kCzas  = 2,
   kCzas2 = 5,
   dCzas  = 20;

char  k_OK[] = {"OK"};
char  k_CH[] = {"ATCH=F\r"}; //kanal radiowy
char  k_DH[] = {"ATDH=0\r"}; //ustawia: Destination Address High
char  k_CN[] = {"ATCN\r"}; //koniec trybu command
char  k_CT[] = {"ATCT=0x64\r"}; //timeout dla trybu command
char  k_ID[] = {"ATID=3332\r"}; //ustawia: ID (Pan ID)
char  k_ATDL[] = {"ATDL "};
char  k_r[] = {"\r"};

char  port0[] = {"/dev/cuaU0"};
char  port1[] = {"/dev/cuaU1"};

char  k_NI[17] = {0};
char  k_MY[17] = {0};
char  k_DL[17] = {0};
char  portX[15] = {0};

char  k_NI_1[] = {"ATNI Stacja1\r"};
char  k_MY_1[] = {"ATMY=111\r"};

char  k_NI_2[] = {"ATNI Stacja2\r"};
char  k_MY_2[] = {"ATMY=222\r"};

    if(argc==1)
    {
printf("Nie podano parametrow w wywolaniu programu.\n");
return(129);
    };

    if(argc>2)
    {
printf("Za duzo parametrow, maksymalnie podaj jeden parametr (np.: -h)\n");
return(130);
    };

    switch (*argv[1])
    {
case 'v':
   printf("Versja 1.9\n");
   return(131);
case 'h':
   printf("Poprawne wywolanie programu: zad01 <numer portu 0 lub 1>\n");
   return(132);
case '0':
   strcpy(k_NI, k_NI_1);
   strcpy(k_MY, k_MY_1);
   strcpy(portX, port0);
   break;
case '1':
   strcpy(k_NI, k_NI_2);
   strcpy(k_MY, k_MY_2);
   strcpy(portX, port1);
   break;
    };

    srand(time(0));
    openPort(portCom, optCom, portX);
    // konfiguracja XBee   
    ustawPort(portCom, optCom, kCzas);
    wewy_ppp(portCom);
    wewy(portCom, k_CH, sizeof(k_CH), k_OK, sizeof(k_OK)); //ATCH
    wewy(portCom, k_NI, sizeof(k_NI), k_OK, sizeof(k_OK)); //ATNI
    wewy(portCom, k_MY, sizeof(k_MY), k_OK, sizeof(k_OK)); //ATMY
    wewy(portCom, k_ID, sizeof(k_ID), k_OK, sizeof(k_OK)); //ATID
    wewy(portCom, k_DH, sizeof(k_DH), k_OK, sizeof(k_OK)); //ATDH
   
    wewy(portCom, k_CT, sizeof(k_CT), k_OK, sizeof(k_OK)); //ATCT
    wewy(portCom, k_CN, sizeof(k_CN), k_OK, sizeof(k_OK)); //ATCN
   
    wewy_ppp(portCom);

    ustawPort(portCom, optCom, dCzas);
    
    strcpy(k_DL, k_ATDL); 
    strcat(k_DL,wyborDL);
    strcat(k_DL, k_r);

    // ustawiam adres DL
    ustawPort(portCom, optCom, kCzas);
    wewy_ppp(portCom);
    wewy(portCom, k_DL, sizeof(k_DL), k_OK, sizeof(k_OK)); //DL

    ustawPort(portCom, optCom, kCzas2);

    for (licznik=0; licznik<21; licznik++)
//    while (true)
    {
wewy(portCom, k_CN, sizeof(k_CN), k_OK, sizeof(k_OK)); //CN
// sprawdza czy przyszla komenda wyswietl
dioda = wewy_wyswietl(portCom, przycisk); 
wewy_ppp(portCom);
if (dioda)
{
    
   dioda_znacznik = true;
}
else
{
   if (dioda_znacznik)
   {
dioda_znacznik = false;
   };
};

// sprawdza nacisniecie przycisku
przycisk = wewy_przycisk(portCom); 
    };
    
    close(portCom);
    printf("Koniec programu.\n");
};




void czekaj(const int sekundy, const int setne)
// jednostka = 10ms
{
timespec    czas,
   czasPozostaly;

    czas.tv_sec = sekundy;
    czas.tv_nsec = (long)10000000 * setne;

    nanosleep(&czas,&czasPozostaly);
};




void openPort(int &portCom, struct termios &optCom, const char *portx)
{
    portCom = open(portx, O_RDWR | O_NOCTTY | O_NDELAY);
    if (portCom < 0) {perror(portx); return; }
    fcntl(portCom, F_SETFL, 0);

    tcgetattr(portCom, &optCom);

    cfsetispeed(&optCom, B9600);
    cfsetospeed(&optCom, B9600);

    optCom.c_cflag |= (CLOCAL | CREAD);
    optCom.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    optCom.c_oflag &= ~OPOST;

    tcsetattr(portCom, TCSANOW, &optCom);
};




void ustawPort(const int &portCom, struct termios &optCom, const int ustawCzas)
{
    optCom.c_cc[VMIN]  = 0;
    optCom.c_cc[VTIME] = ustawCzas;
    tcsetattr(portCom, TCSANOW, &optCom);
};




void wewy_ppp(const int &portCom)
{
char bufor[255]; 
char *bufptr;    
int   rbytes;       
int   proba;       

    czekaj(1,20);
    for (proba = 0; proba < 12; proba++)
    {
if (proba > 0)
{
   if (proba>2)
   {
czekaj(1,0);
   };
}
else
{
   printf("Wysylam do modemu: +++\n");
};

write(portCom, "+++", 3);
czekaj(1,20);
write(portCom, "AT\r", 3);

bufptr = bufor;

while ( (rbytes = read(portCom, bufptr, bufor + sizeof(bufor) - bufptr - 1)) > 0 )
{
   bufptr += rbytes;
   if (bufptr[-1] == '\r')
break;
};

if ( strncmp(bufor, "OK", 2) == 0 )
{
   bufor[3]='\0';
    
   return;
};
    }

    printf("Koncze program, nie moge wyslac: '+++'.\n");   
    abort();
};




void wewy(const int &portCom, const char *komenda, const int kdl, char *wynik, const int wdl)
{
char bufor[255],  
    *bufptr;     
int  rbytes,
    proba;       

    for (proba = 0; proba < 4; proba ++)
    {
if (proba > 0)
{

}
else
{
    
};

if (write(portCom, komenda, kdl) < kdl)
   continue;

bufptr = bufor;

while ( (rbytes = read(portCom, bufptr, bufor + sizeof(bufor) - bufptr - 1)) > 0 )
{
   bufptr += rbytes;
   if (bufptr[-1] == '\r')
break;
};

*bufptr = '\0';
wynik[wdl] = '\0';       

if ( strncmp(bufor, wynik, wdl-1) == 0 )
{
   
   return;
};

wewy_ppp(portCom);
    };
};




void wewy_nd(const int &portCom, char *wyborDL)
{
char bufor[255]={0},
  *bufptr,      
  *spis[20][5];
int   rbytes,    
  nrWpisu=0,
  nrPola=0,
wybor,
znacznik0D=0,
  licz;

    for (int i=0; i<20; i++)
    {
for (int j=0; j<5; j++)
{
   spis[i][j] = new char[22];        
};
    };

    for (licz=0; licz<7; licz++)
    {
bufptr = bufor;
while ( (rbytes = read(portCom, bufptr, 1)) > 0 )
{
   if ( (*bufptr==10) and (znacznik0D>0) )
   {
printf("======\n");
znacznik0D++;
   }
   else
   {
    if (*bufptr==10)
{
   znacznik0D++;
   if (bufptr != bufor+1)
   {
*bufptr = '\0';
printf("-- %s\n", bufor);

strcpy(spis[nrWpisu][nrPola], bufor);
bufptr = bufor;
if (nrPola==4)
{
   nrPola=0;
   if (nrWpisu==19)
   {
printf("Przekroczono zakres tablicy.\n");
abort();
   }
   else
   {
nrWpisu++;
   };
}
else
{    
   nrPola++;
};
   };
}
else
{
   znacznik0D=0;
   bufptr++;
};
   };
};
if (nrWpisu>0)
{
   break;
}
else
{
   
   czekaj(1,0);
};
    };

    if(nrWpisu==0)
    {
printf("Koncze dzialanie programu.\n\n");
abort();
    };

  
    for (int i=0; i<nrWpisu; i++)
    {
printf(" nr. %i: %s NI=%s\n",i+1, spis[i][4],spis[i][0]);
    };

    do
    {
if ( !scanf("%d",&wybor) )
{
   std::cin.clear();
   std::cin.ignore(10, '\n');
};
    }
    while ( wybor<1 or wybor>nrWpisu);
//    while ( !(wybor>0 and wybor<nrWpisu+1));
    
    strcpy(wyborDL, spis[wybor-1][0]);
    
   

    for (int i=0; i<20; i++)
    {
for (int j=0; j<5; j++)
{
   delete spis[i][j];
};
    };
};




bool wewy_przycisk(const int &portCom)
{
char bufor[255],
     *bufptr;     
int  rbytes,
     proba;       

    for (proba = 0; proba < 4; proba ++)
    {
if (proba > 0)
{
    
}
else
{
   
};

if (write(portCom, "ATIS\r", 5) < 5)
   continue;

bufptr = bufor;
while ( (rbytes = read(portCom, bufptr, bufor + sizeof(bufor) - bufptr - 1)) > 0 )
{
   bufptr += rbytes;
};

*bufptr = '\0';
if ( (bufor[6]=='0') and (bufor[7]=='0') and (bufor[8]=='0') )
{
   return(true);
}
wewy_ppp(portCom);
    };
    return(false);
};




bool wewy_wyswietl(const int &portCom, const bool test)
{
char bufor[255],
        *bufptr,
komunikat[] = {'*','G','R','1','*'};     
int rbytes,
komunikatDl = 5,
licznik;    

    if (test) 
    {
for (licznik=0; licznik<8; licznik++)
{    
   write(portCom, komunikat, komunikatDl);
   czekaj(0,25);
};
    };

    bufptr = bufor;

    while ( (rbytes = read(portCom, bufptr, bufor + sizeof(bufor) - bufptr - 1)) > 0 )
    {
bufptr += rbytes;
    };

    if (test) 
    {
   write(portCom, komunikat, komunikatDl);
    };

    *bufptr = '\0';

    if ( strncmp(bufor, komunikat, komunikatDl) == 0 )
    {



if (test) 
{
   write(portCom, komunikat, komunikatDl);
};

for (licznik=0; licznik<3; licznik++)
{    
   if (test) 
   {
czekaj(0,50);
write(portCom, komunikat, komunikatDl);
   };
};

return (true);
    };
    
    czekaj(0,(rand()%25));

    if (test) 
    {
   write(portCom, komunikat, komunikatDl);
    };

    return (false);
};


//end



Wersja Windows:

#include <windows.h>
//#include "stdio.h"
#include "string.h"
//#include <stdio.h>
//#include <iostream>
//#include <iomanip>
//#include <list>
//#include <time.h>
//#include <windows.h>
//#include <conio.h>
//#include <stdlib.h> 
//#include <cstdio>
//#include <ctime>
//#include <iostream> 
//#include <stdio.h>



char * k_OK = {"OK"};

char * k_ppp = {"+++"};
char * k_ppp_spr = {"OK"};

char * k_ATCT = {"ATCT=64"};
char * k_ATCT_spr = {"ATCT=64"};


//NAZWA
char * k_ATNI_1 = {"ATNI Unit1"};
char * k_ATNI_spr_1 = {"ATNI"};
char * k_ATNI_2 = {"ATNI Unit2"};
char * k_ATNI_spr_2 = {"ATNI"};


//KANAL
char * k_ATCH = {'A','T','C','H','=','B',13,0};
char * k_ATCH_spr = {"ATCH,",13};

char * k_ATDH = {"ATDH=0"};
char * k_ATDH_spr = {"ATDH"};


char * k_ATMY_1 = {"ATMY=1357"};
char * k_ATMY_spr_1 = {"ATMY"};

char * k_ATDL_1 = {"ATDL=2468"};
char * k_ATDL_spr_1 = {"ATDL"};


char * k_ATMY_2 = {"ATMY=2468"};
char * k_ATMY_spr_2 = {"ATMY"};

char * k_ATDL_2 = {"ATDL=1357"};
char * k_ATDL_spr_2 = {"ATDL"};



//KONIEC
char * k_ATCN = {"ATCN"};
char * k_ATCN_spr = {""};



HANDLE portCOM;    
DCB dcb;        
BOOL fSuccess;  
BYTE RS_buf;    
DWORD RS_ile;   
COMMTIMEOUTS ustawCOM={0, 0, 0, 0, 0};

int licznik_komunikatow = 0;
const byte czekaj_1   = 1;
const byte czekaj_10  = 10;
const byte czekaj_100 = 100;


void czekaj(byte czekaj)
// jednostka = 10ms
{
int i;
for (i = 0; i < czekaj; i++)
{
Sleep(10);
}
}


void rs_otworz_urzadzenie()
{
//port COM1 z prawami RW
portCOM = CreateFile( TEXT("COM1"), GENERIC_READ | GENERIC_WRITE,
0,    // exclusive access
NULL, // default security attributes
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (portCOM == INVALID_HANDLE_VALUE)
{
printf("Open - blad %d.\n", GetLastError());
}
}


int rs_ustaw_parametry()
{
int blad;
blad = GetCommState(portCOM, &dcb);
if (!blad)
{
printf ("GetCommState - blad %d.\n", GetLastError());
return 2;
}

dcb.BaudRate = CBR_9600;     
dcb.ByteSize = 8;             
dcb.Parity = NOPARITY;        
dcb.StopBits = ONESTOPBIT;    

blad = SetCommState(portCOM, &dcb);
if (!blad)
{
printf ("SetCommState - blad %d.\n", GetLastError());
return 3;
}
}


int rs_znak_pisz(char znak)
{
int blad;
RS_buf=znak;
printf("%c",znak);
ustawCOM.ReadTotalTimeoutConstant=0;
    blad = WriteFile( portCOM, &RS_buf, 1, &RS_ile, 0);
    if (!blad)
    {
    
      return 4;
    }
}


char rs_znak_czytaj()
{

}



void pisz_raw(char *wyslij, char *odczytaj, byte czekaj_przed, byte czekaj_pomiedzy, byte czekaj_po, byte ilosc_powt)
// string do wyslania, 
// string, ktory ma zwrocic urzadzenie
// czekaj przed wyslaniem w ms
// czekaj pomiedzy powtorzeniami wyslania w ms
// czekaj po wyslaniu w ms
// ilosc prob powtorzen operacji
{
int i;

//czekaj(czekaj_przed);

int len = strlen(wyslij);
for (i = 0; i < len; i++) 
{
//printf("%c",wyslij[i]);
rs_znak_pisz(wyslij[i]);

}


czekaj(czekaj_po);
}


void pisz(char *wyslij, char *odczytaj, byte czekaj_przed, byte czekaj_pomiedzy, byte czekaj_po, byte ilosc_powt)
{
}



char czytaj(int czekaj_max)
//jak dlugo ma czekac na znaki
{
int blad;
int testuj=1;

   while(testuj!=0)
   {         
czekaj(10);
  testuj--;

ustawCOM.ReadTotalTimeoutConstant=1100;

SetCommTimeouts(portCOM,&ustawCOM);
 
       
 
     
        //if(RS_ile==1)
       // {

          //  if(RS_buf == )
           // {
               
           //     testuj=0;
           //     break;
          //  };
//            printf("%c", RS_buf);
            printf("%s", &RS_buf);
FlushFileBuffers(portCOM);

      //  }
   }

}


void xbee_ustaw_parametry_stanowisko_1(void)
{
}


void xbee_ustaw_parametry_stanowisko_2(void)
{
}


void xbee_ustaw_parametry(void)
{
    xbee_ustaw_parametry_stanowisko_1();
}


int main()
{
    rs_otworz_urzadzenie();
    rs_ustaw_parametry();

//+++

   czekaj(110);
   czytaj(1);
   czekaj(5);
printf ("\n");

printf ("\n");
 czytaj(1);
   czekaj(5);

/*
//ATCH=B
pisz_raw(k_ATCH, k_ATCH_spr, 110, 120, 10, 100);
czytaj(1);
czekaj(10);
printf ("\n");
*/
/*
pisz_raw(k_ATCH_spr, k_ATCH_spr, 110, 120, 10, 100);
czytaj(1);
czekaj(10);
printf ("\n");
*/


//pisz_raw(k_ENTER, k_ENTER, 110, 120, 10, 100);
//pisz_raw(k_ATCH_spr, k_ATCH_spr, 110, 120, 10, 100);
//   czytaj(1);
//   czekaj(10);
//ATNI Unit1
//pisz_raw(k_ATNI_1, k_ATNI_spr_1, 110, 120, 10, 100);
//   czytaj(1);

//ATCH=B
//pisz_raw(k_ATCH, k_ATCH_spr, 110, 120, 10, 100);
//   czytaj(1);

//ATDH=0
//pisz_raw(k_ATDH, k_ATDH_spr, 110, 120, 10, 100);
//   czytaj(1);

//ATMY=1357
//pisz_raw(k_ATMY_1, k_ATMY_spr_1, 110, 120, 10, 100);
//   czytaj(1);

//ATDL=2468
//pisz_raw(k_ATDL_1, k_ATDL_spr_1, 110, 120, 10, 100);
//   czytaj(1);

printf ("\n");
system("pause");
return (0);   
}

//END


***


Użyłem adapterów:
- Z interface RS232: XBIB-R-DEV
- Z interface USB: XBIB-U-DEV



Heartbeat - nadmuchana bańka.

W sieci przez chwilę zapanowała histeria! Podważano nawet sens istnienia wolnego oprogramowania... tak...
Jednocześnie jakoś bez większego echa przeszła informacja o luce we wszystkich wersjach IE (Internet Explorera) - luce umożliwiającej instalację złośliwego oprogramowania. Wystarczy, że użytkownik IE wejdzie na odpowiednio spreparowaną stronę WWW... Lukę znaleźli ludzie z www.fireeye.com.
Ciekawe czy zostanie wydana poprawka do Windows XP?

Wracając do meritum: błąd nazwany "heartbeat" CVE-2014-0160 znalazł się w implementacji rozszerzenia RFC6520 protokołów TLS/DTLS. Co to oznacza? W ten sposób powinna zostać zabezpieczona transmisja pomiędzy serwerem a klientem. Czyli nie dane przechowywane na serwerach, tylko sama transmisja. 
Błąd jednak pozwalał na kradzież innych danych, niż tylko tych, które ktoś mógłby podsłuchać podłączając się gdzieś pomiędzy nami a np.: bankiem. Lecz kiedy ta kradzież może nastąpić? Tylko wtedy, gdy nie rozdzielamy usług. 
Jeśli wykorzystujemy np. akceleratory SSL, czy to w postaci osobnych maszyn, serwerów proxy na innych maszynach, lub usług obsługujących SSL, ale jako osobne procesy to problem przestaje być ważny, prawda? Szczególnie, jeżeli hasła szyfrujemy i w takiej postaci przesyłamy.

Wystarczy wykorzystać mechanizmy zabezpieczające dostęp do pamięci serwera: usługi uruchomione z prawami różnych użytkowników nie maja dostępu do swoich obszarów panięciu. Czyli prawidłowo wykonana praca administratora zabezpiecza serwer przed heartbeat, ponieważ nie da się odczytać obszarów pamięci np.: z hasłami. Przypominam, że SSL zabezpiecza transmisję, a hasła do aplikacji (lub inne metody potwierdzenia praw) stanowią oddzielny mechanizm.

Pojawiały się enigmatyczne teksty o tym, że błąd dotyczy też poczty elektronicznej. Klienta na pewno nie! Klient (oprogramowanie)  nie jest usługą serwerową, nie nasłuchuje na danym porcie i do tego najczęściej i tak jest ukryty za firewallem. Co z serwerem? Wystarczy stosować odpowiednie oprogramowanie (patrz wiekowy qmail), a bramki email-http potraktować tak samo jak inne serwisy http - obsłużyć ssl na osobnej usłudze/maszynie.
Zresztą jak na razie najlepszym zabezpieczeniem dostępu np.: do poczty jest VPN, ale nie łatwe w konfiguracji wynalazki oparte o SSL, tylko prawdziwe VPN oparte o IPSec. Z tym, że i tu w przypadku nieprawidłowej konfiguracji (i posiadania np.: szybkiej karty grafiki) można znaleźć pewne luki. Dlatego trzeba zatrudniać doświadczonych specjalistów :-)

Jeszcze lepsze rezultaty można uzyskać, wprowadzając w firmie pocztę szyfrowaną technikami asymetrycznymi. Przecież dowolnie zabezpieczona poczta SSL, czy nawet i VPN'em chroniona jest tylko na drodze komputerA-serwer i serwer-komputerB - czyli przed podsłuchem gdzieś na łączach. Mając dostęp na prawach administratora  do serwera poczty mamy dostęp do niezaszyfrowanej poczty. Gdy zastosujemy podpisywanie i szyfrowanie poczty technikami asymetrycznymi zyskujemy:
- Nawet gdy ktoś ukradnie nasze hasło do poczty, lub w inny sposób spróbuje wykorzystać słabość systemu pocztowego, to i tak nie jest w stanie podpisać wiadomości naszym podpisem cyfrowym. Od razu będzie wiadomo, że ktoś próbuje wysłać fałszywą wiadomość.
- Wiadomość odszyfrowana (jawna) będzie dopiero dla odbiorcy i nikt po drodze, w żadnym punkcie, nie będzie mieć dostępu do jej jawnej (nie zaszyfrowanej) treści.

Co do przetrzymywania haseł (i loginów) w pamięci operacyjnej w postaci jawnej. Problem ten już pojawiał się przy okazji użytkowników z prawami administratorów, który to mogli robić zrzuty pamięci serwera i szukać ciągów znaków mogących być hasłami (problem złej administracji serwerem lub nieuczciwych administratorów).
Nic jednak nie stoi na przeszkodzie, by programy trzymały hasła w pamięci operacyjnej zaszyfrowane kluczem aktualnym na czas uruchomienia danej instancji programu. Program uruchamia się, generuje losowy klucz i za jego pomocą szyfruje i deszyfruje hasła pobierane od użytkownika, z bazy danych, itp. Skoro hasło przypominało by inne dane binarne to nie ma można go trywialnie odnaleźć.
Tu oprogramowanie z jawnym kodem ma olbrzymią zaletę - od razu widać, czy ktoś zaimplementował techniki ochrony i czy zrobił to poprawnie.