मैं सिस्टम लॉगिन के लिए परीक्षण कैसे लिखूं?


9

मैंने पायथन सीजीआई स्क्रिप्ट लिखी है जो bashकमांडों को आमंत्रित करती है , और इसे मेजबान पर एक सफल लॉगिन के लिए परीक्षण करने की आवश्यकता है।

मैं उसके लिए परीक्षण कैसे लिखूं?

उदाहरण के लिए, क्या मैं एक bashस्क्रिप्ट बना सकता हूँ जो होस्ट पर पंजीकृत उपयोगकर्ता के खिलाफ दिए गए उपयोगकर्ता नाम और पासवर्ड संयोजन का परीक्षण करती है?


1
शायद आप loginप्रोग्राम के पीछे कोड को देख सकते हैं ।
केविन

प्रश्न से संबंधित नहीं है, लेकिन मुझे आशा है कि आप अपने वेब सर्वर पर ट्रैफ़िक को एन्क्रिप्ट कर रहे हैं ताकि उपयोगकर्ता लॉगिन को तार से सूँघा न जा सके।
jw013

जवाबों:


8

PAM का उपयोग करना सबसे अच्छा उपाय है। आप छोटे C कोड लिख सकते हैं, या अजगर-पीएम पैकेज स्थापित कर सकते हैं और एक पायथन स्क्रिप्ट का उपयोग कर सकते हैं जो अजगर-पीएम पैकेज के साथ आता है। देख/usr/share/doc/python-pam/examples/pamtest.py


मैं पीएएम की कोशिश करता हूं, लेकिन यह काम नहीं किया। लेकिन मैं फिर से इस उदाहरण की कोशिश करता हूं और यह काम करता है।
जकुबिक

1
OpenSUSE 12.3 (python-pam 0.5.0-84.1.1) और 13.1 (0.5.0-87.1.2) में, pamtest.py के लिए पूर्ण पथ /usr/share/doc/packages/python-pam/examples/pamtest.pyस्क्रिप्ट pamtest.py का उपयोग PAM का उपयोग कर सिस्टम पर क्रेडेंशियल्स का परीक्षण करने के लिए किया जा सकता है प्रमाणीकरण के लिए, अजगर-पैम पैकेज (जिसमें अजगर की आवश्यकता होती है) में शामिल है, और कुछ वितरणों में पूर्ण पथ है /usr/share/doc/python-pam/examples/pamtest.py
शाद्सटरलिंग

5

परीक्षण करने का सही तरीका कि क्या कोई उपयोगकर्ता लॉग इन कर सकता है, वास्तव में उस उपयोगकर्ता के रूप में लॉग इन कर सकता है।

तो मैं जो सलाह देता हूं वह है कि CGI स्क्रिप्ट expectको चलाने के लिए उपयोग करें su, एक पासवर्ड पास करें और उस कमांड को चलाएं जिसे निष्पादित किया जाना चाहिए। यहां एक उम्मीद की स्क्रिप्ट का मसौदा तैयार किया गया है जो सिर्फ यही करता है (चेतावनी: बिल्कुल अप्रयुक्त, और मैं उम्मीद में धाराप्रवाह नहीं हूं)। उपयोगकर्ता नाम, पासवर्ड और कमांड (जहां मैंने लिखा था bob, swordfishऔर somecommand) में स्थानापन्न ; सही ढंग से उद्धृत करना सुनिश्चित करें।

spawn "/bin/su" "bob"
expect "Password:"
send "swordfish\r"
expect "^\\$"
send "somecommand"
expect -re "^\\$"
send "exit\r"
expect eof

यदि आप वास्तव में su(उदाहरण के लिए क्योंकि आपको CGI प्रक्रिया द्वारा स्वयं को निष्पादित करने की आवश्यकता है) की एक परत के माध्यम से कमांड निष्पादित नहीं करना चाहते हैं , तो कमांड चलाने की उम्मीद का उपयोग trueकरें और जांचें कि रिटर्न स्थिति 0 है।

एक और तरीका यह होगा कि आप अपने आवेदन में सीधे PAM का उपयोग करें, पाइथन के PAM बाइंडिंग के माध्यम से ।


यह बहुत बढ़िया है, एकमात्र उपाय जो रूट एक्सेस के बिना है।
जकुबिक १४'१२

