Permissão para IUSR para CertOpenSystemStore()

Permissão para IUSR para CertOpenSystemStore()

Meu aplicativo CGI está tentando usar o SSPI Schannel para criar uma conexão TLS com outro servidor. http://www.coastrd.com/c-schannel-smtp

O processo de handshake começa verificando um certificado no armazenamento de certificados "MY" http://msdn.microsoft.com/en-us/library/aa376560(VS.85).aspx

Esta função retorna zero e GetLastError também retorna zero!? Presumo que este seja um problema de permissões. Como faço para que isso funcione sem elevar o IUSR a administrador, por exemplo?

ADICIONADO

O acesso aos certificados de usuário requer a execução como usuário específico, e o acesso à chave privada do usuário requer que o usuário tenha efetuado logon localmente com a senha ou que o servidor esteja habilitado para delegação.

Os certificados de máquina podem ser lidos por todos, mas o acesso à chave privada requer direitos de administrador (ou usuário local), a menos que você ajuste a ACL.

ADICIONADO

Nesta situação, não há restrições aos certificados, mas o armazenamento de certificados "MEU" está vazio e não quero comprar um certificado só para isso.

Atualmente estou usando o WS2003. O servidor ao qual estou me conectando é gmail.com para enviar e-mails usando TLS. Meu código pode procurar um certificado, mas não tenho um. Pela leitura que fiz, parece uma dor de cabeça gigante conseguir um certificado, com cadastro e compra e instalação, caso contrário você só consegue uma solução temporária que não ajuda em nada. A menos que você conheça uma maneira fácil de obter um certificado, isso é muito mais problemático do que eu gostaria apenas de enviar e-mail de um aplicativo CGI. Existe ALGUMA outra maneira?

Agradeço MUITO sua ajuda, Joe, mas US$ 30/ano x nServers simplesmente não é uma opção. Gostaria de saber se existe uma maneira de transferir a tarefa para outro processo que ESTÁ em execução com privilégios de administrador, como um serviço, talvez? Eu poderia até criar um aplicativo programado para ler uma determinada pasta e enviar todos os e-mails encontrados lá. Fora isso, eu teria que tentar elevar o aplicativo CGI para Administrador.

ADICIONADO

Goyuix, obrigado pelas sugestões. O desafio é fornecer uma solução independente sem recorrer a outras bibliotecas como .NET (60 MB) ou ASP com seus problemas inerentes.

Você está correto, só preciso de autenticação do servidor. Eu não sabia que era possível autenticar apenas um lado. sua declaração: "Não ter certificado de cliente não deve impedi-lo de estabelecer um canal seguro para SMTP. Talvez você precise apenas codificar essa parte do handshake." acabou por ser a solução.

Isso me lembra a velha piada do encanador. O encanador é chamado para desentupir o ralo. Ele dá uma olhada, puxa um martelo e bate uma vez no cano. Ele pede US$ 180 por 5 minutos de trabalho, discriminados como US$ 30 de taxa de chamada e US$ 150 para saber onde acertar o cano.

Obrigado a ambos. Este tem sido um longo trabalho árduo.

Responder1

A única razão pela qual o código schannel está tentando abrir o armazenamento "MY" é procurar um certificado potencial que possa ser usado para autenticação do cliente como parte do handshake inicial. No seu exemplo, imagino que você realmente se preocupa apenas com a autenticação do servidor (por exemplo, certifique-se de que seu cliente esteja se comunicando com o servidor que pensa estar). Não ter nenhum certificado de cliente não deve impedir você de estabelecer um canal seguro para SMTP. Talvez você só precise codificar essa parte do handshake.

Se você também precisar de autenticação de cliente, provavelmente precisará:

  • eleve a conta IUSR e instale um certificado no armazenamento de máquinas
  • altere o pool de aplicativos para executar como um usuário diferente e lute contra isso

Quanto a corrigir o código vinculado... bem - eu sugeriria tentar o código SmtpClient que vem com o framework .NET, se for uma opção. Ele suporta comunicações criptografadas e deveria, em teoria, “simplesmente funcionar”. O C++ gerenciado é mesmo uma opção? Ou melhor ainda, basta escrever um manipulador ASP.NET para isso?

http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient_members.aspx

Você também pode tentar fazer algumas perguntas relacionadas ao código emStackOverflow.com, as pessoas de lá também podem ajudar.

Responder2

A melhor opçãoEUveja é usar um certificado de máquina e conceder permissão à conta IUSR para ler a chave privada do certificado. Esta é uma etapa manual, mas muito fácil que só precisa ser executada uma vez.

Existem outros requisitos na sua situação que impediriam a alteração das permissões do certificado?


Instruções para começar

Primeiro, você precisa de um certificado. Você pode gerar o seu próprio, mas dependendo de como deseja utilizá-lo e da outra extremidade que irá validá-lo, pode ser necessário adquirir um. Não abordarei como gerar um certificado. Se você nunca trabalhou com certificados e autoridades de certificação antes, recomendo aprender sobre eles primeiro.

Presumo que você esteja no Windows Server 2003, a menos que comente o contrário.

1) Instale o certificado no armazenamento da máquina. Vá para Iniciar | Execute e entre no MMC para obter um console MMC em branco. Vá para Arquivo | Adicionar/remover snap-in. Clique no botão Adicionar para selecionar o snap-in. Escolha Certificados na lista e clique em Adicionar. Escolha a opção Conta de computador, depois Avançar, Concluir, Fechar e, finalmente, OK.

2) Importando o certificado para o Machine Store. Expanda a árvore e escolha a pasta Pessoal. Clique com o botão direito em Pessoal e escolha Todas as tarefas, Importar. Siga o assistente para concluir o processo. O certificado agora deve estar no armazenamento da máquina.

3) Ajustando as permissões da chave privada. No Windows 2008, isso é adicionado à GUI do Certificate Manager. No Windows 2003, você precisará baixar oFerramentas do Kit de Recursos do Windows Server 2003. Use o seguinte formato de comando para definir permissões:

C:\Program Files\Windows Resource Kits\Tools\winhttpcertcfg.exe -g -c LOCAL_MACHINE\My -s "mycert" -a "USER_ACCOUNT" 

Onde 'LOCAL_MACHINE\My' é o armazenamento de certificados pessoais na máquina local, 'mycert' é o nome do seu certificado e USER_ACCOUNT é a conta que receberá permissões de leitura para a chave privada. Você pode tentar a conta IUSR, mas pode ser necessário usar o 'NETWORK SERVICE' dependendo do contexto exato em que seu aplicativo CGI está sendo executado. Você precisará reiniciar o IIS para que as alterações tenham efeito. Odocumentação para WinHttpCertCfgcobre o que está fazendo.

Agora você deve ter permissões para acessar a chave privada. Você ainda usará CertOpenSystemStore com o sinalizador MY.

Espero que ajude.


Editar 2:

Um lugar fácil para obter um certificado com uma autoridade reconhecida é o GoDaddy. Você pode obter um certificado SSL válido por 1 ano por US$ 30. Existem outros lugares que podem ser mais baratos se você procurar um pouco. Não é muito difícil de fazer. A maioria dos sites é muito amigável e facilita a compra de um certificado.

Como você está fazendo autenticação mútua, precisará de um certificado com uma autoridade válida, e não apenas um certificado autoassinado que você mesmo pode criar, porque o servidor do Gmail não teria como verificá-lo.

informação relacionada