Método 1: Eu não gosto simplesmente porque em 2 segundos pensando nisso, esses comentários são essencialmente corretos. Você está criando uma superfície que expõe seu arquivo /etc/shadow
, seja ele explorável ou não, eu simplesmente não gosto disso.
Método 2: também é ruim. Codificar senhas em um arquivo é simplesmente idiota. Passá-los através de um cano parece igualmente perigoso.
Método 3: é provavelmente o jeito que eu iria, e eu não acho que você teria que escrever sua própria solução do zero. Em alguns minutos de googling eu encontrei esta implementação que alguém montou usando a API libpam.
implementação c
excerto da implementação de C - pam.c
#include <security/pam_appl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct pam_response *reply;
int null_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) {
*resp = reply;
return PAM_SUCCESS;
}
static struct pam_conv conv = { null_conv, NULL };
int main(int argc, char *argv[]) {
int retval;
char *user, *pass;
if(argc == 3) {
user = argv[1];
pass = strdup(argv[2]);
} else {
fprintf(stderr, "Usage: login [username] [password]\n");
exit(1);
}
return authenticate("system-auth", user, pass);
}
int authenticate(char *service, char *user, char *pass) {
pam_handle_t *pamh = NULL;
int retval = pam_start(service, user, &conv, &pamh);
if (retval == PAM_SUCCESS) {
reply = (struct pam_response *)malloc(sizeof(struct pam_response));
reply[0].resp = pass;
reply[0].resp_retcode = 0;
retval = pam_authenticate(pamh, 0);
if (retval == PAM_SUCCESS)
fprintf(stdout, "Authenticated\n");
else
fprintf(stdout, "Not Authenticated\n");
pam_end(pamh, PAM_SUCCESS);
return ( retval == PAM_SUCCESS ? 0:1 );
}
return ( retval == PAM_SUCCESS ? 0:1 );
}
comando para compilá-lo
$ gcc -g -lpam -o chkpasswd pam.c
exemplo executado
$ ./chkpasswd myusername mypassword
Eu imagino que com um pouco de esforço essa abordagem poderia ser adaptada para atender às suas necessidades com a Horda.
implementação do PHP
Como uma outra alternativa para essa abordagem, você poderia potencialmente fazer o seu próprio no PHP. Eu encontrei esta biblioteca PAM no site da PECL que parece com o que você gostaria.
Eu também dou uma olhada em como o projeto Moodle faz isso. É discutido aqui.
PAM de uma perspectiva de segurança
Olhando para o propósito do PAM, eu esperaria que a interface da API fosse projetada de forma que nenhum acesso a entidades de nível inferior, como o /etc/shadow
, precisaria ser necessário para que os usuários da API possam usá-lo. Isso é discutido um pouco no wiki do Gentoo neste artigo intitulado: PAM, seção: Como o PAM funciona .
tirado de Como o PAM funciona
So when a user wants to authenticate itself against, say, a web application, then this web application calls PAM (passing on the user id and perhaps password or challenge) and checks the PAM return to see if the user is authenticated and allowed access to the application. It is PAMs task underlyingly to see where to authenticate against (such as a central database or LDAP server).
The strength of PAM is that everyone can build PAM modules to integrate with any PAM-enabled service or application. If a company releases a new service for authentication, all it needs to do is provide a PAM module that interacts with its service, and then all software that uses PAM can work with this service immediately: no need to rebuild or enhance those software titles.
Método 4: Também é uma boa alternativa. Deve haver boa acessibilidade às bibliotecas e tal para fazer as chamadas necessárias para acessar algo como o LDAP através da rede para fazer sua autenticação para você. Um servidor LDAP também pode ser configurado no mesmo sistema que a instalação do Horde, configurando-o apenas para o uso da Horde.
Isso permitiria o acesso à autenticação do sistema subjacente, potencialmente, "agrupando-a" em um serviço LDAP para o Horde consumir.