Jump to content

Simple telnet server skeleton with authentication


jvanegmond
 Share

Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

Link to comment
Share on other sites

  • 1 month later...

Are you per suing with the ssh idea???

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Link to comment
Share on other sites

  • 2 months later...

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.
Link to comment
Share on other sites

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
Link to comment
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?

Link to comment
Share on other sites

  • 6 years later...
  • 3 months later...

I know this is an old thread, but could somebody please tell me what the difference is here. I use windows 7 ftp to connect to my server on port 21, and although I can receive messages from my server (like '220 connection okay') I can not type anything to send to my server. but yet when I use telnet  I can freely type.

how do I set up my autoit server so that when I connect with FTP I accept input? Something tells me there is a lot more to TCP/FTP I do not understand.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...