🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: es.comp.os.linux.programacion
Article #8150

Re: Comprobar comtraseña

#8150
From: J.A. Gutierrez
Date: Tue, 17 Dec 2002 18:37
185 lines
6309 bytes
Jose A <MAQUI000@.nospan.mundo-r.com> wrote:
: quantium escribi�:

:> Hola a todos.

: Hola.
:
:> �Sabeis como puedo comprobar si una contrase�a insertada es la del
:> usuario que la ha insertado?
:>
:> He estado mirando en google y en la faq de unix, se que lo tiros van por
:> strcmp y crypt, pero no me queda nada clar, �me podriais poner un
:> ejemplo sobre su uso?

: Puedes usar algo asi:

: #include <shadow.h>

    esto depende de la variante de unix utilizada.
    (ver mas abajo)


: int main (int argc, char *argv[0]) {
:     char *pwd, salt[11], *passwd, *tpwd;
:     struct spwd *p;

:     if (argc < 3) {
:         printf ("Usar %s nombre password\n", argv[0]);
:         exit (1);
:     }
:
: // Limpiamos la variable salt para evitar problemas.

    no es bueno usar comentarios de C++ en programas de C

:     bzero (salt, sizeof (salt));

    no es bueno usar funciones poco portables (BSD)

    Ademas, en realidad, no es necesario ni copiar la sal ni
    poner el buffer a cero.

> CONFORMING TO
>        4.3BSD.  This function is deprecated -- use memset in  new
>        programs.


: // Bloqueamos el fichero "/etc/shadow" para que no se
: // modifique mientras accedemos a sus datos.
:     lckpwdf ();
:     p = getspnam (argv[1]);
: // Y aqu� lo desbloqueamos.
:     ulckpwdf ();
:

    creo que por lo general no se considera necesario bloquear el
    shadow antes de leerlo, solamente antes de modificarlo.

:     pwd = argv[2];
:     passwd = p->sp_pwdp;
: // Dentro de este bloque if comprobamos el tipo de
: // password que se usa, si empieza por "$1$", es
: // del tipo md5, y copiamos los 11 primeros caracteres
: // del password que est�n formados por la identificaci�n
: // (3 caracteres) y la salt (8 caracteres), por ejemplo:
: // $1$aT���TjK
: // Estos 11 caracteres son usados para que la funci�n crypt
: // identifique la password como del tipo md5.
:     if (memcmp (passwd, "$1$", 3) == 0) {
:         strncpy (salt, passwd, 11);
: // Si no es del tipo des y se cogen solo los 2 primeros
: // caracteres.
:     } else {
:         strncpy (salt, passwd, 2);
:     }

    mas facil, le pasas a crypt() directemente el password encriptado
    en el campo salt y el solo se las apa~na.
    Ademas, es mas portable.

    tpwd = crypt (pwd, p->sp_pwdp);

: // Aqu� se encripta la password pasada al programa y
: // a continuaci�n se compara con la almacenada en el
: // fichero "/etc/shadow".
:     tpwd = (char *) crypt (pwd, salt);

    notese que el cast es innecesario.

:     if (strcmp (tpwd, passwd) == 0) {
:         printf ("Las password son iguales\n");
:     } else {
:         printf ("Las password son distintas\n");
:     }
:     return 0;
: }

: y el uso es as�:
: ./nombre_fichero usuario password

    notese que requiere privilegios de root.


    Alternativa:
---------------------------------------------------------------------------
[...]
#include <pwd.h>
#include <sys/param.h>

#ifdef _USE_SHADOW_
#  include <shadow.h>
struct spwd *spasswd;
#endif

#ifdef _BSD_
extern char *sys_errlist[];
# define raise(s) kill(getpid(),(s))
# define strerror(e) sys_errlist[(e)]
extern char *crypt( char *key, char *salt);
extern char *getpass( char *prompt);
#else
#include <crypt.h>
#endif

[...]

    if ( NULL == ( pwd = getpwuid ( getuid () )))
    {
        output("getpwuid failed for %s (%s)",
            getuid(), strerror(errno) );
        error = errno;
    }
    else
    {
        sprintf(s, "%s's password? ", pwd->pw_name);
        if ( NULL == (pass = getpass(s)))
        {
            output( "getpass failed for %s (%s)",
                pwd->pw_name, strerror(errno));
            error = errno;
        }
        else
        {
#ifdef _USE_SHADOW_
            if ( NULL == ( spasswd = getspnam(pwd->pw_name) ))
            {
                output( "getspnam failed for %s (%s)\n",
                pwd->pw_name, strerror(errno));

                exit(errno);
            }
            if (strcmp(spasswd->sp_pwdp, crypt(pass, spasswd->sp_pwdp)))
#else
            if (strcmp(pwd->pw_passwd, crypt(pass, pwd->pw_passwd)))
#endif

            {
                output( "incorrect password for %s\n",
                    pwd->pw_name);
            }
            else
            {
                [...]
            }
        }
    }
---------------------------------------------------------------------------

    La cosa se puede complicar aun mas con cosas como crypt16, bigcrypt
    y demas, pero en fin, con lo de arriba ya vale para bastantes casos...

    PS: Notese en se utilza getpass, que segun linux, tampoco deberia
    utilizarse:

DESCRIPTION
       This function is obsolete. Do not use it.

    En solaris existe getpassphrase()...


-- 
PGP and other useless info at      \
http://www.cps.unizar.es/~spd/      \
finger://daphne.cps.unizar.es/spd    \       Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/          \                         (Virgilio)
Technical Details
Message-ID: <atnqsp$pkd$1@news.unizar.es>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed.icl.net!newsfeed.fjserv.net!newsfeed.icl.net!newsfeed.fjserv.net!isdnet!news.rediris.es!news.unizar.es!not-for-mail
References: <atgjct$13knnp$1@ID-129971.news.dfncis.de> <atncbv$k5m81@cesio.mundo-r.com>

Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII
X-Google-Thread: f86c8,249be857bbf5a850
X-Google-Attributes: gidf86c8,public
X-Google-ArrivalTime: 2002-12-17 09:57:09 PST
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed.icl.net!newsfeed.fjserv.net!newsfeed.icl.net!newsfeed.fjserv.net!isdnet!news.rediris.es!news.unizar.es!not-for-mail
From: "J.A. Gutierrez" <spd@daphne.cps.unizar.es>
Newsgroups: es.comp.os.linux.programacion
Subject: Re: Comprobar comtraseña
Date: 17 Dec 2002 18:37:13 GMT
Organization: Rank
Lines: 185
Message-ID: <atnqsp$pkd$1@news.unizar.es>
References: <atgjct$13knnp$1@ID-129971.news.dfncis.de> <atncbv$k5m81@cesio.mundo-r.com>
NNTP-Posting-Host: daphne.cps.unizar.es
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: news.unizar.es 1040150233 26253 155.210.152.20 (17 Dec 2002 18:37:13 GMT)
X-Complaints-To: usenet@news.unizar.es
NNTP-Posting-Date: 17 Dec 2002 18:37:13 GMT
User-Agent: tin/1.4.5-20010409 ("One More Nightmare") (UNIX) (IRIX/6.2 (IP22))