• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • linux登陸認證模擬

    發表于:2007-05-26來源:作者:點擊數: 標簽:
    一個很簡陋的認證過程,通過用戶名(或用戶ID)和密碼明文驗證該用戶是否可以登陸系統。 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
    #define _GNU_SOURCE

    #include

    #include
    #include
    #include
    #include
    #include
    #include

    #include
    #include
    #include
    #include
    #include

    typedef enum{
    AUTH_TYPE_AUTO,
    AUTH_TYPE_DES,
    AUTH_TYPE_MD5,

    NR_AUTH_TYPE
    }auth_type_t;

    typedef enum{
    AUTH_INFO_AUTO,
    AUTH_INFO_PASSWD,
    AUTH_INFO_SHADOW,

    NR_AUTH_INFO
    }auth_info_t;

    typedef struct login_info{
    char* login; /* login name */
    char* cname; /* cname */
    char* group;
    char* passwd; /* plain text password */

    uid_t uid;
    gid_t gid;

    uint16_t auth_type;
    uint16_t auth_info;
    }login_info_t;

    static login_info_t login_info = {
    NULL, NULL, NULL, NULL, -1, -1, 0, 0,
    };

    static int verbose_flag;

    /**
    * option for getopt_long
    */
    static const struct option opt_options[] = {
    {"user", 1, 0, 'n'},
    {"uid", 1, 0, 'u'},
    {"password", 1, 0, 'p'},
    {"help", 0, 0, '?'},
    {"version", 0, 0, 'V'},
    {"verbose", 0, 0, 'v'},
    {0, 0, 0, 0},
    };

    static void help(void)
    {
    const struct option* o;

    for(o = &opt_options[0]; o && o->name; o++){
    fprintf(stderr, "%s\n", o->name);
    }
    fprintf(stderr, "\n");
    }

    static void version(void)
    {
    fprintf(stderr, "version: 0.0.1\n");
    }

    int verbose(const char* fmt, ...)
    {
    va_list ap;
    int n;

    if(!verbose_flag)
    return 0;

    va_start(ap, fmt);
    n = vfprintf(stderr, fmt, ap);
    va_end(ap);

    return 0;
    }

    int auth_des(const char* plain_text, const char* key_compare)
    {
    char* des_key;
    char salt[2] = ;

    if(strlen(key_compare) < 2)
    return -1;

    strncpy(salt, key_compare, 2);

    des_key = crypt(plain_text, salt);

    if(strcmp(des_key, key_compare) == 0)
    return 0;

    verbose("auth DES: non-match(Wrong) password!\n");

    return -1;
    }

    /**
    * need GNU libc 2.x or higher
    */

    int auth_md5(const char* plain_text, const char* key_compare)
    {
    char* md5_key;
    const char* p;
    char salt[12] = ;
    int n = 0;

    if(strlen(key_compare) < 3)
    return -1;

    if(strncmp(key_compare, "$", 3) != 0){ /* not start with "$", please confirm
    to /etc/shadow file */
    verbose("auth MD5: not start with \"$\"\n");
    return -1;
    }

    p = key_compare + 3;

    while(*p++){
    ++n;
    if(!p){
    verbose("auth MD5: invalid shadowed MD5 password!\n");
    return -1; /* invalid shadowed md5 password */
    }

    if(n > 8){
    break;
    }
    if(*p == '$'){
    break;
    }
    }

    strncpy(salt, key_compare, n + 3);
    md5_key = crypt(plain_text, salt);

    if(strcmp(md5_key, key_compare) == 0)
    return 0;

    verbose("auth MD5, non-match(Wrong) password!\n");

    return -1;
    }

    int check_shadowed_passwd(login_info_t* login_info)
    {
    struct passwd* pw;
    struct spwd* spw;

    if(login_info->login){
    spw = getspnam(login_info->login);
    }else if(login_info->uid >= 0){
    pw = getpwuid(login_info->uid);
    if(!pw){
    verbose("getpwuid [%d] failed, error: %s\n", login_info->uid,
    strerror(errno));
    return -1;
    }
    login_info->login = pw->pw_name;
    spw = getspnam(pw->pw_name);
    }else{
    return -1;
    }

    if(!spw){
    fprintf(stderr, "unable to read shadow passwd info: %s\n",
    strerror(errno));
    return -1;
    }

    if(login_info->auth_type == AUTH_TYPE_AUTO){
    if(strncmp(spw->sp_pwdp, "$", 3) == 0){ /* GNU extension, md5 used */
    return auth_md5(login_info->passwd, spw->sp_pwdp);
    }else{
    return auth_des(login_info->passwd, spw->sp_pwdp);
    }
    }else if(login_info->auth_type == AUTH_TYPE_DES){
    return auth_des(login_info->passwd, spw->sp_pwdp);
    }else if(login_info->auth_type == AUTH_TYPE_MD5){
    return auth_md5(login_info->passwd, spw->sp_pwdp);
    }else{
    verbose("unknown auth type: %d\n", login_info->auth_type);
    return -1;
    }
    }

    /**
    * checkpasswd
    */

    int check_passwd(login_info_t* login_info)
    {
    struct passwd* pw;

    if(login_info->login){
    pw = getpwnam(login_info->login);
    if(!pw){
    verbose("getpwnam [%s] failed, error: %s\n", login_info->login,
    strerror(errno));
    return -1;
    }
    login_info->uid = pw->pw_uid;
    }else if(login_info->uid >= 0){
    pw = getpwuid(login_info->uid);
    if(!pw){
    verbose("getpwuid [%d] failed, error: %s\n", login_info->uid,
    strerror(errno));
    return -1;
    }
    login_info->login = pw->pw_name;
    }else{
    return -1;
    }

    if(!login_info->passwd){
    verbose("no password specified!\n");
    return -1;
    }

    if(login_info->auth_info == AUTH_INFO_AUTO){
    if(strlen(pw->pw_passwd) < 2){
    if(strcmp(pw->pw_passwd, "x") == 0){ /* shadow password used */
    return check_shadowed_passwd(login_info);
    }else{
    return -1;
    }
    }
    return auth_des(login_info->passwd, pw->pw_passwd);
    }else if(login_info->auth_info == AUTH_INFO_PASSWD){
    return auth_des(login_info->passwd, pw->pw_passwd);
    }else if(login_info->auth_info == AUTH_INFO_SHADOW){
    return check_shadowed_passwd(login_info);
    }else{
    verbose("unknown auth info: %d\n", login_info->auth_info);
    return -1;
    }
    }

    void handle_args(int argc, char* argv[])
    {
    int ch;
    int option_index;

    while((ch = getopt_long(argc, argv, "u:i:p:Vvh", opt_options, &option_index)) != -1){
    switch(ch){
    case 'u':
    login_info.login = optarg;
    break;
    case 'i':
    login_info.uid = atoi(optarg);
    break;
    case 'p':
    login_info.passwd = optarg;
    break;
    case 'h':
    help();
    exit(0);
    break;
    case 'V':
    version();
    exit(0);
    break;
    case 'v':
    verbose_flag = 1;
    break;
    case '?':
    default:
    help();
    exit(1);
    break;
    }
    }

    if(!login_info.passwd){
    fprintf(stderr, "please specifie login password\n");
    help();
    exit(1);
    }
    if(!login_info.login && !login_info.uid){
    fprintf(stderr, "please specifie either login name or user id\n");
    help();
    exit(1);
    }
    }

    int main(int argc, char* argv[])
    {
    int ret;
    const char seperator[] =
    "==========================================================================================\n";
    int retcode = 1;

    handle_args(argc, argv);

    printf(seperator);

    ret = check_passwd(&login_info);

    if(ret < 0){
    fprintf(stderr, "3[1;31mauthentication failed for user: "
    "[%s], uid[%d], password: [%s]3[m\n",
    login_info.login, login_info.uid, login_info.passwd);
    goto quit;
    }else if(ret == 0){
    printf("3[1;32mauthenticated token suclearcase/" target="_blank" >ccessfully, user: "
    "[%s], uid: [%d]3[m\n",
    login_info.login, login_info.uid);
    retcode = 0;
    }else{
    assert(0);
    retcode = -1;
    }

    quit:
    printf(seperator);
    exit(retcode);
    }



    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>