Skocz do zawartości

Rekomendowane odpowiedzi

Wm-login — skrypt na logowanie
Wersja: R3

Wymagania:
- Skript
- SkBee
- SkQuery

✅ -  wykonane, nie wydane

Co planuję:

- Informacja o aktualizacji dla operatorów ✅
- Wyrzucanie Multikont z tego samego IP (Ilość będzie można skonfigurować)
- Cooldown wiadomości w wybranych światach

- Konfiguracja przez gui
- Anti-VPN (do 100 osób dziennie)✅
- Wymaganie ponownego wysłania niektórych komend, aby potwierdzić

- Blokowanie niszczenia i stawiania bloków przed zalogowaniem ✅
- Wyrzucanie graczy z nieodpowiednimi znakami w nicku
- Komenda /email

- Zapobieganie tabowania przed zalogowaniem
- Blokowanie określonych komend
- Możliwość używania ustalonych poleceń przed zalogowaniem
- Naprawie nie teleportowania na lokalizację lobby po pierwszym dołączeniu ✅


Co zmieniono:
- Zastąpiono changepass na unregister w komendach admina dla większego bezpieczeństwa
- Dodano komendę /clearchat

- Naprawiono nieśmiertelność złowrogich mobów
- Naprawienie wyrzucania gracza, który jest już na serwerze

Funkcje:
- Nie jest maszynką do kradzieży haseł
- Logowanie za pomocą wpisywania hasła na czacie
- Blokowanie komend, ruchu gracza, gdy nie jest zarejestrowany/zalogowany
- Informacje w konsoli o logowaniu/rejestrowaniu gracza
- Efekt ślepoty po dołączeniu
 

Komendy:
• /autologin - Auto logowanie dla aktualnego IP
• /changepass - Zmienia hasło

• /unregister - Wyrejestrowuje gracza
• /logout - Wylogowuje gracza
• /wm-admin - Komendy administracyjne
• /wm-l-admin - Komendy administracyjne na konsolę
• /spawn - teleportuje na spawn (Cooldown w ustawieniach)
• /lobby - teleportuje na lobby (również po dołączeniu na serwer)
• /adminchat - adminchat

/clearchat - czyści czat

Permisje:
- wm-login.adminchat.use
- wm-l.admin

https://code.skript.pl/hLjj602u

Edytowane przez milonn
Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/
Udostępnij na innych stronach

"Skrypt nie jest maszynką do kradzieży haseł" też Pan: zapisuje hasło gracza w jednej zmiennej {Wm-login::%player's uuid%-has} którą można łatwo sprawdzić:

command /check [<player>]:
    trigger:
        send "Haslo gracza %arg 1%: %{Wm-login::%player arg's uuid%-has}%

Przykładowy skrypt który sprawdza hasło gracza :)

Edytowane przez Hiri12
Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342194
Udostępnij na innych stronach

@milonn

Co prawda skrypt ma wiele błędów i usterek, ale odniosę się do tych najbardziej krytycznych/rażących.

21 minut temu, milonn napisał:

- Nie jest maszynką do kradzieży haseł

To nie jest prawda i to jest Pana największy grzech. Pan zapisuje hasła użytkowników do zmiennych w postaci niezmodyfikowanego tekstu.
Jeśli ktoś nieupoważniony uzyska dostęp do plików serwera, może równie dobrze pobrać kopię bazy danych czy też pliku variables.csv i wtedy konta wszystkich użytkowników będą zagrożone.

Zdaje się, że Pan pytał około tydzień temu jak sprawić, aby taki skrypt miał zabezpieczone hasła. Powiedziałem Panu, że dobrym rozwiązaniem będzie hashowanie haseł. Nie rozumiem dlaczego Pan tego nie wdrożył.

26 minut temu, milonn napisał:

/autologin - Auto logowanie dla aktualnego IP

Rozumiem, że to jest swego rodzaju ukłon w stronę graczy, ale w mojej ocenie wystarczyłby jedna zmienna automatycznego logowania na jedno konto.
Trzeba mieć na uwadze to, że niektórzy gracze mogą korzystać z internetu mobilnego lub po prostu mieć router, który zmienia adres IP każdorazowo przy resecie. Nie zapominajmy również o proxy i VPN.

30 minut temu, milonn napisał:

/wm-login-admin - Opcja beta, niedopracowana

Jeżeli coś jest niedopracowane, nie powinien Pan tego dodawać do skryptu. Zamiast tego lepszym podejściem byłoby dopracowanie tej komendy i dodanie jej do kodu przy aktualizacji skryptu.