यह काम करता है su -c true bob && echo successयह शर्म की बात है कि su पासवर्ड को तर्क के रूप में स्वीकार नहीं करता है
jcubic

मैंने suCGI स्क्रिप्ट से परीक्षण किया और इसे काम करने के लिए एक टर्मिनल की आवश्यकता है।
जकुबिक

3
@jcubic कमांड लाइन के तर्क में पासवर्ड लगाना वास्तव में एक मूर्खतापूर्ण विचार है, क्योंकि कमांड लाइन के तर्क एक यूनिक्स प्रणाली पर सार्वजनिक हैं। पासवर्ड को हटाने से कमांड लाइन में डालने के समान सुरक्षा मिलेगी। और यह जांचना बहुत आसान /bin/trueहोगा : पर्याप्त होगा।
छत

2

अधिक विशेष रूप से उत्तर देने के लिए: "क्या यह संभव है कि एक बश लिपि बनाई जाए जो किसी दिए गए उपयोगकर्ता नाम और पासवर्ड के संयोजन को मेजबान पर रजिस्टर्ड उपयोगकर्ता के खिलाफ परीक्षण करेगी?"

हाँ।

#!/bin/bash
uid=`id -u`

if [ $uid -ne 0 ]; then 
    echo "You must be root to run this"
    exit 1
fi

if [ $# -lt 1 ]; then
    echo "You must supply a username to check - ($# supplied)"
    exit 1
fi

username=$1
salt=`grep $username /etc/shadow | awk -F: ' {print substr($2,4,8)}'`

if [ "$salt" != "" ]; then

        newpass=`openssl passwd -1 -salt $salt`
        grep $username  /etc/shadow | grep -q  $newpass && echo "Success" || echo "Failure"

fi

2
क्या यह आपके लिए काम करता है? मैं देख रहा हूं कि आप छाया पासवर्ड के खिलाफ मौजूदा छाया पासवर्ड की जांच कर रहे हैं, लेकिन हैशिंग यहां कहां शामिल है?
निखिल मुल्ले

मैंने परीक्षण किया और यह काम नहीं करता है
jcubic

3
बुरा विचार! आप मान रहे हैं कि आपका कार्यक्रम रूट के रूप में चल रहा है, या कम से कम shadowसमूह के रूप में , जो बहुत दृढ़ता से एक सीजीआई के लिए अनुशंसित नहीं है: आपको विशेषाधिकार वृद्धि की एक और परत की आवश्यकता होगी। और आप एक विशेष पासवर्ड हैशिंग एल्गोरिथ्म (एक ओपनसेल द्वारा समर्थित) और पासवर्ड भंडारण स्थान ( /etc/shadowउदाहरण के लिए एनआईएस या एलडीएपी के विपरीत ) मान रहे हैं, जो उस विशेष उपयोगकर्ता के लिए वास्तव में उपयोग किया जा सकता है या नहीं भी हो सकता है।
गिल्स एसओ- बुराई को रोकना

2

यहाँ उद्धृत एक 'C', 'पायथन' PAM समाधान है, मुझे एक भी डाल देना है :-)

स्रोत: http://search.cpan.org/~nikip/Authen-PAM-0.16/PAM/FAQ.pod#1._Can_I_authenticate_a_user_non_interactively ?

#!/usr/bin/perl

  use Authen::PAM;
  use POSIX qw(ttyname);

  $service = "login";
  $username = "foo";
  $password = "bar";
  $tty_name = ttyname(fileno(STDIN));

  sub my_conv_func {
    my @res;
    while ( @_ ) {
        my $code = shift;
        my $msg = shift;
        my $ans = "";

        $ans = $username if ($code == PAM_PROMPT_ECHO_ON() );
        $ans = $password if ($code == PAM_PROMPT_ECHO_OFF() );

        push @res, (PAM_SUCCESS(),$ans);
    }
    push @res, PAM_SUCCESS();
    return @res;
  }

  ref($pamh = new Authen::PAM($service, $username, \&my_conv_func)) ||
         die "Error code $pamh during PAM init!";

  $res = $pamh->pam_set_item(PAM_TTY(), $tty_name);
  $res = $pamh->pam_authenticate;
  print $pamh->pam_strerror($res),"\n" unless $res == PAM_SUCCESS();

