linux登陆认证模拟Linux -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

    一个很简陋的认证过程,通过用户名(或用户ID)和密码明文验证该用户是否可以登陆系统,

linux登陆认证模拟Linux

。 just for fun,没有时间完善了,不过应该比较容易扩充和增加其他的功能。 注意链接需要制定-lcrypt。如果需要一般用户同样可以使用,需要将程序setuid(需要验证/etc/s

    一个很简陋的认证过程,通过用户名(或用户ID)和密码明文验证该用户是否可以登陆系统。

    just for fun,没有时间完善了,不过应该比较容易扩充和增加其他的功能。

    注意链接需要制定-lcrypt。如果需要一般用户同样可以使用,需要将程序setuid(需要验证/etc/shadow):

    # chown root:root checkpasswd

    # chmod 4755 checkpasswd

    usage:

    $ checkpasswd --user testuser --password testpassword --verbose

    $ checkpasswd -i 1001 -p empty_passwd -v

   

#define    _XOPEN_SOURCE</p><p>    #define    _GNU_SOURCE</p><p>    #include<sys></p><p>    #include<stdlib.h></p><p>    #include<string.h></p><p>    #include<stdio.h></p><p>    #include</p><p>    #include<errno.h></p><p>    #include<stdarg.h></p><p>    #include<unistd.h></p><p>    #include<stdint.h></p><p>    #include<pwd.h></p><p>    #include<shadow.h></p><p>    #include<getopt.h></p><p>    typedef enum{</p><p>    AUTH_TYPE_AUTO,</p><p>    AUTH_TYPE_DES,</p><p>    AUTH_TYPE_MD5,</p><p>    NR_AUTH_TYPE</p><p>    }auth_type_t;</p><p>    typedef enum{</p><p>    AUTH_INFO_AUTO,</p><p>    AUTH_INFO_PASSWD,</p><p>    AUTH_INFO_SHADOW,</p><p>    NR_AUTH_INFO</p><p>    }auth_info_t;</p><p>    typedef struct login_info{</p><p>    char* login;    /* login name */</p><p>    char* cname;    /* cname */</p><p>    char* group;</p><p>    char* passwd;    /* plain text password */</p><p>    uid_t uid;</p><p>    gid_t gid;</p><p>    uint16_t auth_type;</p><p>    uint16_t auth_info;</p><p>    }login_info_t;</p><p>    static login_info_t login_info = {</p><p>    NULL, NULL, NULL, NULL, -1, -1, 0, 0,</p><p>    };</p><p>    static int verbose_flag;</p><p>    /**</p><p>    * option for getopt_long</p><p>    */</p><p>    static const struct option opt_options[] = {</p><p>    {"user", 1, 0, 'n'},</p><p>    {"uid", 1, 0, 'u'},</p><p>    {"password", 1, 0, 'p'},</p><p>    {"help", 0, 0, '?'},</p><p>    {"version", 0, 0, 'V'},</p><p>    {"verbose", 0, 0, 'v'},</p><p>    {0, 0, 0, 0},</p><p>    };</p><p>    static void help(void)</p><p>    {</p><p>    const struct option* o;</p><p>    for(o = &opt_options[0]; o && o->name; o++){</p><p>    fprintf(stderr, "%s\n", o->name);</p><p>    }</p><p>    fprintf(stderr, "\n");</p><p>    }</p><p>    static void version(void)</p><p>    {</p><p>    fprintf(stderr, "version: 0.0.1\n");</p><p>    }</p><p>    int verbose(const char* fmt, ...)</p><p>    {</p><p>    va_list ap;</p><p>    int n;</p><p>    if(!verbose_flag)</p><p>    return 0;</p><p>    va_start(ap, fmt);</p><p>    n = vfprintf(stderr, fmt, ap);</p><p>    va_end(ap);</p><p>    return 0;</p><p>    }</p><p>    int auth_des(const char* plain_text, const char* key_compare)</p><p>    {</p><p>    char* des_key;</p><p>    char salt[2] = ;</p><p>    if(strlen(key_compare) < 2)</p><p>    return -1;</p><p>    strncpy(salt, key_compare, 2);</p><p>    des_key = crypt(plain_text, salt);</p><p>    if(strcmp(des_key, key_compare) == 0)</p><p>    return 0;</p><p>    verbose("auth DES: non-match(Wrong) password!\n");</p><p>    return -1;</p><p>    }</p><p>    /**</p><p>    * need GNU libc 2.x or higher</p><p>    */</p><p>    int auth_md5(const char* plain_text, const char* key_compare)</p><p>    {</p><p>    char* md5_key;</p><p>    const char* p;</p><p>    char salt[12] = ;</p><p>    int n = 0;</p><p>    if(strlen(key_compare) < 3)</p><p>    return -1;</p><p>    if(strncmp(key_compare, "$", 3) != 0){    /* not start with "$", please confirm</p><p>    to /etc/shadow file */</p><p>    verbose("auth MD5: not start with \"$\"\n");</p><p>    return -1;</p><p>    }</p><p>    p = key_compare + 3;</p><p>    while(*p++){</p><p>    ++n;</p><p>    if(!p){</p><p>    verbose("auth MD5: invalid shadowed MD5 password!\n");</p><p>    return -1;    /* invalid shadowed md5 password */</p><p>    }</p><p>    if(n > 8){</p><p>    break;</p><p>    }</p><p>    if(*p == '$'){</p><p>    break;</p><p>    }</p><p>    }</p><p>    strncpy(salt, key_compare, n + 3);</p><p>    md5_key = crypt(plain_text, salt);</p><p>    if(strcmp(md5_key, key_compare) == 0)</p><p>    return 0;</p><p>    verbose("auth MD5, non-match(Wrong) password!\n");</p><p>    return -1;</p><p>    }</p><p>    int check_shadowed_passwd(login_info_t* login_info)</p><p>    {</p><p>    struct passwd* pw;</p><p>    struct spwd* spw;</p><p>    if(login_info->login){</p><p>    spw = getspnam(login_info->login);</p><p>    }else if(login_info->uid >= 0){</p><p>    pw = getpwuid(login_info->uid);</p><p>    if(!pw){</p><p>    verbose("getpwuid [%d] failed, error: %s\n", login_info->uid,</p><p>    strerror(errno));</p><p>    return -1;</p><p>    }</p><p>    login_info->login = pw->pw_name;</p><p>    spw = getspnam(pw->pw_name);</p><p>    }else{</p><p>    return -1;</p><p>    }</p><p>    if(!spw){</p><p>    fprintf(stderr, "unable to read shadow passwd info: %s\n",</p><p>    strerror(errno));</p><p>    return -1;</p><p>    }</p><p>    if(login_info->auth_type == AUTH_TYPE_AUTO){</p><p>    if(strncmp(spw->sp_pwdp, "$", 3) == 0){    /* GNU extension, md5 used */</p><p>    return auth_md5(login_info->passwd, spw->sp_pwdp);</p><p>    }else{</p><p>    return auth_des(login_info->passwd, spw->sp_pwdp);</p><p>    }</p><p>    }else if(login_info->auth_type == AUTH_TYPE_DES){</p><p>    return auth_des(login_info->passwd, spw->sp_pwdp);</p><p>    }else if(login_info->auth_type == AUTH_TYPE_MD5){</p><p>    return auth_md5(login_info->passwd, spw->sp_pwdp);</p><p>    }else{</p><p>    verbose("unknown auth type: %d\n", login_info->auth_type);</p><p>    return -1;</p><p>    }</p><p>    }</p><p>    /**</p><p>    * checkpasswd<user><pass></p><p>    */</p><p>    int check_passwd(login_info_t* login_info)</p><p>    {</p><p>    struct passwd* pw;</p><p>    if(login_info->login){</p><p>    pw = getpwnam(login_info->login);</p><p>    if(!pw){</p><p>    verbose("getpwnam [%s] failed, error: %s\n", login_info->login,</p><p>    strerror(errno));</p><p>    return -1;</p><p>    }</p><p>    login_info->uid = pw->pw_uid;</p><p>    }else if(login_info->uid >= 0){</p><p>    pw = getpwuid(login_info->uid);</p><p>    if(!pw){</p><p>    verbose("getpwuid [%d] failed, error: %s\n", login_info->uid,</p><p>    strerror(errno));</p><p>    return -1;</p><p>    }</p><p>    login_info->login = pw->pw_name;</p><p>    }else{</p><p>    return -1;</p><p>    }</p><p>    if(!login_info->passwd){</p><p>    verbose("no password specified!\n");</p><p>    return -1;</p><p>    }</p><p>    if(login_info->auth_info == AUTH_INFO_AUTO){</p><p>    if(strlen(pw->pw_passwd) < 2){</p><p>    if(strcmp(pw->pw_passwd, "x") == 0){    /* shadow password used */</p><p>    return check_shadowed_passwd(login_info);</p><p>    }else{</p><p>    return -1;</p><p>    }</p><p>    }</p><p>    return auth_des(login_info->passwd, pw->pw_passwd);</p><p>    }else if(login_info->auth_info == AUTH_INFO_PASSWD){</p><p>    return auth_des(login_info->passwd, pw->pw_passwd);</p><p>    }else if(login_info->auth_info == AUTH_INFO_SHADOW){</p><p>    return check_shadowed_passwd(login_info);</p><p>    }else{</p><p>    verbose("unknown auth info: %d\n", login_info->auth_info);</p><p>    return -1;</p><p>    }</p><p>    }</p><p>    void handle_args(int argc, char* argv[])</p><p>    {</p><p>    int ch;</p><p>    int option_index;</p><p>    while((ch = getopt_long(argc, argv, "u:i:p:Vvh", opt_options, &option_index)) != -1){</p><p>    switch(ch){</p><p>    case 'u':</p><p>    login_info.login = optarg;</p><p>    break;</p><p>    case 'i':</p><p>    login_info.uid = atoi(optarg);</p><p>    break;</p><p>    case 'p':</p><p>    login_info.passwd = optarg;</p><p>    break;</p><p>    case 'h':</p><p>    help();</p><p>    exit(0);</p><p>    break;</p><p>    case 'V':</p><p>    version();</p><p>    exit(0);</p><p>    break;</p><p>    case 'v':</p><p>    verbose_flag = 1;</p><p>    break;</p><p>    case '?':</p><p>    default:</p><p>    help();</p><p>    exit(1);</p><p>    break;</p><p>    }</p><p>    }</p><p>    if(!login_info.passwd){</p><p>    fprintf(stderr, "please specifie login password\n");</p><p>    help();</p><p>    exit(1);</p><p>    }</p><p>    if(!login_info.login && !login_info.uid){</p><p>    fprintf(stderr, "please specifie either login name or user id\n");</p><p>    help();</p><p>    exit(1);</p><p>    }</p><p>    }</p><p>    int main(int argc, char* argv[])</p><p>    {</p><p>    int ret;</p><p>    const char seperator[] =</p><p>    "==========================================================================================\n";</p><p>    int retcode = 1;</p><p>    handle_args(argc, argv);</p><p>    printf(seperator);</p><p>    ret = check_passwd(&login_info);</p><p>    if(ret < 0){</p><p>    fprintf(stderr, "3[1;31mauthentication failed for user: "</p><p>    "[%s], uid[%d], password: [%s]3[m\n",</p><p>    login_info.login, login_info.uid, login_info.passwd);</p><p>    goto quit;</p><p>    }else if(ret == 0){</p><p>    printf("3[1;32mauthenticated token su<strong>clearcase</STRONG>/" target="_blank" >cc</STRONG>essfully, user: "</p><p>    "[%s], uid: [%d]3[m\n",</p><p>    login_info.login, login_info.uid);</p><p>    retcode = 0;</p><p>    }else{</p><p>    assert(0);</p><p>    retcode = -1;</p><p>    }</p><p>    quit:</p><p>    printf(seperator);</p><p>    exit(retcode);</p><p>    }

   

    原文转自:http://www.ltesting.net

最新文章