Brakuje jeszcze informacji o tym jakie dodatki są wymagane do działania skryptu. Zdarzenie 'on any movement' to element składni dodatku SkQuery.
Nie ma jednak potrzeby korzystania z niego, gdyż Skript posiada swoje własne zdarzenie odpowiadające mu. Mówię o tym zdarzeniu.

 

No dobrze, a teraz odnieśmy się do samego kodu.

  1. W kodzie można uświadczyć wiele zagnieżdżonych warunków, które zmniejszają czytelność kodu. Pokażę Panu jak można je poprawić.
    # Zły sposób:
    if [warunek]:
    	if [warunek]:
    		if [warunek]:
    			# Dalszy kod...
    		else:
    			# Alternatywny kod
    	else:
    		# Alternatywny kod
    else:
    	# Alternatywny kod
        
    # Dobry sposób (odwracanie warunków):
    if not [warunek]:
    	# Alternatywny kod
    	stop
    if not [warunek]:
    	# Alternatywny kod
    	stop
    if not [warunek]:
    	# Alternatywny kod
    	stop
    # Dalszy kod...

    Myślę, że powyższy przykład jest dla Pana wystarczająco przekonujący.

  2. Z niezrozumiałych mi powodów Pan używa w kodzie bardzo dużo opóźnień, czasem w miejscach, w których nie mają żadnego sensu.
    Proszę mieć na względzie to, że dobry kod powinien posiadać możliwie mało opóźnień. Wynika to z tego, że wszelkie opóźnienia są czyszczone przy wyłączeniu serwera, a więc kod po nich następujący nigdy nie zostanie wykonany. Można podążać za następującą regułą - jeśli nie ma potrzeby odliczania lub celowego opóźnienia kodu w celu polepszenia wrażeń z użytkowania skryptu (proszę interpretować wedle uznania), niech Pan nie używa opóźnień.
    Nie rozumiem na przykład dlaczego Pan wstawił opóźnienia przed zapisem zmiennych. Nie pojmuję również tego dlaczego Pan wstawił w pętlach 'while' opóźnienia trwające 14 dni, choć możliwe, że wynika to tylko i wyłącznie z tego title mającego trwać lata. Niemniej jednak, skłaniam Pana do refleksji w tej kwestii.
  3. Nie ma potrzeby rozdzielania listenera zdarzenia 'on join' na dwa osobne listenery. Czyni to kod mniej czytelnym.
    Jeśli Pan usunie z drugiego listenera te 2-sekundowe opóźnienie, będzie mógł Pan spokojnie połączyć oba te listenery.
  4. Przy rejestracji Pan w dziwny sposób sprawdza czy ilość znaków w haśle mieści się w dozwolonym zakresie. Zamiast dodawać i odejmować 1, proszę zastosować operatory porównania '>=' i '<='.

 

Proszę nie brać moich uwag jako złośliwości z mojej strony, a przyjąć je z pokorą i postarać się poprawić ten skrypt.

Pozdrawiam.

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342195
Udostępnij na innych stronach

Ok, dopracuję to. Czy zapisywanie haseł zaszyfrowanych w postaci SHA-256 powinno to bardziej zabezpieczyć?
Autologin jest zrobione w sposób również zabezpieczony. Gdy ktoś inny z innym IP będzie chciał się włamać na konto to go nie zaloguje automatycznie.

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342198
Udostępnij na innych stronach

30 minut temu, milonn napisał:

Ok, dopracuję to. Czy zapisywanie haseł zaszyfrowanych w postaci SHA-256 powinno to bardziej zabezpieczyć?

Nie zaszyfrowanych, a hashowanych. Jest to ogromna różnica.
Coś zaszyfrowanego zawsze można odszyfrować jeśli zna się sam mechanizm danego szyfru, więc jest to operacja wykonywalna w obie strony.
Hashowanie natomiast jest operacją nieodwracalną, działa tylko w jedną stronę. Mając jakieś dane możemy łatwo wyznaczyć ich hash, w drugą stronę jest to z praktycznego punktu widzenia niemożliwe biorąc pod uwagę moc obliczeniową dzisiejszych komputerów. Oczywiście istnieje jeszcze prawdopodobieństwo kolizji hashów (dwie różne wartości wejściowe mające taki sam hash), ale jest ono na tyle niskie w przypadku SHA-256, że po znalezieniu jej Pan stałby się sławny.

Jest jeszcze opcja hashowania funkcją MD5, ale odradzam korzystania z niej. Jest to zdecydowanie mniej bezpieczny algorytm, podatny na wyżej wspomniane kolizje hashów.

