Seite 1 von 1

Bug in telnetlib?

Verfasst: Mittwoch 12. November 2008, 10:37
von jens
Experimentiere gerade mit [mod]telnetlib[/mod] unter Windows. Ich verbinde mich auch mit dem Windowsrechner (localhost)...

Wenn ich debug mit tn.set_debuglevel(999) einschalte, kann ich sehen, das Daten die gesendet werden nur mit "\n" abgeschlossen sind. Das scheint aber mit Windows nicht zu funktionieren, weil "\n\r" erwartet wird!

Kann jeder unter Windows ja mal selber Testen mit dem hier:

Code: Alles auswählen

import sys
import telnetlib

HOST = "localhost"

print "connect '%s'..." % HOST,
tn = telnetlib.Telnet(HOST)
print "OK"

tn.set_debuglevel(1)

tn.mt_interact()
Man muß den "telnet" Dienst anhaben und den User in die Gruppe "TelnetClients" packen.

Es sieht so aus:
connect 'localhost'... OK
...
Telnet(localhost,23): recv 'Welcome to Microsoft Telnet Service \r\n'
Welcome to Microsoft Telnet Service
Telnet(localhost,23): recv '\n\rlogin: '


login: jens
Telnet(localhost,23): send 'jens\n'
Telnet(localhost,23): recv 'jens'
jens
Es wird also nur mit "\n" gesendet und man kommt nicht weiter...

Mit "\n\r" geht's aber, siehe:

Code: Alles auswählen

import sys
import telnetlib

HOST = "localhost"

print "connect '%s'..." % HOST,
tn = telnetlib.Telnet(HOST)
print "OK"

tn.set_debuglevel(1)

tn.read_until('login: ')
tn.write("jens\r\n")

tn.mt_interact()
Ausgabe:
connect 'localhost'... OK
...
Telnet(localhost,23): recv 'Welcome to Microsoft Telnet Service \r\n'
Telnet(localhost,23): recv '\n\rlogin: '
Telnet(localhost,23): send 'jens\n\r'
Telnet(localhost,23): recv 'jens\n\rpassword: '
jens

password:
Nun wurde der Username akzeptiert und man kommt zur Passwort abfrage...

hab in den Quellen von telnetlib.py gesucht, aber nichts gefunden, wie man das Problem ändern könnte.

(Getestet mit Python 2.5.2 unter Vista.)

Lustig ist, das es egal ist ob "\n\r" oder "\r\n" gesendet wurde ;)

Verfasst: Mittwoch 12. November 2008, 12:22
von Fabian Kochem
Und wo liegt das Problem, \r ebenfalls noch mitzusenden?
Kannst ja eine Wrapper-Methode bauen, die das automatisch für dich erledigt (vllt noch überprüft, ob der zu sendene String bereits mit \n oder \r endet).

Verfasst: Mittwoch 12. November 2008, 12:24
von jens
Das Problem ist, das man so ohne weiteres nicht einfach nur tn.mt_interact() nutzten kann. Ein Wrapper bauen könnte man zwar tun, aber ist doch nur ein work-a-round. IMHO sollte es einfach so funktionieren...

Verfasst: Mittwoch 12. November 2008, 14:30
von HWK
Das scheint aber nichts mit der telnetlib zu tun zu haben. Ich habe dasselbe Phänomen auch bei 2 über die serielle Schnittstelle verbundenen Rechnern beobachtet. Eingaben vom Windows- an den Linuxrechner wurden nur akzeptiert, wenn diese mit '\r\n' abgeschlossen wurden.
MfG
HWK

Verfasst: Mittwoch 12. November 2008, 14:43
von Y0Gi
Hast du vielleicht mal die Telnet-RFC gelesen? Ich glaube auch, dass man sich hier nach den Delimitern richten sollte, die das Protokoll vorschreibt und nicht nach denen, die das Betriebssystem in Dateien verwendet. HTTP klappt auch nicht nur mit einem Newline.

Verfasst: Mittwoch 12. November 2008, 15:06
von BlackJack
Ein wirklich ganz kurzer Blick in RFC854 lässt mich vermuten, dass das Telnet-Protokoll einfach CR LF oder LF CR erwartet bzw. vorschreibt.

edit: Ups da war ich wohl auch mit dem ganz kurzen Blick zu langsam. :-)

Verfasst: Mittwoch 12. November 2008, 15:18
von Y0Gi
Keine Sorge, kurz reingeblickt hab' ich da auch ;)

Verfasst: Mittwoch 12. November 2008, 15:59
von jens
Naja, egal was die RFC854 nun vorschreibt, fakt ist, das es bei mir ertmal nur dann funktioniert, wenn \r\n oder \n\r gesendet wird und nicht nur ein \n...

Somit sollte entweder os.linesep genommen werden, oder zumindest die Möglichkeit die zeilenenden einfach zu ändern. z.B.:

Code: Alles auswählen

tn = telnetlib.Telnet(HOST, linesep=os.linesep)
oder so...

Verfasst: Mittwoch 12. November 2008, 16:53
von Y0Gi
Äh nee, es ist *nicht* egal, was die RFC vorschreibt - dafür ist ein Standard ja da. Und wenn der das festlegt, dann braucht man eine Library auch nicht konfigurierbar machen.

Und wie kommst du überhaupt auf die Idee, einen "file separator" mit einem Telnet-Kommando-Delimiter gleichsetzen zu wollen? Und wieso sollte der überhaupt uneinheitlich sein? Wie soll man gegen so eine (fehlende) Konvention denn etwas implementieren?

Verfasst: Donnerstag 13. November 2008, 09:38
von jens
Verwechselst du os.linesep mit os.sep?
http://docs.python.org/dev/library/os.html#os.linesep
http://docs.python.org/dev/library/os.html#os.sep

In einer guten, schönen Welt sollte man sich auf RFC und Co. verlassen können. In der bösen M$ Welt aber nicht. Gefällt mir auch nicht, aber so ist es halt.

Die Aufforderung "dann nimm doch ein gescheites Betriebsystem" hilft da auch nicht weiter...

Verfasst: Donnerstag 13. November 2008, 12:03
von Leonidas
jens hat geschrieben:In einer guten, schönen Welt sollte man sich auf RFC und Co. verlassen können. In der bösen M$ Welt aber nicht. Gefällt mir auch nicht, aber so ist es halt.

Die Aufforderung "dann nimm doch ein gescheites Betriebsystem" hilft da auch nicht weiter...
Es hilft insefern weiter, dass man kaputte Implementationen vermeidet. Die richtige Lösung wäre entweder ein anderes OS zu verwenden, einen anderen Telnet-Server oder gleich SSH. ``telnetlib`` empfinde ich als überflüssig, ist ähnlich nüzlich wie eine ``gopherlib``, selbst wenn Windows einen Gopher-Server mitliefern würde.

Verfasst: Donnerstag 13. November 2008, 14:09
von Y0Gi
jens hat geschrieben:Verwechselst du os.linesep mit os.sep?
Tatsache. Ich sehe allerdings nicht ein, wieso sich ein plattformübergreifendes/-unabhängiges Protokoll an den Eigenheiten einzelner Betriebssysteme orientieren sollte, solange sie ein bisschen mit ASCII hantieren können.