हाँ, ठीक है, लेकिन यह सवाल पायथन में लिखी गई एक सीजीआई स्क्रिप्ट के बारे में था।
गिल्स एसओ- बुराई को रोकना '

1

यदि आपके पास रूट एक्सेस है, और md5 पासवर्ड का उपयोग कर रहे हैं, और आपको केवल पासवर्ड की तुलना करने की आवश्यकता है, तो आप पर्ल क्रिप्ट का उपयोग कर सकते हैं :: PasswdMD5 मॉड्यूल। MD5 हैश को / etc / छाया से लें, $ 1 $ की पट्टी करें, और फिर शेष $ पर विभाजित करें। फ़ील्ड 1 = नमक, फ़ील्ड 2 = क्रिप्टेड टेक्स्ट। फिर अपने सीजीआई में हैश इनपुट करें, इसकी तुलना क्रिप्टेड टेक्स्ट और बॉब के अपने चाचा से करें।

#!/usr/bin/env perl

use Crypt::PasswdMD5;

my $user                = $ARGV[0];
my $plain               = $ARGV[1];
my $check               = qx{ grep $user /etc/shadow | cut -d: -f2 };
chomp($check);
my($salt,$md5txt)       = $check =~ m/\$1\$([^\$].+)\$(.*)$/;
my $pass                = unix_md5_crypt($plain, $salt);

if ( "$check" eq "$pass" ) {
        print "OK","\n";
} else {
        print "ERR","\n";
}

2
सादा और सरल :-)। यह तब तक काम करेगा जब तक / etc / passwd md5 हैशिंग का उपयोग करता है। सिस्टम के लिए प्रमाणीकरण (nsswitch) अलग है, तो pam मॉड्यूल का उपयोग करना सबसे अच्छा है।
निखिल मुल्ले

2
बुरा विचार! आप मान रहे हैं कि आपका कार्यक्रम रूट के रूप में चल रहा है, या कम से कम shadowसमूह के रूप में , जो बहुत दृढ़ता से एक सीजीआई के लिए अनुशंसित नहीं है: आपको विशेषाधिकार वृद्धि की एक और परत की आवश्यकता होगी। और आप एक विशेष पासवर्ड हैशिंग एल्गोरिदम (MD5 और अन्य अनुशंसित एल्गोरिथ्म नहीं) और पासवर्ड भंडारण स्थान ( /etc/shadowउदाहरण के लिए NIS या LDAP के विपरीत ) मान रहे हैं , जो वास्तव में उस विशेष उपयोगकर्ता के लिए उपयोग किया जा सकता है या नहीं भी हो सकता है।
गिल्स एसओ- बुराई को रोकना

0

कुछ खोज के बाद मैंने इस C प्रोग्राम को लिखा जिसका उपयोग स्क्रिप्ट से किया जा सकता है

#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
#include <shadow.h>
#include <string.h>
#include <crypt.h>
#include <unistd.h>
#include <libgen.h>

int main(int argc, char **argv) {
    struct spwd *pwd;
    if (argc != 3) {
        printf("usage:\n\t%s [username] [password]\n", basename(argv[0]));
        return 1;
    } else if (getuid() == 0) {
        pwd = getspnam(argv[1]);
        return strcmp(crypt(argv[2], pwd->sp_pwdp), pwd->sp_pwdp);
    } else {
        printf("You need to be root\n");
        return 1;
    }
}

आप इसे संकलित करते हैं:

gcc -Wall password_check.c /usr/lib/libcrypt.a -o check_passwd

आप इसका उपयोग कर सकते हैं

sudo ./check_passwd <user> <password> && echo "success" || echo "failure"

1
बुरा विचार! आप मान रहे हैं कि आपका कार्यक्रम रूट के रूप में चल रहा है, या कम से कम shadowसमूह के रूप में , जो बहुत दृढ़ता से एक सीजीआई के लिए अनुशंसित नहीं है: आपको विशेषाधिकार वृद्धि की एक और परत की आवश्यकता होगी। और आप एक विशेष पासवर्ड हैशिंग एल्गोरिथ्म (एक ओपनसेल द्वारा समर्थित) और पासवर्ड भंडारण स्थान ( /etc/shadowउदाहरण के लिए एनआईएस या एलडीएपी के विपरीत ) मान रहे हैं, जो उस विशेष उपयोगकर्ता के लिए वास्तव में उपयोग किया जा सकता है या नहीं भी हो सकता है। PAM का उपयोग करें, यह अपनी नौकरी जानता है।
गिल्स का SO-