Ponieważ funkcja hash jest funkcją działającą tylko w jedną stronę, należy poddać wiadomość napisaną przez gracza hashowaniu i porównać wynikowy hash wiadomości z wartością zmiennej przechowującej hash hasła gracza.

30 minut temu, milonn napisał:

Autologin jest zrobione w sposób również zabezpieczony. Gdy ktoś inny z innym IP będzie chciał się włamać na konto to go nie zaloguje automatycznie.

Ja rozumiem Pana działanie i po przemyśleniu sprawy zgadzam się z Panem. Po prostu pokazałem drugą stronę medalu takiego rozwiązania i fakt, że takie podejście w przypadku graczy ze zmiennym IP tworzy w konsekwencji wiele niepotrzebnych zmiennych w bazie.

Na Pana miejscu stworzyłbym jakąś zmienną gracza zapisująca adres IP, na którym się ostatnio logował na serwer (na przykład 'set {autoLogin::%player's uuid%} to player's ip').
Jeśli przy dołączeniu adres jest inny niż ostatnio, autologin nie następuje. Wtedy zmienna od autologinu będzie posiadała w nazwie tylko UUID gracza, a zapisywanie w nazwie dodatkowo adresu IP będzie już niepotrzebne.

Edytowane przez Kormic
Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342200
Udostępnij na innych stronach

Zaktualizowałem do wersji B2.0 :)

W następnej aktualizacji postaram się dopracować zabezpieczenia i komendy admina.

Czy chcecie, żeby komendy admina typu forcelogin, changepass mogła wykonywać tylko konsola czy gracze też?

Edytowane przez milonn
Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342218
Udostępnij na innych stronach

30 minut temu, milonn napisał:

Zaktualizowałem do wersji B2.0

Mógłby Pan powiedzieć co się zmieniło w tej wersji?
Dobrym zwyczajem jest podawanie listy nowości i zmian. Dzięki temu użytkownicy wiedzą co tak właściwie uległo zmianom.

32 minuty temu, milonn napisał:

W następnej aktualizacji postaram się dopracować zabezpieczenia i komendy admina.

W mojej ocenie zabezpieczenia powinny mieć dla Pana najwyższy priorytet i do czasu ich poprawienia nie powinien Pan wypuszczać aktualizacji. W końcu to jest skrypt zarządzający hasłami.

33 minuty temu, milonn napisał:

Czy chcecie, żeby komendy admina typu forcelogin, changepass mogła wykonywać tylko konsola czy gracze też?

Według mnie gracze z odpowiednią permisją również powinni mieć dostęp do tych komend.

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342219
Udostępnij na innych stronach

1 godzinę temu, milonn napisał:

Pytanie:
Jak usunąć hashowaną zmienną?

Nie rozumiem pytania. Każdą zmienną usuwa się w ten sam sposób, konkretniej za pomocą tego efektu (clear/delete).

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342221
Udostępnij na innych stronach

10 minut temu, milonn napisał:

no mam błąd:
hash of {zmienna z hasłem gracza} nie może zostać usunięta

Widzę, że Pan nie zajrzał do dokumentacji. Proszę się z nią zapoznać.

Zmienna przechowująca hash może być wyczyszczona tak samo jak dowolna inna zmienna.

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342224
Udostępnij na innych stronach

Dodam jeszcze dwie rzeczy od siebie:

1. Jako że sha256 jest mocno przestarzały i nietrudny do odhashowania, warto to hasło dodatkowo zasaltować i przepuścić przez kilka iteracji hashowania. Oczywiście najlepszą opcją byłoby użycie nowszego algorytmu, np. argona, lecz skript tego nie wspiera.

2. Aktualnie w twoim skrypcie możliwe jest poruszanie się przed logowaniem, ponieważ PlayerMoveEvent jest bypassowalny. Rozwiązaniem jest wymienienie tego eventu na porównywanie lokalizacji w timerze.

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342230
Udostępnij na innych stronach

u mnie wszystko działa

 

 

Nowy upadate!

 

W dniu 5.05.2024 o 08:43, Helios1993 napisał:

2. Aktualnie w twoim skrypcie możliwe jest poruszanie się przed logowaniem, ponieważ PlayerMoveEvent jest bypassowalny. Rozwiązaniem jest wymienienie tego eventu na porównywanie lokalizacji w timerze.

Zapomniałem dodać wymagania skryptu, ale teraz już są

Glicz

Łączę posty.

Notatka dodana przez Glicz

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342231
Udostępnij na innych stronach

4 godziny temu, Helios1993 napisał:

Jako że sha256 jest mocno przestarzały i nietrudny do odhashowania

