This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Username and Password Server
Started by ratchetgame98, 17 July 2013 - 09:35 AMPosted 17 July 2013 - 11:35 AM
In my server, I have a computer room with a lot of computers, but I would really like a username and password server for the clients. Can someone please help. I will appreciate it
Posted 17 July 2013 - 11:44 AM
Check out the wiki.
Posted 17 July 2013 - 03:15 PM
First you'll want to set up a server that is sitting in a while loop listening for usernames/passwords. For example:
Next you'll want to flesh out that while loop with some way to verify actual requests. You'll need a way to store usernames/passwords as well - I would suggest using tables like this:
Then make a function that verifies the user:
So now we have a users table and a way to verify messages. All that's left now is to insert the onRequest function into our previous while loop.
Done with the server code, now onto the client code. This is quite simple. We'll want a way for users to input a username/password, and then we'll need to save that into a table. We can then use textutils.serialize to format that table into a string and send it along to the server.
And that's about it! Hopefully that's not too much to take in. If you need any help, feel free to ask.
local auth_channel = 234 --#This is just a random channel that we'll use for listening on
local modem = peripheral.wrap("top") --#Or whatever the side is
modem.open(auth_channel)
while true do
local event, sender, reply, message = os.pullEvent("modem_message")
end
Next you'll want to flesh out that while loop with some way to verify actual requests. You'll need a way to store usernames/passwords as well - I would suggest using tables like this:
local users = {
["username"] = "password";
["bubba"] = "not_my_password";
}
Then make a function that verifies the user:
local function onRequest(message)
--[[#A user has to send their messages in string form. In order to check both
#the username and password from a single message however, it would be benficial to use a table.
#Fortunately, textutils provides the perfect utility for this.]]
local tMessage = textutils.unserialize(message)
if not tMessage then --#The user sent a message in the wrong form
print("Invalid message type received - not a table!")
elseif users[tMessage["username"]]==tMessage["password"] then --#If they sent a correct user/password
return true
else --#Invalid username or password
return false
end
end
So now we have a users table and a way to verify messages. All that's left now is to insert the onRequest function into our previous while loop.
local auth_channel = 234 --#This is just a random channel that we'll use for listening on
local modem = peripheral.wrap("top") --#Or whatever the side is
modem.open(auth_channel)
while true do
local event, modem_side, sender, reply_channel, message = os.pullEvent("modem_message")
if onRequest(message) then --#If they sent a valid message
modem.transmit(reply_channel, auth_channel, "valid")
else --#They sent a bad username/password or maybe not even in a table format
modem.transmit(reply_channel, auth_channel, "invalid")
end
end
Done with the server code, now onto the client code. This is quite simple. We'll want a way for users to input a username/password, and then we'll need to save that into a table. We can then use textutils.serialize to format that table into a string and send it along to the server.
local auth_channel = 234 --#Ensure that the auth channel is the same!
local myChannel = 10 --#Any channel the user wishes
local modem = peripheral.wrap("top")
modem.open(myChannel) --#We don't need to open the auth_channel to send messages, only if we need to receive on that channel
local authenticated = false --#In order to break the loop, we can simply change this to true.
while not authenticated do
term.clear() term.setCursorPos(1,1)
term.write("Username: ")
local username = read() --#Gets the user's input
local password = read("*") --#The asterisk is the masking character
local user_table = {["username"] = username, ["password"] = password}
modem.transmit(auth_channel, myChannel, textutils.serialize(user_table)) --#Go ahead and send off the info to the server
local response = false
while not response do --Now we wait for a response
local event, modem_side, sender_channel, reply_channel, message = os.pullEvent("modem_message")
if reply_channel == auth_channel then --#If it is indeed the server that sent the message
response = true
if message == "valid" then --#It was indeed a valid username/password combo
print("Valid username/password!") --#Do whatever you want here
authenticated = true
break
else --#Nope, invalid.
print("Invalid username/password!")
end
end
end
end
And that's about it! Hopefully that's not too much to take in. If you need any help, feel free to ask.
Posted 17 July 2013 - 03:43 PM
Done with the server code, now onto the client code. This is quite simple. We'll want a way for users to input a username/password, and then we'll need to save that into a table. We can then use textutils.serialize to format that table into a string and send it along to the server.local auth_channel = 234 --#Ensure that the auth channel is the same! local myChannel = 10 --#Any channel the user wishes local modem = peripheral.wrap("top") modem.open(myChannel) --#We don't need to open the auth_channel to send messages, only if we need to receive on that channel while true do term.clear() term.setCursorPos(1,1) term.write("Username: ") local username = read() --#Gets the user's input local password = read("*") --#The asterisk is the masking character local user_table = {["username"] = username, ["password"] = password} modem.transmit(auth_channel, myChannel, textutils.serialize(user_table)) --#Go ahead and send off the info to the server while true do --Now we wait for a response local event, modem_side, sender_channel, reply_channel, message = os.pullEvent("modem_message") if reply_channel == auth_channel then --#If it is indeed the server that sent the message if message == "valid" then --#It was indeed a valid username/password combo print("Valid username/password!") --#Do whatever you want here else --#Nope, invalid. print("Invalid username/password!") end end end end
And that's about it! Hopefully that's not too much to take in. If you need any help, feel free to ask.
you forgot to break the while true loop. it will start again and ask for a username and password… even if correct. Just to catch it before it comes back to haunt :D/>
local oldpullevent = os.pullevent
local os.pullevent = os.pullEventRaw
local auth_channel = 234 --#Ensure that the auth channel is the same!
local myChannel = 10 --#Any channel the user wishes
local modem = peripheral.wrap("top")
modem.open(myChannel) --#We don't need to open the auth_channel to send messages, only if we need to receive on that channel
while true do
term.clear() term.setCursorPos(1,1)
term.write("Username: ")
local username = read() --#Gets the user's input
local password = read("*") --#The asterisk is the masking character
local user_table = {["username"] = username, ["password"] = password}
modem.transmit(auth_channel, myChannel, textutils.serialize(user_table)) --#Go ahead and send off the info to the server
while true do --Now we wait for a response
local event, modem_side, sender_channel, reply_channel, message = os.pullEvent("modem_message")
if reply_channel == auth_channel then --#If it is indeed the server that sent the message
if message == "valid" then --#It was indeed a valid username/password combo
printError("Valid username/password!") --#Do whatever you want here + sets the exit error.
os.pullEvent = oldpullevent
error() -- Exit the program
else --#Nope, invalid.
print("Invalid username/password!")
sleep(3)
end
end
end
end
Posted 17 July 2013 - 04:09 PM
-snip-
Thanks for catching that. :)/>
However, I don't think erroring is a good way to get out of the program. Using a break statement is much better and allows you to use the same program to do other tasks after authentication. I have updated my original post to reflect this.
Posted 17 July 2013 - 04:30 PM
I'm planning to do something similar and have a few questions.
1. Is this modem thing for wired or wireless modems or does it work with both the same way? (yeah, a nooby question, i know :D/>)
2. Is there a hash function built in CC? That way I would not have to transmit the password directly. Of course one could then simply login with the hash which would have the same effect, but if the hash contains something like the current time (1-minute-accurate) this would generate a token which is only valid for 1 minute at most. Or is there even a way to use assymetric encryption (or should I go ahead and implement RSA myself? :D/>)?
3. If the password validation process, or any other process handled by the server, would take some time, this would block the connection for that time… Is there a way to spawn like a new thread for every request that reaches the server? I know there are the parallel and the coroutine API, but the wiki describes them in a not very detailed way.
Thx
1. Is this modem thing for wired or wireless modems or does it work with both the same way? (yeah, a nooby question, i know :D/>)
2. Is there a hash function built in CC? That way I would not have to transmit the password directly. Of course one could then simply login with the hash which would have the same effect, but if the hash contains something like the current time (1-minute-accurate) this would generate a token which is only valid for 1 minute at most. Or is there even a way to use assymetric encryption (or should I go ahead and implement RSA myself? :D/>)?
3. If the password validation process, or any other process handled by the server, would take some time, this would block the connection for that time… Is there a way to spawn like a new thread for every request that reaches the server? I know there are the parallel and the coroutine API, but the wiki describes them in a not very detailed way.
Thx
Posted 17 July 2013 - 05:26 PM
I do actually have a server setup for my passwords, that also displays the time, as an example of how fast the server can respond… I have it listening for rednet messages on a 0.8 pause, then update time. * this means if I get a rednet message it does not update time untill that message is dealt with and responded too…
So far, I have yet to see a login effect the update speed of the time / seconds passing (aka minecraft minutes)
I have to update my server code… found a bug in it. along the lines of a correct password would log you in as any user. after i fix this tomorrow I will try and do a pastebin upload.
So far, I have yet to see a login effect the update speed of the time / seconds passing (aka minecraft minutes)
I have to update my server code… found a bug in it. along the lines of a correct password would log you in as any user. after i fix this tomorrow I will try and do a pastebin upload.
Posted 21 July 2013 - 06:33 AM
First you'll want to set up a server that is sitting in a while loop listening for usernames/passwords. For example:local auth_channel = 234 --#This is just a random channel that we'll use for listening on local modem = peripheral.wrap("top") --#Or whatever the side is modem.open(auth_channel) while true do local event, sender, reply, message = os.pullEvent("modem_message") end
Next you'll want to flesh out that while loop with some way to verify actual requests. You'll need a way to store usernames/passwords as well - I would suggest using tables like this:local users = { ["username"] = "password"; ["bubba"] = "not_my_password"; }
Then make a function that verifies the user:local function onRequest(message) --[[#A user has to send their messages in string form. In order to check both #the username and password from a single message however, it would be benficial to use a table. #Fortunately, textutils provides the perfect utility for this.]] local tMessage = textutils.unserialize(message) if not tMessage then --#The user sent a message in the wrong form print("Invalid message type received - not a table!") elseif users[tMessage["username"]]==tMessage["password"] then --#If they sent a correct user/password return true else --#Invalid username or password return false end end
So now we have a users table and a way to verify messages. All that's left now is to insert the onRequest function into our previous while loop.local auth_channel = 234 --#This is just a random channel that we'll use for listening on local modem = peripheral.wrap("top") --#Or whatever the side is modem.open(auth_channel) while true do local event, modem_side, sender, reply_channel, message = os.pullEvent("modem_message") if onRequest(message) then --#If they sent a valid message modem.transmit(reply_channel, auth_channel, "valid") else --#They sent a bad username/password or maybe not even in a table format modem.transmit(reply_channel, auth_channel, "invalid") end end
Done with the server code, now onto the client code. This is quite simple. We'll want a way for users to input a username/password, and then we'll need to save that into a table. We can then use textutils.serialize to format that table into a string and send it along to the server.local auth_channel = 234 --#Ensure that the auth channel is the same! local myChannel = 10 --#Any channel the user wishes local modem = peripheral.wrap("top") modem.open(myChannel) --#We don't need to open the auth_channel to send messages, only if we need to receive on that channel local authenticated = false --#In order to break the loop, we can simply change this to true. while not authenticated do term.clear() term.setCursorPos(1,1) term.write("Username: ") local username = read() --#Gets the user's input local password = read("*") --#The asterisk is the masking character local user_table = {["username"] = username, ["password"] = password} modem.transmit(auth_channel, myChannel, textutils.serialize(user_table)) --#Go ahead and send off the info to the server local response = false while not response do --Now we wait for a response local event, modem_side, sender_channel, reply_channel, message = os.pullEvent("modem_message") if reply_channel == auth_channel then --#If it is indeed the server that sent the message response = true if message == "valid" then --#It was indeed a valid username/password combo print("Valid username/password!") --#Do whatever you want here authenticated = true break else --#Nope, invalid. print("Invalid username/password!") end end end end
And that's about it! Hopefully that's not too much to take in. If you need any help, feel free to ask.
Done with the server code, now onto the client code. This is quite simple. We'll want a way for users to input a username/password, and then we'll need to save that into a table. We can then use textutils.serialize to format that table into a string and send it along to the server.local auth_channel = 234 --#Ensure that the auth channel is the same! local myChannel = 10 --#Any channel the user wishes local modem = peripheral.wrap("top") modem.open(myChannel) --#We don't need to open the auth_channel to send messages, only if we need to receive on that channel while true do term.clear() term.setCursorPos(1,1) term.write("Username: ") local username = read() --#Gets the user's input local password = read("*") --#The asterisk is the masking character local user_table = {["username"] = username, ["password"] = password} modem.transmit(auth_channel, myChannel, textutils.serialize(user_table)) --#Go ahead and send off the info to the server while true do --Now we wait for a response local event, modem_side, sender_channel, reply_channel, message = os.pullEvent("modem_message") if reply_channel == auth_channel then --#If it is indeed the server that sent the message if message == "valid" then --#It was indeed a valid username/password combo print("Valid username/password!") --#Do whatever you want here else --#Nope, invalid. print("Invalid username/password!") end end end end
And that's about it! Hopefully that's not too much to take in. If you need any help, feel free to ask.
you forgot to break the while true loop. it will start again and ask for a username and password… even if correct. Just to catch it before it comes back to haunt :D/>local oldpullevent = os.pullevent local os.pullevent = os.pullEventRaw local auth_channel = 234 --#Ensure that the auth channel is the same! local myChannel = 10 --#Any channel the user wishes local modem = peripheral.wrap("top") modem.open(myChannel) --#We don't need to open the auth_channel to send messages, only if we need to receive on that channel while true do term.clear() term.setCursorPos(1,1) term.write("Username: ") local username = read() --#Gets the user's input local password = read("*") --#The asterisk is the masking character local user_table = {["username"] = username, ["password"] = password} modem.transmit(auth_channel, myChannel, textutils.serialize(user_table)) --#Go ahead and send off the info to the server while true do --Now we wait for a response local event, modem_side, sender_channel, reply_channel, message = os.pullEvent("modem_message") if reply_channel == auth_channel then --#If it is indeed the server that sent the message if message == "valid" then --#It was indeed a valid username/password combo printError("Valid username/password!") --#Do whatever you want here + sets the exit error. os.pullEvent = oldpullevent error() -- Exit the program else --#Nope, invalid. print("Invalid username/password!") sleep(3) end end end end
I've copied and pasted this code into the mod if that's alright, because, to be honest, i don't really understand all the code in ComputerCraft. If you want to, you can join my CCraft Server, just apply o the forums at computercraftschool.enjin.com
I've also figured out that something on the code doesn't work, because when I log in to the client, it doesn't got take me to the command lie, because on the server, there is an error on something
Spoiler
The client[attachment=1246:client.jpg]
The server after logging on
[attachment=1247:server.jpg]
I don't know what the error is, but can you please fix it
Posted 21 July 2013 - 08:42 AM
I actually lost this topic on the forums… lol I was trying to find it to post my pastebins of the code…
Server - Passwords
http://pastebin.com/JiQFgstb
Client - Login
http://pastebin.com/Y77DKddS
This is a functioning server login system that I use on my friends server.
uses rednet to communicate. (you have to edit where the configuration of senderId's etc) some setup is required after install on the server.
When you setup your server you need to do this…
0. ************* ATTACH A WIRELESS MODEM ******** hehe ( I nevvver forget that part ) [ read nevvver as always ]
1. start the computer (server) goto the command prompt, type id and hit enter. (note the id of the computer)
2. on ALL client computers. change the sever id varible to the id you just noted from the server. (hehe).
3. note the ID of every computer on your network.
4. Edit the server file and remove all numbers from the varible senders and insert your computer id's … remember to keep the { } and " , " beteeen each number.
5. setup your login names and passwords.
6. Choose an Admin terminal. (one computer not easy to access).
7. note your admin pc ID. then find "adminid = 12" in the code and change 12 to your admin id. ** make sure you setup a "admin" user with a complex password, not "notch" or "god"…
8. start the server.
Start a client pc and attempt a login.
Server - Passwords
http://pastebin.com/JiQFgstb
Client - Login
http://pastebin.com/Y77DKddS
This is a functioning server login system that I use on my friends server.
uses rednet to communicate. (you have to edit where the configuration of senderId's etc) some setup is required after install on the server.
When you setup your server you need to do this…
0. ************* ATTACH A WIRELESS MODEM ******** hehe ( I nevvver forget that part ) [ read nevvver as always ]
1. start the computer (server) goto the command prompt, type id and hit enter. (note the id of the computer)
2. on ALL client computers. change the sever id varible to the id you just noted from the server. (hehe).
3. note the ID of every computer on your network.
4. Edit the server file and remove all numbers from the varible senders and insert your computer id's … remember to keep the { } and " , " beteeen each number.
5. setup your login names and passwords.
6. Choose an Admin terminal. (one computer not easy to access).
7. note your admin pc ID. then find "adminid = 12" in the code and change 12 to your admin id. ** make sure you setup a "admin" user with a complex password, not "notch" or "god"…
8. start the server.
Start a client pc and attempt a login.
Posted 22 July 2013 - 09:22 AM
Thanks for all the help, but now i need a code for a computercraft bank. Can someone please help. Like always, it will be appreciated.
P.S. If you would like to join my server, go to this website, sign up and apply on the forums. Teaching polls are available.
http://computercraftschool.enjin.com
P.S. If you would like to join my server, go to this website, sign up and apply on the forums. Teaching polls are available.
http://computercraftschool.enjin.com
Posted 29 July 2013 - 04:07 AM
I actually lost this topic on the forums… lol I was trying to find it to post my pastebins of the code…
Server - Passwords
http://pastebin.com/JiQFgstb
Client - Login
http://pastebin.com/Y77DKddS
This is a functioning server login system that I use on my friends server.
uses rednet to communicate. (you have to edit where the configuration of senderId's etc) some setup is required after install on the server.
When you setup your server you need to do this…
0. ************* ATTACH A WIRELESS MODEM ******** hehe ( I nevvver forget that part ) [ read nevvver as always ]
1. start the computer (server) goto the command prompt, type id and hit enter. (note the id of the computer)
2. on ALL client computers. change the sever id varible to the id you just noted from the server. (hehe).
3. note the ID of every computer on your network.
4. Edit the server file and remove all numbers from the varible senders and insert your computer id's … remember to keep the { } and " , " beteeen each number.
5. setup your login names and passwords.
6. Choose an Admin terminal. (one computer not easy to access).
7. note your admin pc ID. then find "adminid = 12" in the code and change 12 to your admin id. ** make sure you setup a "admin" user with a complex password, not "notch" or "god"…
8. start the server.
Start a client pc and attempt a login.
I've done everything you said to do and it's working great thanks for the help but there is one problem. Even though I set my admin terminal and account other users that login as lets say a guest have the exact same commands/permissons as an admin does on the computer server. How do I change this? If you could help me out I would greatly appreciate it :)/> Thanks!
Posted 29 July 2013 - 05:09 AM
the admin login only effects the server computer. it enables the ctrl + T escape to exit the server, So if you login as admin (on the definied admin computer) then move to the server computer… you can then use CTRL+T to stop the server and edit the file.
The client computers are exactly the same, no matter who you login as. (the admin account was intended for server maintenance.)
The client computers are exactly the same, no matter who you login as. (the admin account was intended for server maintenance.)
Posted 29 July 2013 - 07:29 PM
Oh ok I gotcha ya. Thanks for clearing up that bit of confusion!