हां, मुझे पता है, लेकिन यह सोचा कि यह जड़ के बिना सकारात्मक नहीं है। अन्य सभी समाधान जड़ के रूप में अच्छी तरह से उपयोग करते हैं, तुम्हारा निर्वासन करते हैं।
जकुबिक १४'१२

0

चूंकि आपने उल्लेख किया है कि आप अजगर में CGI का उपयोग कर रहे हैं, तो शायद यह मान लेना कि आप Apache को अपने httpd सर्वर के रूप में उपयोग कर रहे हैं। यदि ऐसा है, तो अपाचे के लिए अपने प्रोग्राम की प्रमाणीकरण प्रक्रिया को छोड़ दें और केवल प्रमाणित लोगों को ही आपके cgi स्क्रिप्ट / प्रोग्राम को निष्पादित करने दें।

पर्याप्त मॉड्यूल हैं जो अपाचे पर आपके लिए प्रमाणीकरण कर सकते हैं, यह वास्तव में इस बात पर निर्भर करता है कि आप किस तरह के प्रमाणीकरण तंत्र की तलाश कर रहे हैं। जिस तरह से आप प्रश्न में उद्धृत करते हैं, वह स्थानीय होस्ट खाता प्रमाणीकरण / / / पासव्ड, छाया फ़ाइलों के आधार पर संबंधित लगता है। मॉड्यूल जो इस बारे में मेरी त्वरित खोज के लिए आता है mod_auth_shadow। लाभ यह है कि आप अपने लिए उपयोगकर्ता / पासवर्ड को प्रमाणित करने के लिए किसी को आधिकारिक (विशेषाधिकार पोर्ट 80 पर चलने) की अनुमति दे रहे हैं और जरूरत पड़ने पर उपयोगकर्ता की ओर से कमांड चलाने के लिए उपयोगकर्ता की प्रमाणित जानकारी पर भरोसा कर सकते हैं।

शुरू करने के लिए अच्छे लिंक:

http://adam.shand.net/archives/2008/apache_tips_and_tricks/#index5h2

http://mod-auth-shadow.sourceforge.net/

http://www.howtoforge.com/apache_mod_auth_shadow_debian_ubuntu

एक अन्य दृष्टिकोण अपाचे के SuEXEc मॉड्यूल का उपयोग करना है, जो प्रमाणित उपयोगकर्ता की ओर से प्रक्रियाओं (cgi प्रोग्राम) को निष्पादित करता है।


यह CGI स्क्रिप्ट JSON-RPC सेवा है जिसे अजाक्स के माध्यम से कहा जाता है और मुझे एक विधि लॉगिन की आवश्यकता है जो एक टोकन लौटाती है, यदि लॉगिन सफल होता है तो टोकन लौटाया जाना चाहिए। इसलिए आधारभूत प्रत्येक उपयोगकर्ता को उस स्क्रिप्ट को निष्पादित करने में सक्षम होना चाहिए।
जकुबिक १४'१२

0

PAM का उपयोग करने वाले इस कोड ने मेरे लिए काम किया:

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>
#include <string.h>

// Define custom PAM conversation function
int custom_converation(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata_ptr)
{
    // Provide password for the PAM conversation response that was passed into appdata_ptr
    struct pam_response* reply = (struct pam_response* )malloc(sizeof(struct pam_response));
    reply[0].resp = (char*)appdata_ptr;
    reply[0].resp_retcode = 0;

    *resp = reply;

    return PAM_SUCCESS;
}

