Программа для чтения смарт карт

Программа для чтения смарт карт

Название:
Smart Card ToolSet Pro
Разработчик:
Игорь Харченко
Обновлено:
11.12.2009 00:15
Цена:
Условно-бесплатная, 60 EUR
Русский язык:
Нет
ОС:
XP/2000/2003
Размер:
1.55 МБ
Оценка:

Рейтинг:


Программное обеспечение для XP/2000/2003

Скриншоты
Smart Card ToolSet Pro

WinScan2PDF (Portable) 5.25

Небольшая бесплатная программа для сканирования документов и их сохранения в формате PDF

PaperScan Free 3.0.101

Бесплатное приложение для работы со сканером: сканирование, редактирование, отправка на печать. Поддерживаются любые TWAIN и WIA сканеры

VueScan 9.7.26

Приложение для расширения возможностей по взаимодействию со сканером или цифровой камерой

Домашний термометр 2003

Программа для измерения комнатной температуры с помощью терморезистора, подключенного к игровому порту компьютера

FinePrint 10.22

Значительно расширяет возможности любых принтеров при печати документов: предпросмотр, несколько страниц на одном листе, брошюры, автовставка заголовка и "подвала", создание фирменных бланков и т.п.

Bulldog Flash Tester 0.92 / 0.92.7

Бесплатный инструмент для выявления поддельных карт памяти, USB-флешек, SSD и HDD, а также для проверки любого накопителя на наличие дефектов, задержек доступа, искажений записываемых данных, скорости чтения и записи

USB Image Tool 1.8.0.0

Бесплатное приложение для создания образов USB флэш-накопителей, MP3-плееров, цифровых камер, мобильных телефонов и любых других устройств, подключаемых к ПК как диски USB

FinePrint 10.22

Значительно расширяет возможности любых принтеров при печати документов: предпросмотр, несколько страниц на одном листе, брошюры, автовставка заголовка и "подвала", создание фирменных бланков и т.п.

O&K Print Watch 4.14.0.4879 / 4.9.0.0 Free

Ведет учет печати и использования бумаги — точное число напечатанных страниц, имя пользователя, имя документа, размер бумаги, время печати для каждого задания. Допускает управление очередью печати

WinScan2PDF (Portable) 5.25

Небольшая бесплатная программа для сканирования документов и их сохранения в формате PDF

Отзывы о Smart Card ToolSet Pro

» Оставьте первым свой отзыв об этом приложении.

Сначала, на момент задумки, в 2014 году, данная статья планировалась как единая публикация, но, проработав материал (лень вынудила растянуть этот процесс), я понял, что необходимо её разделить на две части:

  1. Знакомство с библиотекой и написание/разбор кода специального командного процессора, который ее использует.
  2. Использование командного процессора из ч.1 для чтения содержимого файла с симки, которую я, однажды, подобрал на улице (никаких персональных данных раскрыто не будет). Узнаем, как отучить Windows встревать в наше взаимодействие с картой, а также, возможно, затронем тему выбора (активации) системного приложения на карте (если моя экспериментальная карта окажется UICC).

Думаю, для профи-карточников первая часть будет представлять бо́льший интерес, а вторая часть будет интересна, прежде всего, новичкам в этой теме (и будет иметь метку Tutorial).

Среди множества Python-библиотек, обзоры которых есть на Хабре, я не обнаружил pyscard — библиотеки для взаимодействия со смарт-картами.
В этой статье я постараюсь дать краткое описание основных фич pyscard, а на сладкое напишем простенький командный процессор, работающий с картой посредством APDU .
Прошу учесть, что для понимания того, как использовать эту библиотеку, и окружающей терминологии требуется знакомство со стандартом ISO 7816-4 или, хотя бы, GSM 11.11 . К GSM-стандарту проще получить официальный доступ, скачав его с сайта ETSI, впрочем и ISO 7816-4 (pdf, старенькая версия) гуглится, несмотря на то, что за него на оф. сайте хотят денег).

Pyscard существует с 2007 года и является кроссплатформенной (win/mac/linux) надстройкой над PC/SC API.

