Sign in to follow this  
Followers 0
jvanegmond

Simple telnet server skeleton with authentication

13 posts in this topic

#1 ·  Posted (edited)

I find myself in need of a simple telnet server skeleton all the time. I've written one a long time ago, but could never find it again, until on attempt #9001 I did find it here:

From the example I have stripped all the code that made it actually do something, so we are left with a nice and simple telnet server skeleton that accepts the command: quit, help, command1, command2 and command3. Any and all questions are welcome.

Most of it can be written far more nicely, but I like the simple and honest way it works right now.

;; SETTINGS HERE, CHANGE THESE
Global Const $sAdminPass = "manadar" ;; Admin password. Change this please.
;; END OF SETTINGS, STOP CHANGING!!

;; Do not touch these "settings" / global variables
Global Const $sAppName = "Manadar.com Telnet Server"
Global Const $nVersion = 1.2
Global Const $sWelcomeMessage = $sAppName & " [Version " & $nVersion & "]" & @CRLF & "Created by: Manadar.com in 2008"

;; TCP Variables
Dim $sMaxConnections = 10
Dim $sSocket[$sMaxConnections], $sBuffer[$sMaxConnections], $iAuth[$sMaxConnections]

;; TCP Options
Dim $sIPAddress = @IPAddress1, $nPort = 23

TCPStartup()

$sMainSocket = TCPListen($sIPAddress, $nPort, 5)
If @error Then
    Switch @error
        Case 1
            _FatalError("The listening address was incorrect (Possibly another server was already running): " & $sIPAddress)
        Case 2
            _FatalError("The listening port was incorrect (Possibly another server was already running): " & $nPort)
        Case Else
            _FatalError("Unable to set up a listening server on " & $sIPAddress & ":" & $nPort)
    EndSwitch
EndIf

While 1
    ;; Accept new incoming clients, and ask them to authorise.
    $sNewSocket = TCPAccept($sMainSocket)
    If $sNewSocket > -1 Then
        For $x = 0 To UBound($sSocket) - 1
            If Not $sSocket[$x] Then
                $sSocket[$x] = $sNewSocket
                $iAuth[$x] = 0
                TCPSend($sSocket[$x], $sWelcomeMessage & @CRLF & @CRLF)
                TCPSend($sSocket[$x], "Please enter the administrator password" & @CRLF & ">")
                ExitLoop
            EndIf
        Next
    EndIf

    ;; Loop through existing connections, check if they sent us any data
    For $x = 0 To UBound($sSocket) - 1
        If $sSocket[$x] Then

            ;; Handle incoming data
            $sData = TCPRecv($sSocket[$x], 100)
            $sBuffer[$x] &= $sData
            If @error Then
                TCPCloseSocket($sSocket[$x])
                $sSocket[$x] = ""
                $sBuffer[$x] = ""
                $iAuth[$x] = 0
            ElseIf Asc($sData) = 0x8 Then ;backspace received
                $len = StringLen($sBuffer[$x])
                $sBuffer[$x] = StringTrimRight($sBuffer[$x], 2) ; trim the buffer
                If $len = 1 Then
                    TCPSend($sSocket[$x], ">")
                Else
                    TCPSend($sSocket[$x], " " & Chr(0x8))
                EndIf
            EndIf

            ;; Handle data, in case data is complete: ended with newline
            If StringInStr($sBuffer[$x], @CRLF) Then
                $sBuffer[$x] = StringTrimRight($sBuffer[$x], 2)

                ;; Check if user is authorised
                If $iAuth[$x] == 0 Then
                    ;; Not authorised, user is typing password
                    If ($sBuffer[$x] == $sAdminPass) Then
                        $iAuth[$x] = 1
                        TCPSend($sSocket[$x], "Administrator authorisation granted." & @CRLF & @CRLF & "Type 'help' for a list of the available commands." & @CRLF & ">")
                    Else
                        TCPSend($sSocket[$x], "Access denied." & @CRLF & ">")
                    EndIf

                Else
                    ;; Is authorised with password, do some commands
                    Switch $sBuffer[$x]
                        Case "quit", "q", "exit"
                            ; Closes the server on the remote client
                            TCPCloseSocket($sSocket[$x])
                            $sSocket[$x] = ""
                            $sBuffer[$x] = ""
                            $iAuth[$x] = 0
                        Case "command1", "command2", "command3"
                            TCPSend($sSocket[$x], "You executed a command")
                        Case "?", "help"
                            TCPSend($sSocket[$x], @CRLF & "quit" & @TAB & @TAB & "Closes connection to the Server" & @CRLF & _
                                    "command1" & @TAB & @TAB & "Description for command1" & @CRLF & _
                                    "command2" & @TAB & @TAB & "Description for command2" & @CRLF & _
                                    "command3" & @TAB & @TAB & "Description for command3" & @CRLF & _
                                    "help" & @TAB & "View this help message again")
                        Case Else
                            TCPSend($sSocket[$x], "Invalid command. Please type 'help' for a list of commands.")
                    EndSwitch
                    TCPSend($sSocket[$x], @CRLF & ">")
                EndIf
                $sBuffer[$x] = ""
            EndIf
        EndIf
    Next