int main (int argc, char* argv[]) 
{
    if (argc > 2)
    {
        // Set up a custom PAM conversation passing in authentication password
        char* password = (char*)malloc(strlen(argv[2]) + 1);
        strcpy(password, argv[2]);        
        struct pam_conv pamc = { custom_converation, password };
        pam_handle_t* pamh; 
        int retval;

        // Start PAM - just associate with something simple like the "whoami" command
        if ((retval = pam_start("whoami", argv[1], &pamc, &pamh)) == PAM_SUCCESS)
        {
            // Authenticate the user
            if ((retval = pam_authenticate(pamh, 0)) == PAM_SUCCESS) 
                fprintf(stdout, "OK\n"); 
            else 
                fprintf(stderr, "FAIL: pam_authentication failed.\n"); 

            // All done
            pam_end(pamh, 0); 
            return retval; 
        }
        else
        {
            fprintf(stderr, "FAIL: pam_start failed.\n"); 
            return retval;
        }
    }

    fprintf(stderr, "FAIL: expected two arguments for user name and password.\n"); 
    return 1; 
}

क्या आप इसे उत्तर की तरह "महसूस" करने के लिए कुछ संदर्भ जानकारी जोड़ सकते हैं?
वोल्कर सीगल

-3

सबसे अच्छी बात जो आप कर सकते हैं, यदि आपको एक होस्ट में लॉगिन करने के लिए स्क्रिप्ट की आवश्यकता है, तो मेजबानों के बीच एक ssh कुंजी कॉन्फ़िगर करें।

लिंक: http://pkeck.myweb.uga.edu/ssh/

मैंने पेज से इसे बहुत हटा लिया


सबसे पहले, दो UNIX मशीनों पर ओपनएसएसएच को स्थापित करें, जल्दी और पूरी तरह से। जहाँ तक मैं बता सकता हूँ डिफ़ॉल्ट रूप से डीएसए कुंजी और SSH2 का उपयोग करके यह सबसे अच्छा काम करता है। अन्य सभी HOWTOs मैंने देखा है कि RSA कुंजियों और SSH1 से निपटना प्रतीत होता है, और निर्देश आश्चर्यजनक रूप से SSH2 के साथ काम करने में विफल नहीं होते हैं। प्रत्येक मशीन पर ssh somemachine.example.com टाइप करें और अपने नियमित पासवर्ड के साथ संबंध बनाएं। यह आपके घर निर्देशिका में उचित परमिट के साथ .ssh dir बनाएगा। अपनी प्राथमिक मशीन पर जहां आप चाहते हैं कि आपकी गुप्त कुंजियाँ जीवित रहें (चलो जल्दी से कहो), टाइप करें

ssh-keygen -t dsa

यह आपको गुप्त पासफ़्रेज़ के लिए संकेत देगा। यदि यह आपकी प्राथमिक पहचान कुंजी है, तो एक अच्छा पासफ़्रेज़ का उपयोग करना सुनिश्चित करें। यदि यह सही काम करता है तो आपको अपने .ssh dir में id_dsa और id_dsa.pub नामक दो फाइलें मिलेंगी। नोट: पासफ़्रेज़ के लिए संकेत दिए जाने पर, एंटर कुंजी को दबाया जाना संभव है, जो बिना पासफ़्रेज़ के कुंजी बना देगा। यह एक पहचान कुंजी के लिए एक बुरा आइडिया ™ है, इसलिए ऐसा न करें! पासफ़्रेज़ के बिना कुंजियों के उपयोग के लिए नीचे देखें।

scp ~/.ssh/id_dsa.pub burly:.ssh/authorized_keys2

Id_dsa.pub फ़ाइल को अधिकृत host_ss2 नाम के साथ अन्य होस्ट के .ssh dir पर कॉपी करें। अब आपकी ssh कुंजी स्वीकार करने के लिए तैयार है। यह कैसे बताएं कि किस कुंजी का उपयोग करना है? Ssh-add कमांड इसे करेगा। एक परीक्षण के लिए, टाइप करें

ssh-agent sh -c 'ssh-add < /dev/null && bash'

यह ssh- एजेंट को शुरू करेगा, आपकी डिफ़ॉल्ट पहचान (आपके पासफ़्रेज़ के लिए आपको संकेत देना) जोड़ देगा, और एक बैश शेल स्पॉन करेगा। इस नए शेल से आप को सक्षम होना चाहिए:

ssh burly

आपको लॉग इन करने में सक्षम होना चाहिए


हालांकि यह सच है, यह सवाल के लिए प्रासंगिक नहीं दिखता है, जो कि वेब ब्राउज़र के माध्यम से एक्सेस किए गए एप्लिकेशन के बारे में है।
गिल्स एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.