2012-05-11 43 views
5

Mới để Stackoverflow, vì vậy trước hết, xin chào.ssh sử dụng python không có khóa RSA

Tôi đang làm việc trên một dự án nhỏ cho trường học của tôi mà được cho là một gui tùy chỉnh (viết bằng python như một thách thức giáo dục đối với tôi vì tôi chưa bao giờ sử dụng python) cho chương trình Unison nguồn mở. Chúng tôi đang cố gắng cho phép sinh viên và nhân viên đồng bộ hóa một thư mục ở nhà và ở trường bằng cách khởi chạy chương trình này với ít đầu vào nhất có thể (nếu bạn muốn). Giao diện được cho là chỉ là tên người dùng và mật khẩu của trường học và trình bao bọc gui chỉ cần gửi tên người dùng và mật khẩu để hủy liên kết và đồng bộ hóa chúng.

Vấn đề là Unison lần lượt khởi chạy SSh và nhắc mật khẩu nhưng phương thức python subprocess.communicate (input) sẽ không cho phép ssh lấy mật khẩu. Tôi nhận ra ssh sẽ chỉ chấp nhận đầu vào từ thiết bị đầu cuối và tôi không thể tìm ra cách để lừa nó. Tôi đã đọc một số công cụ về cách sử dụng một thiết bị đầu cuối giả nhưng tôi vẫn stumped. Các khóa RSA sẽ là giải pháp lý tưởng, nhưng tạo chúng và sau đó đặt chúng trên máy chủ từ xa vẫn liên quan đến việc tôi cần phải đăng nhập bằng mật khẩu ít nhất một lần và yêu cầu giải pháp ở trên hoặc thiết bị đầu cuối không phải là bằng chứng ngu ngốc.

def startSync(self): 
    ''' 
    ''' 
    userName = self.userNameIn.get() 
    userPass = self.userPassIn.get() 
    localDir = "/Users/localuser/syncFolder/" 
    remoteDir = " ssh://schoolServer/remotesyncFolder" #for testing purposes, I set this to my own home machine which logs into my own account if I don't provide [email protected] 
    unisonExecRemotePath = " -servercmd /Users/RemoteMe/unison" #unison is the unix executable responsible for launching unison on the remote system 
    silenceCmdPrompts = " -silent" #keeps unison from displaying directory differences and asking if its okay to sync 
    executionString = "./unison" + localDir + remoteDir + unisonExecRemotePath + silenceCmdPrompts 

    mainProcess = subprocess.Popen(executionString,shell = True, stdin = subprocess.PIPE) 
    mainProcess.communicate(userPass) 

Chuỗi thực thi hoạt động tốt ở đầu cuối nếu tôi dán vào. Và mọi mẹo trăn chung cũng sẽ được đánh giá cao nếu bạn nghiêng.

Cảm ơn!

Unison Hướng dẫn sử dụng: http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html

Chỉnh sửa: Tôi cũng nên lưu ý rằng trong khi tôi đang phát triển dưới OSX và Linux, tôi cuối cùng sẽ phải làm cho cửa sổ này tương thích vì hầu hết các học sinh trung học của tôi chạy cửa sổ như họ máy chính (hoặc chỉ).

Trả lời

3

Nhìn vào pexpect.

import pexpect 

child = pexpect.spawn('ssh [email protected]') 
child.expect('Password:') 
child.sendline(mypassword) 
child.interact() 
+0

Tôi vừa thử nghiệm dự án này với chính xác những gì bạn có ở đó (rõ ràng với máy chủ thực) và không có gì xảy ra. Chế độ tạm dừng nhẹ và sau đó quay lại dấu nhắc bash không có thư. Tôi đã thử thêm toàn bộ dòng thực thi từ mã ở trên của tôi nghĩ có lẽ nó chỉ đóng nếu không có gì được trao cho nó, nhưng nó cũng làm như vậy. – Hiroshi

+0

Đảm bảo rằng đối số bạn chuyển tới child.expect() khớp với dấu nhắc mật khẩu mà máy chủ cung cấp cho bạn. Ngoài ra, bạn có thể cần gọi child.interact() sau child.sendline (mypassword). Nó đã được một thời gian kể từ khi tôi sử dụng pexpect, nhưng nó là công cụ cho công việc. –

+0

Đã hoạt động! Cảm ơn! :) – Hiroshi

2

Nếu bạn muốn gửi một mật khẩu để ssh bạn cần phải mở pseudoterminal (một pty) và nói chuyện với nó bằng cách sử rằng thay vì chỉ sử dụng stdin/stdout. Hãy xem mô-đun pexpect, được thiết kế để thực hiện chính xác điều đó.

Giải pháp thay thế sẽ bao gồm một số cơ chế ngoài băng để phân phối khóa công khai: ví dụ: thiết lập ứng dụng web đơn giản nơi mọi người có thể dán khóa công khai và quản lý tệp authorized_keys thay mặt người dùng.

Các vấn đề liên quan