WEnd

Func MessageBroadcast($sMsg)
    For $n = 0 To UBound($sSocket) - 1
        If $sSocket[$n] AND $iAuth[$n] == 1 Then
            TCPSend($sSocket[$n], $sMsg)
        EndIf
    Next
EndFunc   ;==>MessageBroadcast

Func _FatalError($msg)
    ConsoleWrite(@CRLF & "! " & $msg & @CRLF)
    MsgBox(0, $sAppName & $nVersion, "A fatal error has occured and " & $sAppName & " has to be closed with the error message: " & @CRLF & $msg)
    Exit
EndFunc
Edited by Manadar

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Remote access to computer via familiar command line interface (Wrapper around cmd.exe):

#include <Constants.au3>

;; SETTINGS HERE, CHANGE THESE
Global Const $sAdminPass = "manadar" ;; Admin password. Change this please.
;; END OF SETTINGS, STOP CHANGING!!

;; Do not touch these "settings" / global variables
;Global Const $sAppName = "Manadar.com Telnet Server"
;Global Const $nVersion = 1.2
;Global Const $sWelcomeMessage = $sAppName & " [Version " & $nVersion & "]" & @CRLF & "Created by: Manadar.com in 2008"

;; TCP Variables
Dim $sMaxConnections = 10
Dim $hSocket[$sMaxConnections], $sBuffer[$sMaxConnections], $iAuth[$sMaxConnections], $hCommand[$sMaxConnections], $bIgnoreCommand[$sMaxConnections]

;; TCP Options
Dim $sIPAddress = @IPAddress1, $nPort = 23

TCPStartup()

$sMainSocket = TCPListen($sIPAddress, $nPort, 5)
If @error Then
    Switch @error
        Case 1
            _FatalError("The listening address was incorrect (Possibly another server was already running): " & $sIPAddress)
        Case 2
            _FatalError("The listening port was incorrect (Possibly another server was already running): " & $nPort)
        Case Else
            _FatalError("Unable to set up a listening server on " & $sIPAddress & ":" & $nPort)
    EndSwitch
EndIf

While 1
    ;; Accept new incoming clients, and ask them to authorise.
    $sNewSocket = TCPAccept($sMainSocket)
    If $sNewSocket > -1 Then
        For $x = 0 To UBound($hSocket) - 1
            If Not $hSocket[$x] Then
                $hSocket[$x] = $sNewSocket
                $iAuth[$x] = 0
                ;TCPSend($hSocket[$x], $sWelcomeMessage & @CRLF & @CRLF)
                TCPSend($hSocket[$x], "Please enter the administrator password" & @CRLF & ">")
                ExitLoop
            EndIf
        Next
    EndIf

    ;; Loop through existing connections, check if they sent us any data
    For $x = 0 To UBound($hSocket) - 1
        If $hSocket[$x] Then

            ;; Handle incoming data
            $sData = TCPRecv($hSocket[$x], 100)
            $sBuffer[$x] &= $sData
            If @error Then
                TCPCloseSocket($hSocket[$x])
                $hSocket[$x] = ""
                $sBuffer[$x] = ""
                $iAuth[$x] = 0
                ProcessClose($hCommand[$x])
            ElseIf Asc($sData) = 0x8 Then ;backspace received
                $len = StringLen($sBuffer[$x])
                $sBuffer[$x] = StringTrimRight($sBuffer[$x], 2) ; trim the buffer
                If $len = 1 Then
                    TCPSend($hSocket[$x], ">")
                Else
                    TCPSend($hSocket[$x], " " & Chr(0x8))
                EndIf
            EndIf

            ;; Handle data, in case data is complete: ended with newline
            If StringInStr($sBuffer[$x], @CRLF) Then
                $sBuffer[$x] = StringTrimRight($sBuffer[$x], 2)
                If StringLen($sBuffer[$x]) = 0 Then
                    $sBuffer[$x] = " " ; You cannot send "nothing" over TCP (no packet is sent), thus I replace it with something non obstrusive
                EndIf

                ;; Check if user is authorised
                If $iAuth[$x] == 0 Then
                    ;; Not authorised, user is typing password
                    If ($sBuffer[$x] == $sAdminPass) Then
                        $iAuth[$x] = 1
                        $hCommand[$x] = Run("cmd", @ScriptDir, @SW_HIDE, $STDIN_CHILD + $STDERR_CHILD + $STDOUT_CHILD)
                        TCPSend($hSocket[$x], "Administrator authorisation granted." & @CRLF & @CRLF)
                        ConsoleWrite($x & " logged in with admin password." & @CRLF)
                    Else
                        TCPSend($hSocket[$x], "Access denied." & @CRLF & ">")
                    EndIf
                Else
                    If $sBuffer[$x] <> "" Then ; stop making output if user starts typing, then punch him in the face or something for fucking it up
                        ConsoleWrite($sBuffer[$x] & @CRLF)
                        StdinWrite($hCommand[$x], $sBuffer[$x] & @CRLF)
                        $bIgnoreCommand[$x] = True
                    EndIf
                EndIf
                $sBuffer[$x] = ""
            EndIf

            If $iAuth[$x] Then ; no @CRLF in buffer, but user is authed for output
                $line = StdoutRead($hCommand[$x])
                If $line <> "" Then
                    If $bIgnoreCommand[$x] Then
                        $line = StringTrimLeft($line, StringInStr($line, @LF)+1)
                        $bIgnoreCommand[$x] = False
                    EndIf
                    ConsoleWrite($line & @CRLF)
                    TCPSend($hSocket[$x], $line)
                EndIf
            EndIf
        EndIf
    Next
