• Как сделать Detached GOST R 34.10 CMS подпись на Node.js?

    @dibrovsd
    У меня работает вот так. Извлеките только ключ из контейнера
    # Контейнер файла с подписью p7m
    openssl cms -sign -inkey ~/certs/private_2018.key -signer ~/certs/sphere.pem -engine gost -binary -outform DER -in file3.pdf -out file3.p7m
    openssl cms -verify -binary -CAfile ~/certs/CA.cer -in file3.p7m -inform DER

    Вот тут еще краткая инструкция как добавить поддержку ГОСТ к OpenSSL.
    Думаю, можно сделать вызов команды консольной из node и считывание результата.

    Вот еще черновые наброски инструкции, которую я вел, пока все это настраивал.

    1) Добавление поддержки алгоритмов в openSSL
    
    1.1) В версии до 1.0 ее просто нет (тут нужно ставить платную версию от КриптоПро) или компилировать вручную из исходников новую версию.
    Это я не делал, поэтому пропускаю
    
    1.2) OpenSSL версии 1.0 (1.1 по другому)
    gost engine входит в операционную систему уже. Чтоб подключить engine, нужно
    
    nano /etc/ssl/openssl.cnf
    
    сразу до секции [ new_oids ]
    вписать
    "openssl_conf=openssl_def"
    
    и в самом низу файла
    
    [openssl_def]
    engines = engine_section
    
    # Engine scetion
    [engine_section]
    gost = gost_section
    
    # Engine gost section
    [gost_section]
    engine_id = gost
    dynamic_path = /usr/lib/x86_64-linux-gnu/openssl-1.0.2/engines/libgost.so
    default_algorithms = ALL
    
    Возможно, libgost.so engine окажется немного не там где у меня
    
    1.3) OpenSSL версии 1.1
    Было принято решение убрать из ядра поддержку gost и теперь она на github-е
    Нужно ее скачать и выполнить инструкции по установке.
    В debian нужно поставить вот эти компиляторы и заголовки к libssl
    apt-get install libssl-dev make cmake
    https://github.com/gost-engine/engine/blob/master/INSTALL.md
    Тут по инструкции все просто и оно рабочее.
    Тут же есть и как правильно модифицировать конфиг openssl
    
    2) Где достать всю цепочку сертификатов (мне для версии 1.1 этого не потребовалось почему-то)
    После установки КриптоПро и сертификата с
    https://ca.kontur.ru/about/certificates
    Они выданы неким "Головным удостоверяющим центром". Этот сертификат появляется в системе после установки КриптоПро
    и их можно экспортировать в файлы уже
    
    3) Как вытащить приватный ключ из контейнера КриптоПро вы уже знаете.
    https://habrahabr.ru/post/275039/
    компилировать и ставить Borland C++ не обязательно (там можно скачать уже готовый файл exe под win)
    
    4) Сертификат (публичную часть ключа вы можете прислать довольно просто)
    Итак, у нас есть приватная и публичная часть и CA (это цепочка сертификатов до корня). Можно не мучатся и просто закинуть сертификат Контур-а в доверенные в linux и забыть о нем (но мне для 1.1 это не понадобилось)
    
    4.1) Перегнать в форму pem
    openssl x509 -inform der -in sphere.cer -out sphere.pem
    openssl pkcs12 -in p12.pfx -nocerts -out private.key
    openssl pkcs12 -info -engine gost -nodes -in sphere.pfx
    
    openssl pkcs12 -info -engine gost -nodes -in sphere.pfx -password pass:Dsgdfh46yu56hsgdfgdgh
    
    openssl pkcs12 -nocerts -out PushKey.pem -in p12.pfx -nodes -password pass:Dsgdfh46yu56hsgdfgdgh
    openssl pkcs12 -nocerts -out PushKey.pem -in sphere.pfx -nodes -password pass:Dsgdfh46yu56hsgdfgdgh
    
    5) Шифрование и расшифровка
    openssl smime -encrypt -engine gost -gost89 -in test.txt -out test.txt.enc sphere.pem
    openssl smime -decrypt -engine gost -gost89 -in test1.PDF -inform=DER -out test1_dec.pdf -inkey /home/www/certs/private_2018.key
    
    6) Подпись и ее валидация
    openssl cms -sign -inkey ~/certs/private_2018.key -CAfile ~/certs/CA.cer -signer ~/certs/sphere.pem -engine gost -binary -in file3.pdf -out file3.pdf.sign
    openssl cms -verify -CAfile ~/certs/CA.cer -signer ~/certs/sphere.cer -engine gost -binary -content file3.pdf -in file3.pdf.sign
    
    6.1) Контейнер файла с подписью p7m
    openssl cms -sign -inkey ~/certs/private_2018.key -CAfile ~/certs/CA.cer -signer ~/certs/sphere.pem -engine gost -binary -stream -outform DER -nodetach -in file3.pdf -out file3.p7m
    openssl cms -verify -binary -CAfile ~/certs/CA.cer -in file3.p7m -inform DER
    
    Есть вариации на тему в какой форме подпись или шифрованный файл. Это решается за счет параметра
    -inform=DER (бинарная форма)
    -outform der (для отсоединенной формы)
    
    Ссылки по теме:
    http://big-town.narod.ru/openssl.html  (основная, которая помогла)
    https://habrahabr.ru/post/275039/
    
    Второстепенные:
    https://stackoverflow.com/questions/12790572/openssl-unable-to-get-local-issuer-certificate
    https://www.altlinux.org/ГОСТ_в_OpenSSL
    https://toster.ru/q/28353
    https://kirill-zak.ru/2015/08/13/298
    https://gist.github.com/aamalev/920f1dff286222ef73d7
    http://sysadmins.ru/topic478444.html
    http://www.ssl.ua/news/most-common-openssl-commands/
    http://soft.lissi.ru/ls_product/skzi/OpenSSL/
    Ответ написан
    Комментировать
  • Django. Как подгрузить блок в template по клику?

    @dibrovsd
    Нужно
    - сделать url для ajax-запроса, например
    url(r'^/ajax/loadBlockB/$', view='loadBlockB', name='loadBlockB'),
    - В js написать
    $('#id_контейнера').load('/ajax/loadBlockB/')
    И все.

    Предполагается, что вы используете jquery
    Если нет, то любой другой способ выполнить ajax запрос
    Ответ написан
    Комментировать
  • Как определить текущего пользователя из модели?

    @dibrovsd
    А чем не устроили сигналы?
    Создание экземпляров модели может быть инициировано по цепочке сигналов или как-то по другому, а не только через админку.

    Да и что теперь, писать один и тот же код в админке, всех views и так далее.

    Внутри сигнала получить текущего пользователя без обращения к объекту request поможет вот такая middleware:
    djangosnippets.org/snippets/2179
    Она работает и свою задачу выполняет.

    P.S. Если нужно описать более подробно, говорите.
    Не стал описывать в деталях, чтоб не быть К.О.
    Но если не получится разобраться самостоятельно, готов помочь.
    Ответ написан
  • Как в Django реализовать синхронизацию данных моделей?

    @dibrovsd Автор вопроса
    Решение для создания инкрементных данных для передачи на боевой сервер и наката их там.
    На нужные модели вешаем сигналы post_delete для сохранения модель - id в модель удаленных объектов.

    Привожу код создания файлов.
    Чуть позже тут размещу ссылку на статью с более подробным описанием:
    - Создания файлов изменений
    - Накате с созданием файлов отката
    - Откате изменений

    # coding=utf-8
    
    from datetime import datetime
    from os import makedirs, listdir
    import json
    
    from django.core import serializers
    from django.core.management.base import BaseCommand
    from optparse import make_option
    from django.db.models.loading import get_model
    from django.conf import settings
    
    
    class Command(BaseCommand):
        help = """
        Create difsettings from timestamp. 
        Usage: manage.py docflow_diffsettings_create '2014-01-01'
        """
    
        option_list = BaseCommand.option_list + (
            make_option('--from',
                action="store", 
                type="string",
                dest='from',
                help='timestamp: changed from argument to current DateTime'),
            make_option('--project_id',
                action="store", 
                type="int",
                dest='project_id',
                help='Docflow project number'),
        )
    
        def __init__(self, *vargs, **kwargs):
    
            super(Command, self).__init__(*vargs, **kwargs)
            self._datetime_format = '%Y-%m-%d %H:%M'
    
        def handle(self, *args, **options):
    
            date_to = datetime.now()
            date_from = datetime.strptime(options['from'], self._datetime_format)
    
            project_id = options["project_id"]
            project_folder = "%s/docflow/diffsettings/%s" % (settings.BASE_DIR, project_id,)
            folder_path = "%s/%s > %s" % (project_folder, 
                                        date_from.strftime(self._datetime_format),
                                        date_to.strftime(self._datetime_format))
            
            makedirs(folder_path)
    
            JSONSerializer = serializers.get_serializer("json")
            json_serializer = JSONSerializer()
    
            models_paths = set()
    
            for model_path in args:
                models_paths.add(model_path)
    
            # deleted objects
            models_paths.add('docflow.ObjectsDeleted')
    
            # create files
            for model_path in models_paths:
    
                application_name, model_name = model_path.split('.')
                model = get_model(application_name, model_name)
                objects_changed = model.objects.filter(d_change__range=(date_from, 
                                                                        date_to))
                
                # Обязательно наличие файла, даже если нет ни одной измененной модели
                # это необходимо для создания бэкапа при накате настроек 
                # (если по модели нет изменившихся, но есть удаленные объекты)
                # Создание файла отката настроек происходит 
                # внутри итерации перебота этих файлов
                with open("%s/%s.json" % (folder_path, model_path), "w") as out:
                    json_serializer.serialize(objects_changed, stream=out, indent=4)
    Ответ написан
    Комментировать
  • Как в Django реализовать синхронизацию данных моделей?

    @dibrovsd Автор вопроса
    Вроде как задача должна быть типичной:
    есть test, есть production, нужно с теста сливать настройки в prod.
    Неужели нет подобного механизма, доступного и поддерживаемого кем-то.

    Собственно, в этом направлении и думаю.
    Если никто не подскажет готового решения, так и сделаю.
    Спасибо.
    Ответ написан
  • Nginx + 2 RoR3 приложения, один из которых на Sub Uri. Как совместить?

    @dibrovsd
    Аналогичная проблема.
    Решил так:

    1. config/environment.rb

    Внизу

    RedmineApp::Application.routes.default_scope = { :path => '/redmine', :shallow_path => '/redmine' }
    
    # Это в конфиге есть
    RedmineApp::Application.initialize!
    
    Redmine::Utils::relative_url_root = "/redmine"
    


    Таким образом, приложение ожидает запросы не от корня, а от префикса /redmine
    И ссылки формирует соответсвенно, не /users/login, а /redmine/users/login

    2. unicorn.rb не интересен особо, но, на всякий случай, приведу
    orker_processes 2
    working_directory "/home/www/redmine/"
    
    preload_app true
    
    timeout 30
    
    listen "/home/www/redmine/tmp/sockets/unicorn.sock", :backlog => 64
    
    pid "/home/www/redmine/tmp/pids/unicorn.pid"
    
    stderr_path "/home/www/redmine/log/unicorn.stderr.log"
    stdout_path "/home/www/redmine/log/unicorn.stdout.log"
    
    before_fork do |server, worker|
        defined?(ActiveRecord::Base) and
            ActiveRecord::Base.connection.disconnect!
    end
    
    after_fork do |server, worker|
        defined?(ActiveRecord::Base) and
            ActiveRecord::Base.establish_connection
    end
    ~                                                                         
    


    3. Конфиг nginx
    Запросы с префиксом /redmine проксируем на socket через upstream
    rewrite тут не нужно, потому что redmine и так ждет от нас префикса /redmine (чтоб ссылки работали)

    В вот статику отдаем через nginx напрямую.

    upstream unicorn_server { 
            server unix:/home/www/redmine/tmp/sockets/unicorn.sock;         
    } 
    
    server {
            server_name docflow.soglasie.ru;
    
            client_max_body_size 8m;
            keepalive_timeout 5;
    
            # apache
            location / {
                    proxy_pass http://127.0.0.1:8181;
            }
    
            # redmine
            location /redmine {
                    proxy_pass http://unicorn_server;
            }
    
            # redmine static
            location ~* /redmine/.+\.(ico|css|js|png) {
                    rewrite /redmine/(.*) /$1 break;
                    root /home/www/redmine/public/;
            } 
    
    }
    
    


    Не претендую на качественный конфиг. Это первый опыт использования nginx.
    Не пишу скрипты автозапуска и т.п. Предполагается, что они у вас есть.

    Главное, что работает.
    Возможно кому-то пригодится (даже мне самому, через какое-то время)
    Ответ написан