Мое рабочее окружение, где я использую pyscard — Windows7
Материал данной статьи я тестировал, в основном, на mac OS, но на Windows7 тоже погонял, в виртуалке. Должен отметить, что, в отличие от XP , «семерка» и, вероятно, «десятка», с настройками по умолчанию, «ставит палки в колеса» при работе с картой в ридере:

  1. При помещении каждой карты в ридер эта карта считается устройством Plug&Play, для нее системой «ищутся драйверы».
  2. Если мы дождались окончания п. 1, то система начинает искать на карте сертификаты, при этом общаясь с ней своими APDU, эти APDU смешиваются с нашими и возникают коллизии, приводящие к сбоям в наших программах.

Эти факторы доставили мне много боли при переходе с XP, пока я их не победил. Как это сделать, расскажу во второй части.

Разработка начата под эгидой одного из ведущих (и на момент создания, и сейчас) игроков карточного рынка.
Поддерживаются обе ветки Python (2 и 3).

В рабочем окружении я использую связку pyscard + Python 2.7, но, для статьи, мне показалось правильным задействовать актуальную на сегодня ветку Python (3.6)

На мой взгляд библиотека pyscard спроектирована не особо pythonic и больше напоминает порт какого-то Java фреймворка, однако полезности её это не уменьшает, по крайней мере для меня, хотя имена модулей выглядят странно, конечно.

Точкой входа в библиотеку является пакет smartcard .

Отдельно стоит упомянуть пакет smartcard.scard , который отвечает за связь с карточным API операционной системы. Если не нужны все абстракции библиотеки, а только голый PC/SC , то вам сюда. Мы же на нём подробно останавливаться не будем.

Установка pyscard возможна следующими способами:

  • с PyPi ( pip install pyscard ) — подходит для систем, настроенных на сборку артефактов из исходников, используется swig (ок для mac и, возможно, linux)
  • Из бинарного дистрибутива, который можно забрать c appveyor или c sourceforge (великолепно прокатывает в Windows)

Pyscard имеет информативное руководство пользователя, которое доступно на официальном сайте, pydoc и примеры, поэтому не вижу смысла дублировать все это здесь. Вместо этого мы:

  1. Посмотрим на типовую структуру/шаблон программы;
  2. Бросим взгляд на, по моему мнению, важнейшие объекты библиотеки, что должно убедить пользоваться не низкоуровневым smartcard.scard , а именно smartcard ;
  3. Проиллюстрируем применение библиотеки на реальном примере — напишем командный процессор (шелл) на Python 3.6, где командами будут прямо «APDU в хексе» и ответ с карты будет выводиться в консоль. Также будут поддерживаться текстовые команды exit и atr.

Типовой шаблон программы

Пора уже сделать вброс порции кода, а то всё скучные вступительные «бубубу».

Какие задачи решает (практически любая) программа, работающая со смарт-картами в ридере? А вот эти:

  1. Выбор ридера, с которым мы будем взаимодействовать
  2. Определение момента, когда карта окажется в этом ридере
  3. Установка канала связи с картой
  4. Проверка карты на соответствие нашим критериям (мы можем захотеть работать не с каждой картой, которую пользователь нам подсунет)
  5. Обмен данными с картой посредством APDU
  6. Закрытие канала связи с картой
  7. Определение момента, когда карта будет извлечена из ридера

Замечу, что перечисленные задачи решает, например, прошивка мобильного телефона.

Важнейшие объекты пакета smartcard

В этом разделе все имена указаны относительно пакета smartcard .

Подклассы CardType

Позволяют нам указать точный тип карт, с которыми наше приложение собирается работать. Можно сделать так, чтобы наше приложение даже не реагировало на помещение в ридер карты, которая нам не подходит.

Примеры:

  • CardType.ATRCardType (существует в библиотеке) — фильтрация карт по значению ATR. Наше приложение будет реагировать только на карты с определенным значением ATR.
  • USIMCardType (я нафантазировал, можно реализовать) — допустимыми картами являются только USIM, внутри проверяем возможность выбора USIM-приложения.

CardRequest и его подклассы

Позволяют свести воедино все требования нашего приложения, касающиеся установления связи с картой:

  • строго задать тип карты (см. выше)
  • ограничить список допустимых ридеров (из уже установленных в системе)
  • изменить таймаут ожидания карты в ридере

По умолчанию никаких ограничений в CardRequest не ставится.

CardConnection