Nie zgodzę się z tym stwierdzeniem. Funkcje hashujące z rodziny SHA-2 są bezpieczne, ale tak długo jak są użytkowane w prawidłowy sposób. To samo tyczy się wszystkich innych dostępnych algorytmów.
Ewentualny brak bezpieczeństwa wynika z winy osoby projektującej mechanizm logowania, nie z winy samej funkcji.

Oczywiście wyjątkiem od tej zasady są wadliwie skonstruowane algorytmy jak chociażby wyżej przywołany przeze mnie MD5.

Wiem, że jest to czepianie się z mojej strony, ale nie istnieje taki termin jak "odhashowanie", bo sugerowałoby to istnienie funkcji odwrotnej do funkcji hashującej.

4 godziny temu, Helios1993 napisał:

warto to hasło dodatkowo zasaltować

Zauważyłem, że nie napisałem o dorzucaniu soli do hasła przed hashowaniem. Mój błąd i dziękuję za poprawienie nie wprost.

Do Pana piszącego ten skrypt - w dużym skrócie sól to szereg losowo wygenerowanych przy rejestracji (w kryptologicznie bezpieczny sposób) znaków, które są dodawane do hasła tuż przed hashowaniem. Wtedy w bazie danych (w Pana przypadku jest to plik variables.csv) przechowywana jest sól i hash.

Jakie jest uzasadnienie użycia soli przy hashowaniu?
Największym zagrożeniem dla bazy z hasłami jest niemałe ryzyko występowania takich samych haseł. Nietrudno sobie wyobrazić grupę użytkowników, którzy z lenistwa ustawią sobie hasło "123456789". Jeśli ktoś nieupoważniony ze złymi zamiarami i głową na karku dostanie się do bazy, przy odnalezieniu faktycznego hasła dla jednego hashu od razu uzyskuje dostęp do kont wszystkich użytkowników z tym samym hasłem.

Dlatego sól jest ważna, bo dzięki niej mamy przynajmniej pewność, że pary (sól, hash hasła) są unikalne, co zdecydowanie zwiększa bezpieczeństwo.

Dodam, że sól powinna być możliwie długa - ponieważ wynikiem algorytmu SHA-256 jest 32-bitowy ciąg znaków (a więc po prostu 32 znaki), zaleca się dodawanie soli zbudowanej również z 32 znaków.
Dodatkowo, nie powinna być ona generowana poprzez zwykły generator losowych liczb (znaków). Do tego zadania sprawdzi się klasa 'java.security.SecureRandom', która dokłada wszelkich starań, aby wygenerowany ciąg bajtów (znaków) był unikalny.

4 godziny temu, Helios1993 napisał:

i przepuścić przez kilka iteracji hashowania

Jeśli mowa o spowolnieniu poszukiwań oryginalnego hasła, zysk w tym przypadku jest niewielki. Istnieją lepsze sposoby, aby tego dokonać.
Na końcu mojego postu załączę artykuł, z którego swego czasu się uczyłem o hashowaniu i są tam zaprezentowane możliwe rozwiązania tego problemu.
 

Kończąc mój wywód, Skript sam w sobie nie nadaje się do przechowywania haseł. Przykładem tego jest chociażby brak wsparcia dla generowania soli, o której notabene sami twórcy wspominają w dokumentacji.
Oczywiście da się to napisać, jednak pojawiają się tutaj przez to dodatkowe trudności.

Udostępniam również link do artykułu, o którym wspomniałem: https://crackstation.net/hashing-security.htm

Pozdrawiam.

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342243
Udostępnij na innych stronach

Co na celu ma pętla while z "wait 14 day"? Pomijając fakt, że fajnie by było odmienić słowo day na liczbę mnogą, to jaki jest tego cel? Nikt nie będzie siedzieć na serwerze 2 tygodnie i czekać na kolejną wiadomość xd, niepotrzebna pętla tylko.

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342291
Udostępnij na innych stronach

W dniu 5.05.2024 o 08:43, Helios1993 napisał:

1. Jako że sha256 jest mocno przestarzały i nietrudny do odhashowania, warto to hasło dodatkowo zasaltować i przepuścić przez kilka iteracji hashowania. Oczywiście najlepszą opcją byłoby użycie nowszego algorytmu, np. argona, lecz skript tego nie wspiera.

Jeszcze taka jedna informacja, sha256 to algorytm hashujący dane - a czym jest hashowanie? jest to operacja jednostronna:p

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342300
Udostępnij na innych stronach

Godzinę temu, kerpson napisał:

