2011-12-27 3 views
1

나는 한 명의 사용자가 test입니다.paramiko에서 명령을 처음 호출 할 때 암호를 설정하는 방법은 무엇입니까?

해당 사용자가 chage 명령으로 로그인하면 암호가 변경됩니다.

chage -E 2012-01-25 -M 30 -d 0 -W 10 -I 5 test 

그래서 내가 ls

[[email protected] ~]# ssh [email protected] "ls" 
WARNING: Your password has expired. 
Password change required but no TTY available. 
You have new mail in /var/spool/mail/root 

그런 다음 내가 ssh

[[email protected] ~]# ssh [email protected] 
You are required to change your password immediately (root enforced) 
Last login: Tue Dec 27 09:55:55 2011 from localhost 
WARNING: Your password has expired. 
You must change your password now and login again! 
Changing password for user test. 
Changing password for test. 
(current) UNIX password: 

로 그리고 난이 사용자의 암호를 설정할 수있는 것보다 연결을 시도 명령을 실행하려고하면.

paramiko으로 연결하려고하면. 그런 다음

In [1]: import paramiko 

In [2]: ssh_conn = paramiko.SSHClient() 

In [3]: ssh_conn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 

In [4]: ssh_conn.load_system_host_keys() 

In [5]: ssh_conn.connect('n2001', username='root_acc23', password='test') 

In [6]: a = ssh_conn.exec_command('ls') 

In [7]: print a[2].read() 
WARNING: Your password has expired. 
Password change required but no TTY available. 

좀 구글을하고 내가 쓴 invoke_shell 쇼를 하나 개의 기능으로 새 암호를 설정하는 몇 가지 해결책을 찾기

def chage_password_change(ssh_conn, password, curr_pass): 
    ''' 
    If got error on login then set with interactive mode. 
    ''' 
    interact = ssh_conn.invoke_shell() 
    buff = '' 
    while not buff.endswith('UNIX password: '): 
     resp = interact.recv(9999) 
     buff += resp 
    interact.send(curr_pass + '\n') 

    buff = '' 
    while not buff.endswith('New password: '): 
     resp = interact.recv(9999) 
     buff += resp 

    interact.send(password + '\n') 

    buff = '' 
    while not buff.endswith('Retype new password: '): 
     resp = interact.recv(9999) 
     buff += resp 

    interact.send(password + '\n') 


    interact.shutdown(2) 
    if interact.exit_status_ready(): 
     print "EXIT :", interact.recv_exit_status() 

    print "Last Password" 
    print "LST :", interact.recv(-1) 

이것은 우리가, ALPA에게 자리 적절한 암호를 줄 때와 같은 경우에 노력하고 있습니다 특수 문자 조합. 우리는 약간 짧은 암호 또는 오류를 줄 때

는하지만 우리는 오류를 BAD PASSWORD있어이 명령에서이

[[email protected] ~]# ssh [email protected] 
You are required to change your password immediately (root enforced) 
Last login: Tue Dec 27 10:41:15 2011 from localhost 
WARNING: Your password has expired. 
You must change your password now and login again! 
Changing password for user test. 
Changing password for test. 
(current) UNIX password: 
New password: 
Retype new password: 
BAD PASSWORD: it is too short 

같은 비밀번호 변경에서 발생 : 그래서 이것이 내가 내 함수를 결정하지 못할 너무 짧습니다. interact.recv(-1) 할 때이 오류가 발생하지만이 stdout 생각합니다. 그래서 이것이 오류라고 판단 할 수있는 방법이 있습니다.

paramiko doc을 확인한 결과 recv_stderr_readyrecv_stderr이라는 클래스가 있지만이 오류는 해당 데이터에 포함되어 있지 않습니다.

Thx 사전에 도움을 받으십시오.

답변

3

쉬운 대답은 컷오프가 무엇인지 알면 셸을 호출하기 전에 함수의 암호 길이를 확인하는 것입니다. 더 나은 성능. 그러나 컷오프를 모르는 경우 작동하지 않습니다.

설명에 분명하지 않지만 BASS PASSWORD 메시지가 interact.recv (-1)에서 돌아 오면 문제가 발생했다는 것을 알게되고 그에 따라 진행할 수 있습니다. 그것은 stdout 또는 stdout 중 하나에서 다시오고 있어야하므로, 둘 다 확인하십시오. 새 암호가 승인 된 경우 어떤 텍스트가 다시 제공되는지 알면이를 확인할 수도 있습니다. 당신이 먼저 무엇을 얻었는지 당신에게 알려주고, 당신의 기능은 거기에서 계속 될 수 있습니다.

+2

들으 @ScottHunter. 나는 그 오류가 2-3 개의 가능한 단어일지도 모른다는 것을 안다. stdout을 검사하지 않고 stderr에서 출력을 얻으면 에러를 발생시키고 싶습니다. stdout과 stderr에 오류가 있는지 확인해야한다면 stdout에서 매번 확인해야합니다. – Nilesh

+0

불행히도 stdout이 오류 메시지가 기록되는 곳이면 어디에서 읽어야합니까? 죄송합니다. –

+0

Okey 귀하의 도움을 위해 STDOUT thx에서 읽습니다. – Nilesh

1

다음 행은 문제가 될 수 있으며 몇 가지 버그가 발생할 수 있습니다 :

while not buff.endswith('Retype new password: '): 
     resp = interact.recv(9999) 
     buff += resp // this will append the output from the shell 

코드 수정 :

이 더 나은 그것을 지금 이런 식으로

while not buff.endswith('Retype new password: '): 
    resp = interact.recv(9999) 
    buff = resp 

각 반복을 사용하는 것 루프는 현재의 \ 업데이트 된 출력 텍스트를 셸에서 파싱합니다.

감사합니다, 답장을 보내 엘닷

관련 문제