Канал коммуникации нашего приложения с картой, позволяет отправлять на карту APDU и получать ответ, ключевой метод здесь — transmit() . Именно с его помощью происходит непосредственное взаимодействие нашего приложения с картой. Необходимо отметить, что метод transmit() всегда возвращает триплет (кортеж), состоящий из:

  • Ответных данных (содержит реальные данные или None , в зависимости от типа APDU, не все APDU возвращают данные)
  • Первого байта статуса (StatusWord) SW1
  • Второго байта статуса (StatusWord) SW2

CardConnection является контекст-менеджером, что добавляет удобства при его использовании.

CardConnectionDecorator

Слово «декоратор» используется здесь в том же контексте, что и в Java, а не в том, к которому привыкли Python-разработчики.
Позволяет придать особые свойства объекту CardConnection . Библиотека предоставляет рабочие декораторы с говорящими названиями: ExclusiveConnectCardConnection и ExclusiveTransmitCardConnection . Лично я не ощутил эффекта от использования этих декораторов — если система (Windows) уж решила вклиниться со своими APDU в нашу сессию, то ни один из этих декораторов не спасет, но, возможно, я что-то не так делал.

Функция System.readers()

Позволяет получить список подключенных к системе кардридеров и установить связь с картой в определенном ридере.

sw.ErrorChecker , sw.ErrorCheckingChain

По умолчанию, в ходе обмена данными между картой и нашего приложением, никакие ошибочные значения StatusWord (SW1, SW2) не возбуждают исключений. Это можно изменить, задействовав потомков ErrorChecker , которые:

  • объединяются в последовательности sw.ErrorCheckingChain
  • привязываются к CardConnection и проверяют на отсутствие ошибок результат каждого вызова метода transmit() .
    Встроенные в библиотеку «чекеры» позволяют получить в исключении подробную информацию о проблеме без необходимости залезать в спеки и искать необходимые значения SW1 , SW2 .

Потомки CardConnectionObserver

Присоединяются к экземпляру CardConnection и получают информацию обо всех командных APDU и ответах карты, которые проходят через наблюдаемое соединение. Пример применения — ведение лога команд и ответов от карты.

Вооруженные таким знанием, мы вполне можем замахнуться на написание командного процессора, использующего описываемую библиотеку.

Командный процессор с APDU (CLI)

Не буду подробно останавливаться на модуле cmd, который любезно предоставляет нам стандартная библиотека, о нем уже писали здесь, перейду к реализации.

Весь исходный код процессора находится на гитхабе.
Пройдемся по главным моментам, не размениваясь на мелочи.

Функция select_reader()

Возвращает первый ридер, подключенный к компьютеру или None , если подключенных ридеров нет.

Есть вариант этой функции (зависит от модуля msvcrt, т.е. только для Windows), который позволяет выбрать ридер, если их в компьютере несколько.

Класс APDUShell

Данный класс, помимо наследования от cmd.Cmd , реализует интерфейс обладает поведением наблюдателя smartcard.CardMonitoring.CardObserver

Данные экземпляра нашей оболочки

reader — устройство чтения, с которым будем работать.
card — объект карта, потребуется нам, чтобы определить момент смены карты в ридере.
connection — канал передачи APDU на карту и получения результата обработки.
sel_obj — строка, содержащая ID текущего объекта (файла или папки) выбранного командой SELECT . Эта строка меняется всякий раз, когда команда SELECT выполняется.
atr — здесь мы запоминаем ATR текущей карты, чтобы можно было вывести его на экран, не запрашивая карту каждый раз (такой запрос сбрасывает состояние выбора файла в карте).
card_connection_observer — наблюдатель, который привязывается к каждому connection, подробности ниже.

В конструкторе

Мы, помимо инициализации данных, добавляем себя в наблюдатели
smartcard.CardMonitoring.CardMonitor — объекта, который реагирует на события взаимодействия ридера и карты (карта помещена в ридер, карта извлечена из ридера) и оповещает об этих событиях smartcard.CardMonitoring.CardObserver , т.е. нас. Данный вид оповещения настраивается только один раз за время жизни нашей оболочки. CardMonitor является синглтоном, поэтому мы не заботимся о времени жизни его экземпляра.
Также обращаю внимание на экземпляр smartcard.CardConnectionObserver.ConsoleCardConnectionObserver — это готовый библиотечный объект-наблюдатель, отслеживающий состояние канала общения с картой и печатающий это состояние в консоль. Мы его будем навешивать на каждое новое соединение с картой.