WEnd

Func MessageBroadcast($sMsg)
    For $n = 0 To UBound($hSocket) - 1
        If $hSocket[$n] AND $iAuth[$n] == 1 Then
            TCPSend($hSocket[$n], $sMsg)
        EndIf
    Next
EndFunc   ;==>MessageBroadcast

Func _FatalError($msg)
    ConsoleWrite(@CRLF & "! " & $msg & @CRLF)
    ;MsgBox(0, $sAppName & $nVersion, "A fatal error has occured and " & $sAppName & " has to be closed with the error message: " & @CRLF & $msg)
    Exit
EndFunc
Edited by Manadar

Share this post


Link to post
Share on other sites

Seems pretty useful but I've grown to step away from telnet and embrace ssh, purely for the sake of encryption and not sending cleartext.

Share this post


Link to post
Share on other sites

Seems pretty useful but I've grown to step away from telnet and embrace ssh, purely for the sake of encryption and not sending cleartext.

Understandable. I'll see how much effort it will be to create a ssh server using these specs and some packet analysis.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Are you per suing with the ssh idea???

Not in the next few months, sorry. I am short on time and have a few other more urgent private projects that are huge. If you wish to use this server with SSH, then you can use a SSH tunnel program. Edited by Manadar

Share this post


Link to post
Share on other sites

I noticed that the first time you try to login you get the "Access Denied" message. Even if I type the correct password I still get that. It only works the second time.

Is there any way to fix this?

Share this post


Link to post
Share on other sites

I noticed that the first time you try to login you get the "Access Denied" message. Even if I type the correct password I still get that. It only works the second time.

Is there any way to fix this?

It connects the first time perfectly fine. You must of changed something in your source. Also make sure your using the right case, passwords are case sensitive.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

I did change the script, but when I saw that it doesn't log in the first time I ran the original one and the results are the same.

Posted Image

Uploaded with ImageShack.us

I have Windows 7 x64 installed. Maybe it's because of my OS?

Edited by s0arec

Share this post


Link to post
Share on other sites

I did change the script, but when I saw that it doesn't log in the first time I ran the original one and the results are the same.

Posted Image

Uploaded with ImageShack.us

I have Windows 7 x64 installed. Maybe it's because of my OS?

Try using telnet and not putty. It could very well be your client (Putty).

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

You were right it was from my client. I tried logging in with Microsoft's telnet client and it worked, and then I tried logging in with Putty and when I changed the connection type to raw it worked.

Thanks!

Edited by s0arec

Share this post


Link to post
Share on other sites

Seems pretty useful but I've grown to step away from telnet and embrace ssh, purely for the sake of encryption and not sending cleartext.

So what if we throw in some encrypting functions that heavily encrypt the data before sending it to the client, and what if the client is also designed to decrypt the data that was sent to it?


Things that I've done..

Icon Resource Editor: icon resource editor 

AutoIt Piano: a piano

AutoIt Unlocker: unlocks files when you want to delete them

Colorful tooltips: a wrapper for the tool tips UDF

Rouge GoogleBot: a full screen animation

ASciTE text editor: a text editor written in autoit

Warning: Posts by this user are subject to change or may disappear without notice.

Share this post


Link to post
Share on other sites

Hello, sorry to revive this post. Is there anyway to avoid the authentication part? I need to make it communicate with a system that doesn't allow sending command to a telnet server that requests authentication. Any clue on how to edit the code?

 

Thank you

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0