Разрешение на IUSR для CertOpenSystemStore()
Мое приложение CGI пытается использовать SSPI Schannel для создания соединения TLS с другим сервером. http://www.coastrd.com/c-schannel-smtp
Процесс рукопожатия начинается с проверки сертификата в "МОЕМ" хранилище сертификатов http://msdn.microsoft.com/en-us/library/aa376560(VS.85).aspx
Эта функция возвращает ноль, а GetLastError также возвращает ноль!? Я предполагаю, что это проблема с разрешениями. Как мне заставить это работать без повышения IUSR к администратору, например?
ADDED
Для доступа к сертификатам пользователей требуется запуск от имени конкретного пользователя, а для доступа к закрытому ключу пользователя необходимо, чтобы пользователь вошел в систему локально с паролем, или чтобы на сервере был включен режим делегирования.
Сертификаты компьютера доступны для чтения всем, но для доступа к закрытому ключу требуются права администратора (или локального пользователя), если вы не настроите ACL.
ADDED
В этой ситуации нет никаких ограничений на сертификаты, но "МОЕ" хранилище сертификатов пусто, и я не хочу покупать сертификат только для этого.
В настоящее время я использую WS2003. Сервер, к которому я подключаюсь - это gmail.com для отправки электронных писем с использованием TLS. Мой код может искать сертификат, но у меня его нет. В том чтении, которое я прочитал, похоже, что огромная головная боль - получить сертификат, с регистрацией, покупкой и установкой, иначе вы просто получите временное решение, которое не поможет. Если вы не знаете, как легко получить сертификат, это намного сложнее, чем я хочу просто отправить электронное письмо из приложения CGI. Есть ли другой путь?
Я ОЧЕНЬ ценю вашу помощь, Джо, но $30/ год x nServers просто не вариант. Мне интересно, есть ли способ передать задачу другому процессу, работающему с привилегиями администратора, например, сервису? Я мог бы даже создать приложение, которое запланировано на чтение из заданной папки и отправлять любые найденные там электронные письма. Кроме этого, мне пришлось бы попробовать поднять приложение CGI до администратора.
ADDED
Goyuix, спасибо за предложения. Задача состоит в том, чтобы предоставить автономное решение, не прибегая к другим библиотекам, таким как.NET (60 МБ) или ASP с сопутствующими проблемами.
Вы правы, мне нужна только аутентификация сервера. Я не знал, что можно было аутентифицировать только одну сторону. Ваше заявление: "Отсутствие клиентского сертификата не должно помешать вам установить безопасный канал для SMTP. Возможно, вам просто нужно кодировать эту часть рукопожатия". оказалось решением.
Это напоминает мне старую сантехническую шутку. Сантехник вызывается, чтобы разблокировать канализацию. Он бросает один взгляд, достает молоток и ударяется о трубу один раз. Он просит 180 долларов за 5-минутную работу, определенную как: 30 долларов за выноску и 150 долларов, чтобы узнать, где попасть в трубу.
Спасибо вам обоим. Это был долгий подъем в гору.
2 ответа
Единственная причина, по которой код schannel пытается взломать хранилище "MY", - это поиск потенциального сертификата, который можно использовать для аутентификации клиента как часть начального рукопожатия. В вашем примере, я полагаю, вы действительно заботитесь только об аутентификации сервера (например, убедитесь, что ваш клиент говорит с сервером, который, как он думает). Отсутствие сертификата клиента не должно помешать вам установить безопасный канал для SMTP. Возможно, вам просто нужно закодировать эту часть рукопожатия.
Если вам также нужна аутентификация клиента, то вам, вероятно, придется либо:
- повысить учетную запись IUSR и установить сертификат в магазине машины
- измените пул приложения, чтобы он работал от имени другого пользователя и сразитесь с ним
Что касается исправления связанного кода... хорошо - я бы предложил попробовать код SmtpClient, который поставляется с.NET Framework, если это возможно. Он поддерживает зашифрованные сообщения и теоретически должен "просто работать". Управляемый C++ - это даже вариант? Или еще лучше, просто написать обработчик ASP.NET для этого?
http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient_members.aspx
Вы также можете попытаться задать несколько вопросов по коду на https://stackoverflow.com/, и там могут помочь другие люди.
Лучший вариант, который я вижу, - это использовать сертификат компьютера и предоставить разрешение учетной записи IUSR для чтения закрытого ключа сертификата. Это ручной шаг, но очень простой, который нужно сделать один раз.
Существуют ли в вашей ситуации другие требования, которые не позволили бы изменить разрешения для сертификата?
Направления, чтобы начать
Во-первых, вам нужен сертификат. Вы можете создать свой собственный, но в зависимости от того, как вы хотите его использовать, и другого конца, который будет проверять его, вам может понадобиться приобрести его. Я не буду рассказывать, как создать сертификат. Если вы никогда раньше не работали с сертификатами и центрами сертификации, я рекомендую сначала узнать о них.
Я предполагаю, что вы на Windows Server 2003, если вы не прокомментируете иначе.
1) Установите сертификат в магазин машины. Перейти к началу | Запустите и войдите в MMC, чтобы получить пустую консоль MMC. Перейти к файлу | Добавить / удалить оснастку. Нажмите кнопку Добавить, чтобы выбрать оснастку. Выберите Сертификаты из списка и нажмите Добавить. Выберите опцию "Учетная запись компьютера", затем "Далее", "Готово", "Закрыть" и, наконец, "ОК".
2) Импорт сертификата в магазин машин. Разверните дерево и выберите личную папку. Щелкните правой кнопкой на Личные и выберите Все задачи, Импорт. Следуйте указаниям мастера, чтобы завершить процесс. Сертификат теперь должен быть в магазине машин.
3) Настройка разрешений закрытого ключа. В Windows 2008 это добавляется в графический интерфейс диспетчера сертификатов. В Windows 2003 вам необходимо загрузить средства набора ресурсов Windows Server 2003. Используйте следующий формат команды для установки разрешений:
C:\Program Files\Windows Resource Kits\Tools\winhttpcertcfg.exe -g -c LOCAL_MACHINE\My -s "mycert" -a "USER_ACCOUNT"
Где "LOCAL_MACHINE\My" - это хранилище личных сертификатов на локальном компьютере, "mycert" - это имя вашего сертификата, а USER_ACCOUNT - учетная запись, которой будут предоставлены разрешения на чтение для закрытого ключа. Вы можете попробовать учетную запись IUSR, но вам может понадобиться "СЕТЕВАЯ СЛУЖБА" в зависимости от того, в каком именно контексте работает ваше приложение CGI. Вам нужно будет перезапустить IIS, чтобы изменения вступили в силу. Документация для WinHttpCertCfg описывает, что он делает.
Теперь у вас должны быть права доступа к закрытому ключу. Вы по-прежнему будете использовать CertOpenSystemStore с флагом MY.
Надеюсь, это поможет.
Изменить 2:
GoDaddy - это простое место для получения сертификата с признанным авторитетом. Вы можете получить сертификат SSL, действительный в течение 1 года, за 30 долларов. Есть и другие места, которые могут быть дешевле, если вы немного поохотитесь. Это не так уж сложно сделать. Большинство сайтов очень удобны для пользователя и позволяют легко купить сертификат.
Поскольку вы выполняете взаимную аутентификацию, вам нужен сертификат с действительными полномочиями, а не только самозаверяющий, который вы можете создать самостоятельно, потому что сервер Gmail не сможет проверить его.