update()

Это, собственно, поведение smartcard.CardMonitoring.CardObserver . Если наша текущая карта находится в списке removedcards , то мы очищаем состояние оболочки для текущей карты.
Если в нашем выбранном ридере (и в списке addedcards , заодно) появилась новая карта, то мы инициализируем новое состояние оболочки для этой карты.

default()

Здесь все введенные пользователем шестнадцатиричные APDU превращаются в списки байтов и отправляются на карту. Замечу, что единственное, что мы делаем с результатом здесь, это определяем, не является ли отправленная команда успешным SELECT -ом. Если да, то мы обновляем ID последнего выбранного объекта для печати в приглашении пользователю.
Всю остальную рутинную работу по интерпретации и отображению результата команды для пользователя выполняет наш ConsoleCardConnectionObserver .

Небольшое попутное отступление
лично мне не очень нравится, как ConsoleCardConnectionObserver отображает результат исполнения APDU — он не отделяет SW от результирующих данных так, как мне этого хотелось бы. Я использовал его только, чтобы не захламлять код примера маловажными деталями. Однако, если кому-то интересно, код метода update() моего наблюдателя есть в этом коммите.

_set_up_connection()

Трудяга, который помогает нам каждый раз, когда карта в ридере меняется. Он создает соединение с картой, навешивает на него ConsoleCardConnectionObserver , и запоминает ATR карты (чтобы команда atr могла вывести его на экран).

_clear_connection()

Антипод _set_up_connection() , «проводит зачистку», когда карта извлечена из ридера.

Заключение

На данном этапе мы можем запустить нашу командную оболочку и, в зависимости от наличия кард-ридера, получить просто сообщение об ошибке (ридера нет) или увидеть шелл в работе (счастливчики с ридером). При наличии ридера ничто не мешает вставить в него любую смарт-карту и выполнить команду atr — должно сработать, однако, прошу не забывать, что на своих рабочих SIM и банковских картах вы экспериментируете на свой страх и риск.

До встречи во второй части, предполагаю, что там Python-а не будет (почти или совсем), но будут APDU и SW.

Инструкция по предварительной настройке сервиса доступна тут.

Сервис учета Cafe Manager имеет возможность интеграции с бесконтактными смарт-картами (NFC). Ознакомиться с видео-обзором поддержки смарт-карт можно тут. К компьютеру администратора заведения подключается USB-считыватель смарт-карт, при поднесении карточки к которому, система предлагает открыть новый заказ с нужным номером карты или, если заказ уже открыт, предлагает его закрыть или внеси в него изменения.

Сервис поддерживает работу с USB NFC-считывателями и смарт-картами. Вы можете приобрести их в любом магазине и самостоятельно настроить их работу, следуя данной инструкции. У нас вы можете приобрести как сами смарт-карты, так и NFC считыватель ACR122U, который мы рекомендуем использовать. Ознакомиться с каталогом оборудования и ценами можно тут: https://cafe-manager.ru/price/

Также имеется возможность интеграции сервиса с QR-кодами. Инструкция по настройке системы доступна по тут.

Видео-обзор работы смарт-карт:

Инструкция по интеграции

Подготовка системы
Если Вы используете операционную систему Windows 7 или Windows XP, то перед первым подключением USB-считывателя вам потребуется установить драйвер для устройства. Для операционных систем Windows 8,8.1 и 10 устанавливать драйвер не требуется. Для считывания данных с карт, а также их программирования используется бесплатное программное обеспечение – GoToTags или наша собственная разработка Cafe Manager Desktop. Все перечисленное программное обеспечение поддерживает самые современные операционные системы семейства Windows.

Для начала вам необходимо включить поддержку работы со смарт-картами в собственном аккаунте Cafe Manager. Это можно сделать в разделе Меню > Настройки > Поддержка карт. После включения данной опции для вашего аккаунта будет сгенерирован восьмизначный Код доступа, который потребуется нам в дальнейшем.

Существует два варианта настройки работы со смарт-картами:
1. Использовать программу Cafe Manager Desktop — данный вариант максимально прост в настройке. Инструкция по настройке данного варианта.
2. Использовать программу GoToTags — этот вариант потребует несколько дополнительных минут для настройки, но является более функциональным. Если вы уверенный пользователь ПК, то попробуйте данный вариант. Если у вас появятся вопросы вы всегда можете обратиться в нашу службу поддержки. Инструкция по настройке этого варианта находится на этой странице ниже.