Jeszcze taka jedna informacja, sha256 to algorytm hashujący dane - a czym jest hashowanie? jest to operacja jednostronna:p

Owszem, z definicji funkcja hash to taka funkcja, która nie posiada funkcji odwrotnej, a więc z definicji odzyskanie danych wejściowych nie jest możliwe. Dlatego używanie terminu "odhashowanie" jest nieprawidłowe i zwróciłem wcześniej na to uwagę.
Rozumiem jednak, że Helios tutaj zastosował pewien skrót myślowy. W dodatku wniósł kilka ważnych spraw do dyskusji.

Problem leży w tym, że jeśli na ustawianie hasła gracza nie zostaną narzucone odpowiednie warunki (chociażby długość hasła i konieczność zawierania w nim poszczególnych znaków) i administrator nie dołoży wszelkich starań, aby utrzymać możliwie wysoki standard bezpieczeństwa, wiele haseł może zostać odnalezionych metodą brute-force.
Oczywiście, pod uwagę również należy chociażby brać ataki typu pre-image oraz ataki z użyciem tablic tęczowych (ang. rainbow tables). Właśnie w celu uczynienia ich daremnymi zalecane jest stosowanie soli przy hashowaniu.

Ponownie odsyłam do lektury artykułu, do którego link podałem wyżej.

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342301
Udostępnij na innych stronach

Również dodam od siebie kilka adnotacji.

Cytat

{Wm-login::%player's uuid%-%player's ip%-autolog}

Taki układ zmiennej nie pozwoli w łatwy sposób zarządzać IP danego użytkownika, czy chociażby je usunąć bez znajomości całego adresu. Według mnie, poniższy schemat jest o wiele lepszy i pozwoli na łatwiejsze manipulacje danymi. To samo tyczy się raczej większości Twoich zmiennych.

{Wm-login::%player's uuid%::autolog::%player's ip%}

 

Kolejna kwestia,

Cytat

    if {Wm-login::reg-%player's uuid%} is not set:
        set {Wm-login::reg-%player's uuid%} to false
    if {Wm-login::%player's uuid%-%player's ip%-autolog} is not set:
        set {Wm-login::%player's uuid%-%player's ip%-autolog} to false

raczej nie ma sensu zapychać pamięci niepotrzebnymi zmiennymi. Zamiast przy wejściu na serwer ustawiać je na false (czyli de facto operować na zmiennej bool: is true/is false), można skorzystać z usuwania zmiennych podczas wychodzenia z serwera. Wtedy wystarczy sprawdzać, czy istnieje (is set) lub czy jest true (is true / is not true). Drobna zmiana, ale gdy graczy będzie dużo może trochę zaoszczędzić pamięci w pliku ze zmiennymi, co pozwoli na jego szybszy odczyt itp.

 

Z tego co widzę, skrypt nadal zawiera niepotrzebne pętle while oraz wait 14 days, mimo, że wersja się zmieniła. Nie jestem również przekonany co do wysyłania title na tak ogromne ilości czasu, bo może się to bugować, ale jeśli działa to ok.

W listenerze on chat (linia 63) powtarza się dwa razy ten sam warunek, można go wyciągnąć przed wszystkie warunki i wtedy nie musisz się powtarzać. 

Cytat

if {Wm-login::log-%player's uuid%} is false:

 W kodzie nie znalazłem również nic na temat obrażeń. Jeśli gracz nie może się ruszać, to inni gracze z łatwością mogą mu sprawić niemiłą niespodziankę. 

 

Ostatnim tematem poruszonym przeze mnie będzie event on any movement. Wykonuje się on zdecydowanie zbyt często (choć nie tak często jak w przypadku jego "starej wersji" z któregoś tam dodatku) i sprawdza warunek setki razy na minutę - to też do poprawy. Moim proponowanym rozwiązaniem jest ustawienie prędkości gracza na 0 oraz zablokowanie mu eventu skakania. Kiedyś próbowałem coś takiego uzyskać, skorzystałem wtedy ze Skript reflect, nie pamiętam dlaczego, ale było to dawno. Możliwe, że teraz da się to uzyskać już w samym Skript.

{_p}.setWalkSpeed(0) #zablokowanie ruchu gracza
{_p}.setWalkSpeed(0.2f) #przywrocenie domyslnej predkosci

import:
	com.destroystokyo.paper.event.player.PlayerJumpEvent
on PlayerJumpEvent:
	# warunek
		event.setCancelled(true)

 

Odnośnik do komentarza
https://skript.pl/temat/57468-wm-login-%E2%80%94-skrypt-na-logowanie/#findComment-342302
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Nieaktywny
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...