LoginSignup
0
0

More than 1 year has passed since last update.

ろうとるがPythonを扱う、、続き(telnetlib, expect())

Posted at

Pythonでtelnet

こちらの記事「ろうとるがPythonでWindowsプログラムをつくる」の関連で、sshではなく、telnetを扱う機会があった。Pythonのtelnetlibを利用し、Telnet.expect()のサンプルとして、日本語で記載されたものがほとんど見つからないので、ここに記録する。

telnetサーバーへのログイン

やることは単純。telnetサーバーへのログインスクリプトをPythonで実現する。

telnetサーバー

テストで用いたtelnetサーバーは、「HK-TELNET-SERVER」。ここからダウンロードできる。起動すると下記のようになる。
hk telnet server.png
ユーザーを作成(CREATE USER)し、STARTする。

ソースコード

importなど。

import telnetlib
import logging
import logging.handlers
from datetime import datetime
import time
import getpass

SUCCESS = 0
FAILURE = 1

パスワード入力(見えないように)のために、「getpass」が使われている。

telnetサーバーへの接続。

### Connect to Server
def connect_srv():
    ret = FAILURE
    log.debug("== connect_srv ==")
    dst = input("Enter IP address: ")
    log.debug(f"IP address:{dst}")
    try:
        tn = telnetlib.Telnet(dst, 23, 3)
    except IOError:
        print('Connection Error.')
        log.debug('Connection Error.')
        return ret, 1
    except Exception:
        print('Other Erros in Open.')
        log.debug('Other Errors in Open')
        return ret, 1

    while True:
        id = input("Enter ID: ")
        key = getpass.getpass()
        log.debug(f"Input - User:{id}  Password:{key}")
        tn.read_until(b"Username")
        tn.read_very_eager();
        log.debug('-- Send Username --')
        tn.write(id.encode('ascii') + b"\r\n")
        tn.read_until(b"Password")
        tn.read_very_eager();
        log.debug('-- Send Password --')
        tn.write(key.encode('ascii') + b"\r\n")
        time.sleep(1)
        index, match, text = tn.expect([b">", b"Invalid"], 3) # ここがポイント
        log.debug(text.decode() + "\r\n")
        if index == 0:
            #log.debug('Connected.')
            print('Connected.')
            ret = SUCCESS
            break
        elif index == 1:
            print('Authentication Error. Please retry.')
            log.debug('Authentication Error. Please retry.' + '\r\n')
            time.sleep(1)
            # retry
        else:
            print('Other Errors.')
            log.debug('Other Errors.')
            tn.close()
            break
        #end while        

    tn.read_very_eager();
    return ret, tn   
### End of connect_src()

「index, match, text = tn.expect([b">", b"Invalid"], 3) 」がポイント。用いたtelnetサーバーは、ログイン成功時のプロンプトの最後の文字は「>」となり、ログイン失敗時は「Invalid」を返すため、リストを用いて双方を待ち受ける。「3」はタイムアウト(秒)。「>」を受信すればindexは「0」となり、「Invalid」を受信すればindexは「1」となる。それによって、処理を分ける。ここでは、「Invalid」(認証エラー)時には、再度IDとパスワードとの入力に戻る。

メイン部分。

# ログファイル
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
fh = logging.FileHandler('{:LogT-%Y%m%d-%H%M%S}.log'.format(datetime.now()))
log.addHandler(fh)

log.debug('=== Start ===')

# telnetサーバーへの接続
ret, tns = connect_srv()
if ret == SUCCESS:
    print('>> Can do commmands. <<')
    # Do something by using tns like sending commands
    tns.close()

log.debug('=== End ===')

ログファイル設定、telnetサーバーへの接続、成功時のメッセージ出力。

テスト

$ python このファイル.py

ログファイル

接続エラー

=== Start ===
== connect_srv ==
IP address:192.168.250.4
Connection Error.
=== End ===

認証失敗およびリトライ後の成功

=== Start ===
== connect_srv ==
IP address:192.168.250.2
Input - User:test  Password:test
-- Send Username --
-- Send Password --
****

Invalid

Authentication Error. Please retry.

Input - User:test  Password:Himitsu
-- Send Username --
-- Send Password --
****

 [ USERNAME = test ] YOUR IP ADDRESS : 192.168.250.1
 Welcome to Hadi Kiamarsi TELNET Server.

TELNET # H:\Software\hk-telnet-server-version-3-0-1\>

=== End ===

期待どおり。

画面出力

接続エラー

Enter IP address: 192.168.250.4
Connection Error.

認証失敗および成功

Enter IP address: 192.168.250.2
Enter ID: test
Password: 
Authentication Error. Please retry.
Enter ID: test
Password: 
Connected.
>> Can do commmands. <<

その他

Windows10でのtelnetの情報は、ここなどに見つかる。

EOF

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0