Установка и настройка
1. Скачайте и установите на свой компьютер программу GoToTags.
2. Скачайте и разархивируйте в любую доступную вам директорию модуль GTT Connector (например, D:GTT или любую другую директорию, для которой у вас есть права на запись).
3. Подключите считыватель к компьютеру и запустите программу GoToTags. Убедитесь, что ваш считыватель подключен к компьютеру и обнаружен программой. Об этом говорит надпись ACS ACR122 в интерфейсе программы.

4. Зайдите в раздел Integration > External app > Choose External app и в появившемся окне укажите пусть до файла GTT Connector.exe. То есть D:GTTGTT Connector.exe или другой директории, в которой вы разместили файл GTT Connector.exe.
5. Зайдите в раздел Integration > Results file > Choose file и в появившемся диалоговом окне укажите, что вы хотите сохранить файл result.txt в ту же директорию, где находится файл GTT Connector.exe.
6. Программа GoToTags должна быть запущена каждый раз, когда вы планируете работать со смарт-картами. Если вы хотите, чтобы данная программа запускалась автоматически вместе с Windows, то зайдите в меню App и активируйте опцию Auto start on system startup. В этом же разделе можно отключить звуковое сопровождение при работе со смарт-картами, для этого выключите опцию Play sound.

На этом настройка программного обеспечения завершена и нам осталось только запрограммировать смарт-карту.

Программирование карт
Перед первым использованием карты ее необходимо запрограммировать для работы с вашим аккаунтом Cafe Manager. Для этого запустите утилиту GoToTags, которую мы установили и настроили на предыдущем этапе. Чтобы запрограммировать новую смарт-карту нажмите значок Add a New Record (крайний слева) и выберите пункт Uri.

В новом окне необходимо ввести информацию в следующем формате: http://demo.cafe-manager.ru/card/?d7eb120b&10 Где, demo.cafe-namager.ru – адрес вашего Cafe Manager, d7eb120b — Код доступа (его можно узнать в аккаунте Cafe Manager в разделе Меню > Настройки > Поддержка карт), а 10 – номер карты, который вы сами решили ей назначить.


Нажмите ОК и далее кнопку Encode NFC Tags( ), чтобы записать данные в карту. Программа попросит вас поднести к считывателю смарт-карту, в которую необходимо записать эту информацию. Положите смарт-карту на считыватель на несколько секунд и дождитесь сообщения о том, что данные успешно записаны.


Программирование карты завершено. Ей присвоен номер 10, и больше настраивать ее не требуется. При поднесении этой карты к считывателю, будет появляется предложение открыть заказ на карту номер 10. Чтобы запрограммировать другую карту повторите все те же действия, только вместо 10 укажите любое другое число, например 11.

Данные в карте могут быть перезаписаны неограниченное количество раз. Также, Вы можете хранить в карте какую- то дополнительную информацию, на свое усмотрение. Для этого воспользуйтесь другими разделами в меню Add a New Record.

Использование карты
Рассмотрим типовую ситуацию по использованию карты. Программа GoToTags должна быть всегда запущена на компьютере администратора заведения, если подразумевается работа со смарт-картами (допускается ее сворачивание в системный трей). Когда в заведение приходит новый клиент, то менеджер берет любую из имеющихся у него на руках смарт-карт (или получает карту от посетителя, если в вашем заведении они являются именными и пользователь не сдает смарт-карту, когда покидает заведение) и подносит ее к считывателю. Система получает информацию из карты и в браузере, на странице где у вас был открыт сервис Cafe Manager, открывается страница создания нового заказа с нужным номером карты. Если для данной смарт-карты указаны скидки, то они автоматически будут применены к этому заказу. По завершению посещения клиент отдает карточку менеджеру, который снова подносит ее к считывателю. Система отобразит страницу-профиль данного заказа и его можно будет отредактировать или закрыть для произведения расчета с посетителем.

Видео, демонстрирующее программирование смарт-карт и работу с ними доступно тут: http://www.youtube.com/watch?v=5FrzA44MOjk

QR-коды

Вместо смарт-карт вы можете использовать QR-коды. Этот вариант является более бюджетным, так как вам не требуется приобретать считыватель и сами смарт-карты. Для работы с QR-кодами вам потребуется веб-камера, с помощью которой вы будете считывать коды, а также сами QR-коды.
1. Скачайте и установите программу QuickMark.
2. Запустите QuickMark, зайдите в раздел Настройки > Action и активируете опцию Open URL.
3. На этом приготовления закончены и вам осталось только создать "правильный" QR-код. В коде вам нужно зашифровать ту же информацию, что записывается в смарт-карты во втором пункте данной инструкции. Создать QR-код можно с помощью любой программы или сервиса, например, можно использовать сервис www.qrcoder.ru. QR-код нужно распечатать и поднести к веб-камере для открытия заказа. Дополнительную информацию вы всегда можете получить в нашей службе поддержки.

1. C какими NFC-картами и считывателями работает Cafe Manager?
Система работает со всеми картами, которые соответствуют стандарту NFC. Официально протестированными являются считыватель ACR122U и смарт-карты Mifare 1K, который мы и рекомендуем использовать в работе. Со списком оборудования, которое поддерживается программой GoToTags можно ознакомиться тут.

2. Будет ли реализована поддержка RFID-карт?
Нет, поддержка данного типа карт не планируется, так как NFC является более прогрессивной технологией. Но, мы можем предоставить API и все необходимые инструменты для того, чтобы вы самостоятельно реализовали эту интеграцию. По вопросам доступа к API необходимо обратиться в нашу службу технической поддержки.

3. С системой будут работать только считыватель и карты приобретенные у Вас?
Нет, будет работать любое оборудование, которое соответствует стандарту NFC и настроено в соответствии с этой инструкцией.

4. Для чего нужен Код доступа?
Данный параметр используется для обеспечения требуемого уровня безопасности. При осуществлении сброса Кода доступа в разделе Настройки, все ранее выпущенные и запрограммированные карты перестанут работать до того момента, пока вы их не перепрограммируете с новым Кодом доступа.

5. Взимается ли какая-то дополнительная плата за использование смарт-карт?
Нет, данный функционал является полностью бесплатным. Единственные расходы, которые от вас потребуются, связаны с приобретением необходимого оборудования у нас или в любом, удобном для Вас магазине. Вам потребуется один NFC-считыватель, а также некоторое количество смарт-карт, которое зависит от посещаемости заведения. Единственное ограничение, которое накладывает бесплатная программа GoToTags — в сутки можно осуществить первичное программирование не более 50 карт. К сожалению, мы не можем повлиять на данное ограничение, так как не является разработчиками программы GoToTags. Но вы можете воспользоваться нашей программой Cafe Manager Desktop, которая является полным аналогом GoToTags и лишена данного ограничения.

6. Какие системные требования предъявляются к компьютеру, на котором будет работать считыватель?

Если вам требуется поддержка Windows XP/Vista, то вы можете воспользоваться нашей программой Cafe Manager Desktop, которая является альтернативой GoToTags.

7. Ошибка "Unable to connect to the internet; check your internet connectivity and try again."
Если при запуске приложения GoToTags появляется сообщение об ошибке "Ubable to connect to the internet; check your internet connectivity and try again.", то это означает, что программа не может получить доступ к Интернету, который нужен ей для запуска.
Для устранения ошибки необходимо выполнить следующие шаги:

Читайте также:  Лучший ноутбук для серфинга интернета
Ссылка на основную публикацию
Программа для отформатировать флешку
Процесс форматирования флешки мало отличается от форматирования HDD или SSD-дисков. Далее мы рассмотрим лучшие программы для форматирования флешек (такие как...
Приложение следить за человеком по номеру телефона
Отслеживание по номеру телефона - это приложение для Android, благодаря которому вы всегда будете знать где находятся ваши родные и...
Приложение чтобы играть андроид игры на компьютер
Самый мощный эмулятор Android из всех Newest ReleaseВерсия 7.1.3 2020.03.04 Играйте бесплатно в любые игры для Android. Наслаждайтесь оптимизированной графикой...
Программа для оцифровки винила
Каталог продаваемых пластинок (49230) Минимальные аппаратные требования, или что надо иметь для оцифровки Компьютер со звуковой картой. Проигрыватель винила Корректор...
Adblock detector