<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://www.computercraft.info/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bwhodle</id>
		<title>ComputerCraft Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://www.computercraft.info/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bwhodle"/>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/Special:Contributions/Bwhodle"/>
		<updated>2026-07-11T13:34:51Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.1</generator>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Network_Attacks&amp;diff=5993</id>
		<title>Network Attacks</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Network_Attacks&amp;diff=5993"/>
				<updated>2013-09-07T18:49:47Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wireless networking has loads of security flaws. Here are several possible attacks that hackers can do to exploit your system.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Passive Attacks ==&lt;br /&gt;
Passive attacks aim to obtain or view information or data in computer networks without modifying or interfering with anything occurring.&lt;br /&gt;
=== Wiretapping ===&lt;br /&gt;
An attacker can eavesdrop on rednet/modem communications an obtain sensitive information. Unless this information is encrypted, it can easily be read by the attacker, possibly compromising passwords, control signals, or other sensitive info.&lt;br /&gt;
&lt;br /&gt;
'''Rednet''': Wiretapping via rednet can be done by listening on the target computers ID. This is possible because rednet uses the computers ID as the channel number when sending messages to it. Without rednet, the attacker would have to determine which channel that computer is listening on.&lt;br /&gt;
=== Mimicry ===&lt;br /&gt;
An attacker can run a server that listens on the same channel or spoofs the ID of a legitimate server, causing users with the client program to send their data to both the legitimate server and the attacker, who now knows the information.&lt;br /&gt;
Mimicry is possible by mimicking a server identically, except spoofing and wiretapping on its channel. By doing this, an attacker can provide services just like the server, except note the messages sent and received.&lt;br /&gt;
&lt;br /&gt;
== Active Attacks ==&lt;br /&gt;
Active attacks are designed to modify or interrupt normal system usage.&lt;br /&gt;
=== Backdoor ===&lt;br /&gt;
Backdoors are essentially tunnels that lead into a computer which must be manually opened by an attacker.&lt;br /&gt;
A backdoor generally works like this:&lt;br /&gt;
# The attacker sends a program on a channel that the backdoor is listening on.&lt;br /&gt;
# The backdoor finds the program, downloads it, and executes it.&lt;br /&gt;
The program that the backdoor executes can be any form of malicious thing, such as copying or modifying files or programs, setting of redstone signals, or anything else an attacker would like to do.&lt;br /&gt;
Backdoors are usually difficult to put onto a computer, but they are possible to do.&lt;br /&gt;
=== Identity Spoof ===&lt;br /&gt;
Most web applications use computer ID's to determine if it is authentic or not. An attacker can assume a computer ID to bypass ID-based whitelists easily. &lt;br /&gt;
&lt;br /&gt;
'''Rednet''': Spoof via rednet is accomplished by indicating the ID to assume as the channel that the computer should reply on. Rednet uses the reply channel parameter as the ID of the sender.&lt;br /&gt;
=== Forgery ===&lt;br /&gt;
An attacker can send his own message to a client incapable of distinguishing the source of a message between the legitimate server or a forger, causing it to think it's a legitamate message. An attacker can also send a forged message to a server, causing it to think it came from the client.&lt;br /&gt;
&lt;br /&gt;
'''Rednet''': Mimicry via rednet can be done by sending a message to the target computers ID, since rednet.receive() will listen with a modem using the computers ID as the channel number.&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5992</id>
		<title>Login with Roaming Profiles</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5992"/>
				<updated>2013-09-07T18:41:29Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This tutorial covers how to make a password server and a password client. The server will host a Lua table of usernames and passwords and the client will remotely connect each start up, ask the user for their username and password and compare it to that on the password server.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Setting Up ==&lt;br /&gt;
First of all, you must know how to craft a [[Wireless_Modem|wireless modem]] and a [[Computer|computer]]. You need to craft at least 2 wireless modems and 2 computers if you want to have a practical use for this system. Then, attach 1 modem to each computer you want to add to the system.&lt;br /&gt;
&lt;br /&gt;
Second, since typing on normal computers is relatively slow and annoying, I recommend to write the programs in [[Advanced_Computers|advanced computers]](because in advanced computers you can click to move the cursor around, and there are colors to distinguis between different statements), copying them into a [[Floppy|disk]] and moving them into each computer you want to include(with their respective programs of course). Alternatively, if you are the server owner(this tutorial assumes you are in Multiplayer because this system does not have any practical use in Singleplayer), you can go into the world folder and write copy/paste the source code into the folders of each computer you want to use. The folders you should use are the named the IDs of the computers(so if you have 3 computers, with the IDs 5, 7 and 9, you should copy them into the folders 5, 7 and 9). &lt;br /&gt;
&lt;br /&gt;
It does not matter wether you are using Normal or Advanced computers for this tutorial. I recommend to use Normal ones for the server.&lt;br /&gt;
&lt;br /&gt;
When writing the programs, I HIGHLY recommend using a [[Disk_Drive|disk drive]] like stated above, so you dont have to write in prograns for every computer you add.&lt;br /&gt;
Remember to read the text behind the --. These are comments, and you can safely leave them in the code.&lt;br /&gt;
&lt;br /&gt;
== Server ==&lt;br /&gt;
 print(&amp;quot;Initializing...&amp;quot;)&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 valid = false&lt;br /&gt;
 tserved, vserved, dserved = 0&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading startup settings...&amp;quot;)&lt;br /&gt;
 count = true -- If you dont want the server to count request statics, set the value of this variable to &amp;quot;false&amp;quot; without qoutes.&lt;br /&gt;
 modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 whitelist = true -- If you dont want to use a whitelist, change the value to &amp;quot;false&amp;quot; without quotes. This is not recommended on Multiplayer, but it does not make any difference on a Singleplayer World.&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading user database...&amp;quot;)&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } -- Change this to the names for the users you want to have. Make sure the usernames are in the same order as in the password table. Changing the order is fine, but you must maintain the same order in both the users and passwords tables. Incorrect orders WILL cause 2 or more users not being able to log in!&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; } -- Change this to the passwords for the users defined in the variable above. Again, make sure the passwords for users are in the same order as the usernames.&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- change this to the ID's of the all computers you want to accept requests from if you use a whitelist. If you do not use a whitelist, DO NOT REMOVE THIS LINE! Doing so will cause the program to crash everytime it is run, even though the variable is not used.&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading core functions...&amp;quot;)&lt;br /&gt;
 function clear()&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1, 1)&lt;br /&gt;
 print(&amp;quot;CCLS Server 1.0 for CC 1.53&amp;quot;) &lt;br /&gt;
 print(&amp;quot;There is no user interaction here. Please contact your system administrator for assistance regarding the system.&amp;quot;)&lt;br /&gt;
 if count == true then&lt;br /&gt;
  print(tserved..&amp;quot; total requests received this session.&amp;quot;)&lt;br /&gt;
  print(vserved..&amp;quot; requests completed this session.&amp;quot;)&lt;br /&gt;
  print(dserved..&amp;quot; requests denied this session.&amp;quot;)&lt;br /&gt;
 elseif count == false then&lt;br /&gt;
  print(&amp;quot;Request statics have been disabled.&amp;quot;)&lt;br /&gt;
 else&lt;br /&gt;
  rednet.close(modemSide)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1, 1)&lt;br /&gt;
  print(&amp;quot;Error: Counter setting is not boolean and the server can not continue.&amp;quot;)&lt;br /&gt;
  print(&amp;quot;The server program will exit automatically in 10 minutes. Or you can hold down Ctrl+T for 1 second.&amp;quot;)&lt;br /&gt;
  print(&amp;quot;After that, please set the variable \&amp;quot;count\&amp;quot; in the source code to either \&amp;quot;true\&amp;quot; or \&amp;quot;false\&amp;quot; WITHOUT QUOTATION MARKS. Doing this with quotation marks will cause the same error.&amp;quot;)&lt;br /&gt;
  sleep(600)&lt;br /&gt;
  shell.exit()&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Starting up...&amp;quot;)&lt;br /&gt;
 rednet.open(modemSide) -- Opens the modem to wait for incoming login requests&lt;br /&gt;
 &lt;br /&gt;
 clear()&lt;br /&gt;
 &lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   tserved = tserved + 1&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;301&amp;quot;, true) -- Send response code 301 - which means Not Whitelisted.&lt;br /&gt;
    dserved = dserved + 1&lt;br /&gt;
    clear()&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
  password = passwords[i]&lt;br /&gt;
  rednet.send(senderId, password, true)&lt;br /&gt;
  vserved = vserved + 1&lt;br /&gt;
  clear()&lt;br /&gt;
  break&lt;br /&gt;
    else&lt;br /&gt;
  rednet.send(senderId, &amp;quot;300&amp;quot;, true) -- Send response code 300 - which means Bad Auth.&lt;br /&gt;
  dserved = dserved + 1&lt;br /&gt;
  clear()&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&amp;lt;!-- Latias1290, you should remove the branding part, it's a tutorial, not a publish program place. You should also explain everything --&amp;gt;&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local failed = true&lt;br /&gt;
 busr = &amp;quot;nsliq&amp;quot; -- If you ever happen to be unable to log in for some reason, you can use this username as a backup.&lt;br /&gt;
 bpass = &amp;quot;zuFUkVEjQKjkLQhTdpFMheNF&amp;quot; -- If you ever happen to be unable to log in for some reason, you can use this password as a backup.&lt;br /&gt;
 &lt;br /&gt;
 password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while true do&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;Welcome to CCLS 1.0 by Latias1290.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please select an option.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;[1] Login&amp;quot;)&lt;br /&gt;
 print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
 write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
 input = read()&lt;br /&gt;
 if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
  os.shutdown()&lt;br /&gt;
 elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
  print(&amp;quot;Please login.&amp;quot;)&lt;br /&gt;
  write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
  username = read()&lt;br /&gt;
  write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
  password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
  if username == busr then&lt;br /&gt;
  if password == bpass then&lt;br /&gt;
 print(&amp;quot;Access granted&amp;quot;)&lt;br /&gt;
 break&lt;br /&gt;
  end&lt;br /&gt;
  end&lt;br /&gt;
  rednet.send(password_server, username, true)&lt;br /&gt;
  senderId, message, distance = rednet.receive(5)&lt;br /&gt;
  if message == &amp;quot;300&amp;quot; then&lt;br /&gt;
  print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
  sleep(3)&lt;br /&gt;
  elseif password == message then&lt;br /&gt;
  failed = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
  break;&lt;br /&gt;
  else&lt;br /&gt;
  print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
  sleep(3)&lt;br /&gt;
  end&lt;br /&gt;
 else&lt;br /&gt;
  print(&amp;quot;Invalid Command.&amp;quot;)&lt;br /&gt;
  sleep(2)&lt;br /&gt;
 end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Flaws ==&lt;br /&gt;
The above login system has several flaws and vulnerabilities. &lt;br /&gt;
=== Credentials stored on volatile memory (Storage flaw) ===&lt;br /&gt;
The login credentials are stored in a table. Since tables are stored on volatile memory, the computer requires to be on at all times in order for the server to retain login credentials. Computers are automatically restarted on server reload or world reload, rendering this login system inefficient for long-term usage.&lt;br /&gt;
=== [[Network_Attacks#Identity_Spoof|Spoof Attack]] (Active Attack) ===&lt;br /&gt;
Although this system is designed to protect a computer rather than a system, the login server is undeniably vulnerable to ID spoof, where a malicious user assumes the ID of a whitelisted computer, and defeats the purpose of an ID whitelist entirely. More details can be found on the [[Rednet_(API)|Rednet API]] page.&lt;br /&gt;
=== [[Network_Attacks#Wiretapping|Wiretapping]] (Passive Attack) ===&lt;br /&gt;
In this system, the username is sent to the server, which replies with the password for that username. A malicious user can intercept the username as it is being sent to the server, and intercept the password as it is being sent back to the client. The malicious user will be able to clearly read the username and password since no form of encryption is being used. More details can be found on the [[Rednet_(API)|Rednet API]] page.&lt;br /&gt;
=== [[Network_Attacks#Forgery|Password Forgery]] (Active Attack) ===&lt;br /&gt;
A malicious user can enter a random username and password on the target computer. He can then make another computer send the password he typed in to the target computer immediately after it sends the username. The target computer will recieve the forged password and compare it with the malicious user's password, and finding them to be equal, will grant the malicious user access to the computer.&lt;br /&gt;
=== [[Network_Attacks#Forgery|Error code forgery]] (Active Attack) ===&lt;br /&gt;
A malicious user can simply send the not whitelisted or invalid credentials error codes to the target computer before a legitamate error code appears, causing it to assume that the user is not whitelisted or has an invalid username every time the user tries to log in. This works because the target computer has no way of detecting whether the error code messages are forged or authentic.&lt;br /&gt;
=== Program Terminate (Passive Attack) ===&lt;br /&gt;
A malicious user can press and hold Ctrl+T on the computer to terminate the startup program and use the computer.&lt;br /&gt;
=== Bypass username (Passive Attack) ===&lt;br /&gt;
A malicious user can create a malicious floppy disk with a startup program that copies the computer's files to itself. A transfer the floppy disk to another computer and view the bypass credentials.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Server ==&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;This is a password server. There is no user interaction here.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please find a computer and login there.&amp;quot;) &lt;br /&gt;
 local firstCycle = true&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 local modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 local valid = false&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } --make sure users and passwords line up&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; }&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- computer ID's of the computers you want to accept requests from&lt;br /&gt;
 function bootUp()&lt;br /&gt;
  rednet.open(modemSide)&lt;br /&gt;
 end&lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  if firstCycle then&lt;br /&gt;
   bootUp()&lt;br /&gt;
   firstCycle = false&lt;br /&gt;
  end&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
     valid = true&lt;br /&gt;
     password = passwords[i]&lt;br /&gt;
     break&lt;br /&gt;
    else&lt;br /&gt;
     valid = false&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   if valid then&lt;br /&gt;
    rednet.send(senderId, password, true)&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;Not Valid&amp;quot;, true)&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Alternative Client ==&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local locker = true&lt;br /&gt;
 local failed = true&lt;br /&gt;
 local attempted_login = true&lt;br /&gt;
 local password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while locker do&lt;br /&gt;
  attempted_login = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome to a USERS PC : Roaming Profile Enabled&amp;quot;)&lt;br /&gt;
  print(&amp;quot;What would you like to do?&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[1] Login (*)&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
  write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
  local input = read()&lt;br /&gt;
  if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
   os.shutdown()&lt;br /&gt;
  elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
   attempted_login = true&lt;br /&gt;
   print(&amp;quot;Please login...&amp;quot;)&lt;br /&gt;
   write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
   local username = read()&lt;br /&gt;
   write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
   local password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
   rednet.send(password_server, username, true)&lt;br /&gt;
   senderId, message, distance = rednet.receive(5)&lt;br /&gt;
   if password == message then&lt;br /&gt;
    failed = false&lt;br /&gt;
    locker = false&lt;br /&gt;
    term.clear()&lt;br /&gt;
    term.setCursorPos(1,1)&lt;br /&gt;
    print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
   else&lt;br /&gt;
    print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
    sleep(3)&lt;br /&gt;
   end&lt;br /&gt;
  else&lt;br /&gt;
   print(&amp;quot;Command not recognised...&amp;quot;)&lt;br /&gt;
   sleep(2)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Thoughts and Notes ==&lt;br /&gt;
&lt;br /&gt;
Although this may work very well as a login system, it is insecure by the flaw that a malicious sniffer can unnoticeably obtain a copy of the password while it is being sent as described on the [[Rednet_(API)|Rednet API]] page, and use the password to login.&lt;br /&gt;
&lt;br /&gt;
If you change the client code, to &amp;quot;startup&amp;quot; and put it in the root directory, it works very well as a login system.&lt;br /&gt;
You may also want to put in the line &lt;br /&gt;
 os.pullEvent = os.pullEventRaw -- disables Ctrl+T&lt;br /&gt;
as if it doesn't work first time it can be difficult to get out of the program.&lt;br /&gt;
&lt;br /&gt;
If you have either Railcraft or Additional Pipes, find the 'World Anchor' or 'Teleport Tether' block. If your server can afford the resources, place the block within a 3x3 grid of your password server. It will ensure that even if you leave the chunk, the password server still is operational. Otherwise you may find that you cannot login because you've left the chunk and the password server is no longer dealing with requests.&lt;br /&gt;
&lt;br /&gt;
''Alternative version only:''&lt;br /&gt;
This is a minor security flaw but it is only if someone has access to a computer that is 'whitelisted' to access the password server. The security flaw is that if they use the password Not Valid on that computer they are allowed access;&lt;br /&gt;
&lt;br /&gt;
 if valid then&lt;br /&gt;
  --send client password&lt;br /&gt;
 else&lt;br /&gt;
  --send client Not Valid&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To fix this, remove the else statement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Programs]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Network_Attacks&amp;diff=5991</id>
		<title>Network Attacks</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Network_Attacks&amp;diff=5991"/>
				<updated>2013-09-07T18:32:36Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: Created page with &amp;quot;Wireless networking has loads of security flaws. Here are several possible attacks that hackers can do to exploit your system.  __TOC__  == Passive Attacks == Passive attacks ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wireless networking has loads of security flaws. Here are several possible attacks that hackers can do to exploit your system.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Passive Attacks ==&lt;br /&gt;
Passive attacks aim to obtain or view information or data in computer networks without modifying or interfering with anything occuring.&lt;br /&gt;
=== Wiretapping ===&lt;br /&gt;
An attacker can eavesdrop on rednet/modem communications an obtain sensitive information. Unless this information is encrypted, it can easily be read by the attacker, possibly compromising passwords, control signals, or other sensitive info&lt;br /&gt;
=== Mimicry ===&lt;br /&gt;
An attacker can run a server that listens on the same channel or spoofs the ID of a legitamate server, causing users with the client program to send their data to both the legitamate server and the attacker, who now knows the information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Active Attacks ==&lt;br /&gt;
Active attacks are designed to modify or interupt normal system usage.&lt;br /&gt;
=== Backdoor ===&lt;br /&gt;
Backdoors are essentially tunnels that lead into a computer which must be manually opened by an attacker.&lt;br /&gt;
A backdoor generally works like this:&lt;br /&gt;
# The attacker sends a program on a channel that the backdoor is listening on.&lt;br /&gt;
# The backdoor finds the program, downloads it, and executes it.&lt;br /&gt;
The program that the backdoor executes can be any form of malicious thing, such as copying or modifying files or programs, setting of redstone signals, or anything else an attacker would like to do.&lt;br /&gt;
Backdoors are usually difficult to put onto a computer, but they are possible to do.&lt;br /&gt;
=== Identity Spoof ===&lt;br /&gt;
Most web applications use computer ID's to determine if it is authentic or not. An attacker can assume a computer ID to bypass ID-based whitelists easily. &lt;br /&gt;
=== Forgery ===&lt;br /&gt;
An attacker can send his own message to a client incapable of distinguishing the source of a message between the legitamate server or a forger, causing it to think it's a legitamate message. An attacker can also send a forged message to a server, causing it to think it came from the client.&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Receiving_a_rednet_message_through_os.pullEvent()&amp;diff=5990</id>
		<title>Receiving a rednet message through os.pullEvent()</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Receiving_a_rednet_message_through_os.pullEvent()&amp;diff=5990"/>
				<updated>2013-09-06T19:10:18Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following method is a good method of receiving a [[Rednet_(API)|rednet]] message without using rednet.receive().&lt;br /&gt;
It is usually used in IRC, Chat programs e.t.c.&lt;br /&gt;
When a message arrives to a computer, a &amp;quot;rednet_message&amp;quot; event occurs.  &lt;br /&gt;
== The Code ==&lt;br /&gt;
This is a typical Listener which prints the content and the sender id of any incoming message.&lt;br /&gt;
 for n,m in ipairs(rs.getSides()) do rednet.open(m) end -- Opens all rednet sides.&lt;br /&gt;
 while true do&lt;br /&gt;
   event, id, text = os.pullEvent()&lt;br /&gt;
   if event == &amp;quot;rednet_message&amp;quot; then&lt;br /&gt;
     print(id .. &amp;quot;&amp;gt; &amp;quot; .. text)&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Explanation ==&lt;br /&gt;
 for n,m in ipairs(rs.getSides()) do rednet.open(m) end&lt;br /&gt;
Here we just open all sides for rednet processing.&lt;br /&gt;
&lt;br /&gt;
 while true do&lt;br /&gt;
We start a loop because os.pullEvent() terminates itself after 10 seconds.&lt;br /&gt;
&lt;br /&gt;
 event, id, text = os.pullEvent()&lt;br /&gt;
We wait for an event to occur and when this happens, we store the event's info into 3 variables.&lt;br /&gt;
NOTE: You can give your variables whichever name you want.&lt;br /&gt;
&lt;br /&gt;
 if event == &amp;quot;rednet_message&amp;quot; then&lt;br /&gt;
We check if the event was a rednet message.&lt;br /&gt;
&lt;br /&gt;
 print(id .. &amp;quot;&amp;gt; &amp;quot; .. text)&lt;br /&gt;
We print the message and the id of the sender.&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
 end&lt;br /&gt;
We close our previous statements.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
Beware that rednet is not secure on its own, with easily exploitable vulnerabilities that allow hackers to hack your networks into pieces--through attacks like wiretapping, spoofing, forgery, overloading, and many more. Be sure to add your own security when using rednet.&lt;br /&gt;
&lt;br /&gt;
[[Category:Programs]][[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=User:Bwhodle&amp;diff=5989</id>
		<title>User:Bwhodle</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=User:Bwhodle&amp;diff=5989"/>
				<updated>2013-09-06T18:56:33Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: Created page with &amp;quot;I'm bwhodle, with decent expertise in wireless networking and cryptography in real life, and expertise in real life computers. Most of the pages I edit are to inform users abo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I'm bwhodle, with decent expertise in wireless networking and cryptography in real life, and expertise in real life computers. Most of the pages I edit are to inform users about hidden security issues in wireless networking.&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=User_talk:Bwhodle&amp;diff=5988</id>
		<title>User talk:Bwhodle</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=User_talk:Bwhodle&amp;diff=5988"/>
				<updated>2013-09-06T18:56:26Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: Replaced content with &amp;quot;This is my talk page.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is my talk page.&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=User_talk:Bwhodle&amp;diff=5987</id>
		<title>User talk:Bwhodle</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=User_talk:Bwhodle&amp;diff=5987"/>
				<updated>2013-09-06T18:55:20Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: Created page with &amp;quot;I'm bwhodle, with decent expertise in wireless networking and cryptography in real life, and expertise in real life computers. Most of the pages I edit are to inform users abo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I'm bwhodle, with decent expertise in wireless networking and cryptography in real life, and expertise in real life computers. Most of the pages I edit are to inform users about hidden security issues in wireless networking.&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5986</id>
		<title>Login with Roaming Profiles</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5986"/>
				<updated>2013-09-06T18:49:08Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: Attempted to remove most of Latias's tutorial branding and fixed some grammar stuff.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This tutorial covers how to make a password server and a password client. The server will host a Lua table of usernames and passwords and the client will remotely connect each start up, ask the user for their username and password and compare it to that on the password server.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Setting Up ==&lt;br /&gt;
First of all, you must know how to craft a [[Wireless_Modem|wireless modem]] and a [[Computer|computer]]. You need to craft at least 2 wireless modems and 2 computers if you want to have a practical use for this system. Then, attach 1 modem to each computer you want to add to the system.&lt;br /&gt;
&lt;br /&gt;
Second, since typing on normal computers is relatively slow and annoying, I recommend to write the programs in [[Advanced_Computers|advanced computers]](because in advanced computers you can click to move the cursor around, and there are colors to distinguis between different statements), copying them into a [[Floppy|disk]] and moving them into each computer you want to include(with their respective programs of course). Alternatively, if you are the server owner(this tutorial assumes you are in Multiplayer because this system does not have any practical use in Singleplayer), you can go into the world folder and write copy/paste the source code into the folders of each computer you want to use. The folders you should use are the named the IDs of the computers(so if you have 3 computers, with the IDs 5, 7 and 9, you should copy them into the folders 5, 7 and 9). &lt;br /&gt;
&lt;br /&gt;
It does not matter wether you are using Normal or Advanced computers for this tutorial. I recommend to use Normal ones for the server.&lt;br /&gt;
&lt;br /&gt;
When writing the programs, I HIGHLY recommend using a [[Disk_Drive|disk drive]] like stated above, so you dont have to write in prograns for every computer you add.&lt;br /&gt;
Remember to read the text behind the --. These are comments, and you can safely leave them in the code.&lt;br /&gt;
&lt;br /&gt;
== Server ==&lt;br /&gt;
 print(&amp;quot;Initializing...&amp;quot;)&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 valid = false&lt;br /&gt;
 tserved, vserved, dserved = 0&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading startup settings...&amp;quot;)&lt;br /&gt;
 count = true -- If you dont want the server to count request statics, set the value of this variable to &amp;quot;false&amp;quot; without qoutes.&lt;br /&gt;
 modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 whitelist = true -- If you dont want to use a whitelist, change the value to &amp;quot;false&amp;quot; without quotes. This is not recommended on Multiplayer, but it does not make any difference on a Singleplayer World.&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading user database...&amp;quot;)&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } -- Change this to the names for the users you want to have. Make sure the usernames are in the same order as in the password table. Changing the order is fine, but you must maintain the same order in both the users and passwords tables. Incorrect orders WILL cause 2 or more users not being able to log in!&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; } -- Change this to the passwords for the users defined in the variable above. Again, make sure the passwords for users are in the same order as the usernames.&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- change this to the ID's of the all computers you want to accept requests from if you use a whitelist. If you do not use a whitelist, DO NOT REMOVE THIS LINE! Doing so will cause the program to crash everytime it is run, even though the variable is not used.&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading core functions...&amp;quot;)&lt;br /&gt;
 function clear()&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1, 1)&lt;br /&gt;
 print(&amp;quot;CCLS Server 1.0 for CC 1.53&amp;quot;) &lt;br /&gt;
 print(&amp;quot;There is no user interaction here. Please contact your system administrator for assistance regarding the system.&amp;quot;)&lt;br /&gt;
 if count == true then&lt;br /&gt;
  print(tserved..&amp;quot; total requests received this session.&amp;quot;)&lt;br /&gt;
  print(vserved..&amp;quot; requests completed this session.&amp;quot;)&lt;br /&gt;
  print(dserved..&amp;quot; requests denied this session.&amp;quot;)&lt;br /&gt;
 elseif count == false then&lt;br /&gt;
  print(&amp;quot;Request statics have been disabled.&amp;quot;)&lt;br /&gt;
 else&lt;br /&gt;
  rednet.close(modemSide)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1, 1)&lt;br /&gt;
  print(&amp;quot;Error: Counter setting is not boolean and the server can not continue.&amp;quot;)&lt;br /&gt;
  print(&amp;quot;The server program will exit automatically in 10 minutes. Or you can hold down Ctrl+T for 1 second.&amp;quot;)&lt;br /&gt;
  print(&amp;quot;After that, please set the variable \&amp;quot;count\&amp;quot; in the source code to either \&amp;quot;true\&amp;quot; or \&amp;quot;false\&amp;quot; WITHOUT QUOTATION MARKS. Doing this with quotation marks will cause the same error.&amp;quot;)&lt;br /&gt;
  sleep(600)&lt;br /&gt;
  shell.exit()&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Starting up...&amp;quot;)&lt;br /&gt;
 rednet.open(modemSide) -- Opens the modem to wait for incoming login requests&lt;br /&gt;
 &lt;br /&gt;
 clear()&lt;br /&gt;
 &lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   tserved = tserved + 1&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;301&amp;quot;, true) -- Send response code 301 - which means Not Whitelisted.&lt;br /&gt;
    dserved = dserved + 1&lt;br /&gt;
    clear()&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
  password = passwords[i]&lt;br /&gt;
  rednet.send(senderId, password, true)&lt;br /&gt;
  vserved = vserved + 1&lt;br /&gt;
  clear()&lt;br /&gt;
  break&lt;br /&gt;
    else&lt;br /&gt;
  rednet.send(senderId, &amp;quot;300&amp;quot;, true) -- Send response code 300 - which means Bad Auth.&lt;br /&gt;
  dserved = dserved + 1&lt;br /&gt;
  clear()&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&amp;lt;!-- Latias1290, you should remove the branding part, it's a tutorial, not a publish program place. You should also explain everything --&amp;gt;&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local failed = true&lt;br /&gt;
 busr = &amp;quot;nsliq&amp;quot; -- If you ever happen to be unable to log in for some reason, you can use this username as a backup.&lt;br /&gt;
 bpass = &amp;quot;zuFUkVEjQKjkLQhTdpFMheNF&amp;quot; -- If you ever happen to be unable to log in for some reason, you can use this password as a backup.&lt;br /&gt;
 &lt;br /&gt;
 password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while true do&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;Welcome to CCLS 1.0 by Latias1290.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please select an option.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;[1] Login&amp;quot;)&lt;br /&gt;
 print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
 write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
 input = read()&lt;br /&gt;
 if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
  os.shutdown()&lt;br /&gt;
 elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
  print(&amp;quot;Please login.&amp;quot;)&lt;br /&gt;
  write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
  username = read()&lt;br /&gt;
  write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
  password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
  if username == busr then&lt;br /&gt;
  if password == bpass then&lt;br /&gt;
 print(&amp;quot;Access granted&amp;quot;)&lt;br /&gt;
 break&lt;br /&gt;
  end&lt;br /&gt;
  end&lt;br /&gt;
  rednet.send(password_server, username, true)&lt;br /&gt;
  senderId, message, distance = rednet.receive(5)&lt;br /&gt;
  if message == &amp;quot;300&amp;quot; then&lt;br /&gt;
  print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
  sleep(3)&lt;br /&gt;
  elseif password == message then&lt;br /&gt;
  failed = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
  break;&lt;br /&gt;
  else&lt;br /&gt;
  print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
  sleep(3)&lt;br /&gt;
  end&lt;br /&gt;
 else&lt;br /&gt;
  print(&amp;quot;Invalid Command.&amp;quot;)&lt;br /&gt;
  sleep(2)&lt;br /&gt;
 end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Flaws ==&lt;br /&gt;
The above login system has several flaws and vulnerabilities. &lt;br /&gt;
=== Credentials stored on volatile memory (Storage flaw) ===&lt;br /&gt;
The login credentials are stored in a table. Since tables are stored on volatile memory, the computer requires to be on at all times in order for the server to retain login credentials. Computers are automatically restarted on server reload or world reload, rendering this login system inefficient for long-term usage.&lt;br /&gt;
=== Spoof Attack (Active Attack) ===&lt;br /&gt;
Although this system is designed to protect a computer rather than a system, the login server is undeniably vulnerable to ID spoof, where a malicious user assumes the ID of a whitelisted computer, and defeats the purpose of an ID whitelist entirely. More details can be found on the [[Rednet_(API)|Rednet API]] page.&lt;br /&gt;
=== Wiretapping (Passive Attack) ===&lt;br /&gt;
In this system, the username is sent to the server, which replies with the password for that username. A malicious user can intercept the username as it is being sent to the server, and intercept the password as it is being sent back to the client. The malicious user will be able to clearly read the username and password since no form of encryption is being used. More details can be found on the [[Rednet_(API)|Rednet API]] page.&lt;br /&gt;
=== Password Forgery (Active Attack) ===&lt;br /&gt;
A malicious user can enter a random username and password on the target computer. He can then make another computer send the password he typed in to the target computer immediately after it sends the username. The target computer will recieve the forged password and compare it with the malicious user's password, and finding them to be equal, will grant the malicious user access to the computer.&lt;br /&gt;
=== Error code spoof (Active Attack) ===&lt;br /&gt;
A malicious user can simply send the not whitelisted or invalid credentials error codes to the target computer before a legitamate error code appears, causing it to assume that the user is not whitelisted or has an invalid username every time the user tries to log in. This works because the target computer has no way of detecting whether the error code messages are forged or authentic.&lt;br /&gt;
=== Program Terminate (Passive Attack) ===&lt;br /&gt;
A malicious user can press and hold Ctrl+T on the computer to terminate the startup program and use the computer.&lt;br /&gt;
=== Bypass username (Passive Attack) ===&lt;br /&gt;
A malicious user can create a malicious floppy disk with a startup program that copies the computer's files to itself. A transfer the floppy disk to another computer and view the bypass credentials.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Alternative Server ==&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;This is a password server. There is no user interaction here.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please find a computer and login there.&amp;quot;) &lt;br /&gt;
 local firstCycle = true&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 local modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 local valid = false&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } --make sure users and passwords line up&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; }&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- computer ID's of the computers you want to accept requests from&lt;br /&gt;
 function bootUp()&lt;br /&gt;
  rednet.open(modemSide)&lt;br /&gt;
 end&lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  if firstCycle then&lt;br /&gt;
   bootUp()&lt;br /&gt;
   firstCycle = false&lt;br /&gt;
  end&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
     valid = true&lt;br /&gt;
     password = passwords[i]&lt;br /&gt;
     break&lt;br /&gt;
    else&lt;br /&gt;
     valid = false&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   if valid then&lt;br /&gt;
    rednet.send(senderId, password, true)&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;Not Valid&amp;quot;, true)&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Alternative Client ==&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local locker = true&lt;br /&gt;
 local failed = true&lt;br /&gt;
 local attempted_login = true&lt;br /&gt;
 local password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while locker do&lt;br /&gt;
  attempted_login = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome to a USERS PC : Roaming Profile Enabled&amp;quot;)&lt;br /&gt;
  print(&amp;quot;What would you like to do?&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[1] Login (*)&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
  write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
  local input = read()&lt;br /&gt;
  if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
   os.shutdown()&lt;br /&gt;
  elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
   attempted_login = true&lt;br /&gt;
   print(&amp;quot;Please login...&amp;quot;)&lt;br /&gt;
   write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
   local username = read()&lt;br /&gt;
   write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
   local password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
   rednet.send(password_server, username, true)&lt;br /&gt;
   senderId, message, distance = rednet.receive(5)&lt;br /&gt;
   if password == message then&lt;br /&gt;
    failed = false&lt;br /&gt;
    locker = false&lt;br /&gt;
    term.clear()&lt;br /&gt;
    term.setCursorPos(1,1)&lt;br /&gt;
    print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
   else&lt;br /&gt;
    print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
    sleep(3)&lt;br /&gt;
   end&lt;br /&gt;
  else&lt;br /&gt;
   print(&amp;quot;Command not recognised...&amp;quot;)&lt;br /&gt;
   sleep(2)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Thoughts and Notes ==&lt;br /&gt;
&lt;br /&gt;
Although this may work very well as a login system, it is insecure by the flaw that a malicious sniffer can unnoticeably obtain a copy of the password while it is being sent as described on the [[Rednet_(API)|Rednet API]] page, and use the password to login.&lt;br /&gt;
&lt;br /&gt;
If you change the client code, to &amp;quot;startup&amp;quot; and put it in the root directory, it works very well as a login system.&lt;br /&gt;
You may also want to put in the line &lt;br /&gt;
 os.pullEvent = os.pullEventRaw -- disables Ctrl+T&lt;br /&gt;
as if it doesn't work first time it can be difficult to get out of the program.&lt;br /&gt;
&lt;br /&gt;
If you have either Railcraft or Additional Pipes, find the 'World Anchor' or 'Teleport Tether' block. If your server can afford the resources, place the block within a 3x3 grid of your password server. It will ensure that even if you leave the chunk, the password server still is operational. Otherwise you may find that you cannot login because you've left the chunk and the password server is no longer dealing with requests.&lt;br /&gt;
&lt;br /&gt;
''Alternative version only:''&lt;br /&gt;
This is a minor security flaw but it is only if someone has access to a computer that is 'whitelisted' to access the password server. The security flaw is that if they use the password Not Valid on that computer they are allowed access;&lt;br /&gt;
&lt;br /&gt;
 if valid then&lt;br /&gt;
  --send client password&lt;br /&gt;
 else&lt;br /&gt;
  --send client Not Valid&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
To fix this, remove the else statement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Programs]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=User_talk:Latias1290&amp;diff=5985</id>
		<title>User talk:Latias1290</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=User_talk:Latias1290&amp;diff=5985"/>
				<updated>2013-09-06T18:43:55Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: /* Login with Roaming Profiles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Do you mind fixing the shading on [[File:Grid_Advanced_Turtle.png]]? I'm not really a graphics person and all I did was copy the colors from models\turtle2.png onto [[File:Grid_turtle.png]].&lt;br /&gt;
--[[User:Bunny365|Bunny365]] 15:39, 1 September 2013 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Login with Roaming Profiles ==&lt;br /&gt;
&lt;br /&gt;
You have edited the login with roaming profiles pages considerably and redone it even after AfterLifeLochie reverted the changes. Remember that the wiki is a place to put tutorials to help people out, not publish your programs and self-recommend them -- that goes on the forums. &lt;br /&gt;
I love how you added a new login with roaming profiles page, but it seriously looks more like a forum post than a tutorial. You buried the previous program and claimed it as not recommended. Instead you pretty much put your version of the program and essentially copyrighted it, and then recommended it yourself. On top of that, you marked the security issues that DID APPLY to your program as inapplicable to your version. This is for tutorials, not publishing programs to compete with previous ones.&lt;br /&gt;
&lt;br /&gt;
I didn't revert the edition because I think your version is a good improvement, but I added a list of it's flaws (from a wireless networking analyst point of view) to keep users aware and removed the bragging parts (&amp;quot;I recommend the new one, this is just for reference...&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
I can't remove the &amp;quot;by Latias1290&amp;quot; part in the client because it's your intellectual property, but I suggest that you don't brand your tutorial. I mean, it's a tutorial. Also, you should add comments and explain your program rather than just putting the program -- as that doesn't really explain much to people who read the tutorial, instead they have to figure it out themselves.&lt;br /&gt;
&lt;br /&gt;
[[User:Bwhodle|Bwhodle]] 18:43, 6 September 2013 (GMT)&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=User_talk:Latias1290&amp;diff=5984</id>
		<title>User talk:Latias1290</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=User_talk:Latias1290&amp;diff=5984"/>
				<updated>2013-09-06T18:43:41Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: /* Login with Roaming Profiles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Do you mind fixing the shading on [[File:Grid_Advanced_Turtle.png]]? I'm not really a graphics person and all I did was copy the colors from models\turtle2.png onto [[File:Grid_turtle.png]].&lt;br /&gt;
--[[User:Bunny365|Bunny365]] 15:39, 1 September 2013 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Login with Roaming Profiles ==&lt;br /&gt;
&lt;br /&gt;
You have edited the login with roaming profiles pages considerably and redone it even after AfterLifeLochie reverted the changes. Remember that the wiki is a place to put tutorials to help people out, not publish your programs and self-recommend them -- that goes on the forums. &lt;br /&gt;
I love how you added a new login with roaming profiles page, but it seriously looks more like a forum post than a tutorial. You buried the previous program and claimed it as not recommended. Instead you pretty much put your version of the program and essentially copyrighted it, and then recommended it yourself. On top of that, you marked the security issues that DID APPLY to your program as inapplicable to your version. This is for tutorials, not publishing programs to compete with previous ones.&lt;br /&gt;
&lt;br /&gt;
I didn't revert the edition because I think your version is a good improvement, but I added a list of it's flaws (from a wireless networking analyst point of view) to keep users aware and removed the bragging parts (&amp;quot;I recommend the new one, this is just for reference...&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
I can't remove the &amp;quot;by Latias1290&amp;quot; part in the client because it's your intellectual property, but I suggest that you don't brand your tutorial. I mean, it's a tutorial. Also, you should add comments and explain your program rather than just putting the program -- as that doesn't really explain much to people who read the tutorial, instead they have to figure it out themselves.&lt;br /&gt;
[[User:Bwhodle|Bwhodle]] 18:43, 6 September 2013 (GMT)&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=User_talk:Latias1290&amp;diff=5983</id>
		<title>User talk:Latias1290</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=User_talk:Latias1290&amp;diff=5983"/>
				<updated>2013-09-06T18:43:28Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: /* Login with Roaming Profiles */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Do you mind fixing the shading on [[File:Grid_Advanced_Turtle.png]]? I'm not really a graphics person and all I did was copy the colors from models\turtle2.png onto [[File:Grid_turtle.png]].&lt;br /&gt;
--[[User:Bunny365|Bunny365]] 15:39, 1 September 2013 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Login with Roaming Profiles ==&lt;br /&gt;
&lt;br /&gt;
You have edited the login with roaming profiles pages considerably and redone it even after AfterLifeLochie reverted the changes. Remember that the wiki is a place to put tutorials to help people out, not publish your programs and self-recommend them -- that goes on the forums. &lt;br /&gt;
I love how you added a new login with roaming profiles page, but it seriously looks more like a forum post than a tutorial. You buried the previous program and claimed it as not recommended. Instead you pretty much put your version of the program and essentially copyrighted it, and then recommended it yourself. On top of that, you marked the security issues that DID APPLY to your program as inapplicable to your version. This is for tutorials, not publishing programs to compete with previous ones.&lt;br /&gt;
&lt;br /&gt;
I didn't revert the edition because I think your version is a good improvement, but I added a list of it's flaws (from a wireless networking analyst point of view) to keep users aware and removed the bragging parts (&amp;quot;I recommend the new one, this is just for reference...&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
I can't remove the &amp;quot;by Latias1290&amp;quot; part in the client because it's your intellectual property, but I suggest that you don't brand your tutorial. I mean, it's a tutorial. Also, you should add comments and explain your program rather than just putting the program -- as that doesn't really explain much to people who read the tutorial, instead they have to figure it out themselves.&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5982</id>
		<title>Login with Roaming Profiles</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5982"/>
				<updated>2013-09-06T18:32:26Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This tutorial covers how to make a password server and a password client. The server will host a Lua table of usernames and passwords and the client will remotely connect each start up, ask the user for their username and password and compare it to that on the password server.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Setting Up ==&lt;br /&gt;
First of all, you must know how to craft a [[Wireless_Modem|wireless modem]] and a [[Computer|computer]]. You need to craft at least 2 wireless modems and 2 computers if you want to have a practical use for this system. Then, attach 1 modem to each computer you want to add to the system.&lt;br /&gt;
&lt;br /&gt;
Second, since typing on normal computers is relatively slow and annoying, I recommend to write the programs in [[Advanced_Computers|advanced computers]](because in advanced computers you can click to move the cursor around, and there are colors to distinguis between different statements), copying them into a [[Floppy|disk]] and moving them into each computer you want to include(with their respective programs of course). Alternatively, if you are the server owner(this tutorial assumes you are in Multiplayer because this system does not have any practical use in Singleplayer), you can go into the world folder and write copy/paste the source code into the folders of each computer you want to use. The folders you should use are the named the IDs of the computers(so if you have 3 computers, with the IDs 5, 7 and 9, you should copy them into the folders 5, 7 and 9). &lt;br /&gt;
&lt;br /&gt;
It does not matter wether you are using Normal or Advanced computers for this tutorial. I recommend to use Normal ones for the server.&lt;br /&gt;
&lt;br /&gt;
When writing the programs, I HIGHLY recommend using a [[Disk_Drive|disk drive]] like stated above, so you dont have to write in prograns for every computer you add.&lt;br /&gt;
Remember to read the text behind the --. These are comments, and you can safely leave them in the code.&lt;br /&gt;
&lt;br /&gt;
== Server ==&lt;br /&gt;
 print(&amp;quot;Initializing...&amp;quot;)&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 valid = false&lt;br /&gt;
 tserved, vserved, dserved = 0&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading startup settings...&amp;quot;)&lt;br /&gt;
 count = true -- If you dont want the server to count request statics, set the value of this variable to &amp;quot;false&amp;quot; without qoutes.&lt;br /&gt;
 modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 whitelist = true -- If you dont want to use a whitelist, change the value to &amp;quot;false&amp;quot; without quotes. This is not recommended on Multiplayer, but it does not make any difference on a Singleplayer World.&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading user database...&amp;quot;)&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } -- Change this to the names for the users you want to have. Make sure the usernames are in the same order as in the password table. Changing the order is fine, but you must maintain the same order in both the users and passwords tables. Incorrect orders WILL cause 2 or more users not being able to log in!&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; } -- Change this to the passwords for the users defined in the variable above. Again, make sure the passwords for users are in the same order as the usernames.&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- change this to the ID's of the all computers you want to accept requests from if you use a whitelist. If you do not use a whitelist, DO NOT REMOVE THIS LINE! Doing so will cause the program to crash everytime it is run, even though the variable is not used.&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading core functions...&amp;quot;)&lt;br /&gt;
 function clear()&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1, 1)&lt;br /&gt;
 print(&amp;quot;CCLS Server 1.0 for CC 1.53&amp;quot;) &lt;br /&gt;
 print(&amp;quot;There is no user interaction here. Please contact your system administrator for assistance regarding the system.&amp;quot;)&lt;br /&gt;
 if count == true then&lt;br /&gt;
  print(tserved..&amp;quot; total requests received this session.&amp;quot;)&lt;br /&gt;
  print(vserved..&amp;quot; requests completed this session.&amp;quot;)&lt;br /&gt;
  print(dserved..&amp;quot; requests denied this session.&amp;quot;)&lt;br /&gt;
 elseif count == false then&lt;br /&gt;
  print(&amp;quot;Request statics have been disabled.&amp;quot;)&lt;br /&gt;
 else&lt;br /&gt;
  rednet.close(modemSide)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1, 1)&lt;br /&gt;
  print(&amp;quot;Error: Counter setting is not boolean and the server can not continue.&amp;quot;)&lt;br /&gt;
  print(&amp;quot;The server program will exit automatically in 10 minutes. Or you can hold down Ctrl+T for 1 second.&amp;quot;)&lt;br /&gt;
  print(&amp;quot;After that, please set the variable \&amp;quot;count\&amp;quot; in the source code to either \&amp;quot;true\&amp;quot; or \&amp;quot;false\&amp;quot; WITHOUT QUOTATION MARKS. Doing this with quotation marks will cause the same error.&amp;quot;)&lt;br /&gt;
  sleep(600)&lt;br /&gt;
  shell.exit()&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Starting up...&amp;quot;)&lt;br /&gt;
 rednet.open(modemSide) -- Opens the modem to wait for incoming login requests&lt;br /&gt;
 &lt;br /&gt;
 clear()&lt;br /&gt;
 &lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   tserved = tserved + 1&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;301&amp;quot;, true) -- Send response code 301 - which means Not Whitelisted.&lt;br /&gt;
    dserved = dserved + 1&lt;br /&gt;
    clear()&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
  password = passwords[i]&lt;br /&gt;
  rednet.send(senderId, password, true)&lt;br /&gt;
  vserved = vserved + 1&lt;br /&gt;
  clear()&lt;br /&gt;
  break&lt;br /&gt;
    else&lt;br /&gt;
  rednet.send(senderId, &amp;quot;300&amp;quot;, true) -- Send response code 300 - which means Bad Auth.&lt;br /&gt;
  dserved = dserved + 1&lt;br /&gt;
  clear()&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local failed = true&lt;br /&gt;
 busr = &amp;quot;nsliq&amp;quot; -- If you ever happen to be unable to log in for some reason, you can use this username as a backup.&lt;br /&gt;
 bpass = &amp;quot;zuFUkVEjQKjkLQhTdpFMheNF&amp;quot; -- If you ever happen to be unable to log in for some reason, you can use this password as a backup.&lt;br /&gt;
 &lt;br /&gt;
 password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while true do&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;Welcome to CCLS 1.0 by Latias1290.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please select an option.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;[1] Login&amp;quot;)&lt;br /&gt;
 print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
 write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
 input = read()&lt;br /&gt;
 if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
  os.shutdown()&lt;br /&gt;
 elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
  print(&amp;quot;Please login.&amp;quot;)&lt;br /&gt;
  write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
  username = read()&lt;br /&gt;
  write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
  password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
  if username == busr then&lt;br /&gt;
  if password == bpass then&lt;br /&gt;
 print(&amp;quot;Access granted&amp;quot;)&lt;br /&gt;
 break&lt;br /&gt;
  end&lt;br /&gt;
  end&lt;br /&gt;
  rednet.send(password_server, username, true)&lt;br /&gt;
  senderId, message, distance = rednet.receive(5)&lt;br /&gt;
  if message == &amp;quot;300&amp;quot; then&lt;br /&gt;
  print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
  sleep(3)&lt;br /&gt;
  elseif password == message then&lt;br /&gt;
  failed = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
  break;&lt;br /&gt;
  else&lt;br /&gt;
  print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
  sleep(3)&lt;br /&gt;
  end&lt;br /&gt;
 else&lt;br /&gt;
  print(&amp;quot;Invalid Command.&amp;quot;)&lt;br /&gt;
  sleep(2)&lt;br /&gt;
 end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Flaws ==&lt;br /&gt;
The above login system has several flaws and vulnerabilities. &lt;br /&gt;
=== Credentials stored on volatile memory (Storage flaw) ===&lt;br /&gt;
The login credentials are stored in a table. Since tables are stored on volatile memory, the computer requires to be on at all times in order for the server to retain login credentials. Computers are automatically restarted on server reload or world reload, rendering this login system inefficient for long-term usage.&lt;br /&gt;
=== Spoof Attack (Active Attack) ===&lt;br /&gt;
Although this system is designed to protect a computer rather than a system, the login server is undeniably vulnerable to ID spoof, where a malicious user assumes the ID of a whitelisted computer, and defeats the purpose of an ID whitelist entirely. More details can be found on the [[Rednet_(API)|Rednet API]] page.&lt;br /&gt;
=== Wiretapping (Passive Attack) ===&lt;br /&gt;
In this system, the username is sent to the server, which replies with the password for that username. A malicious user can intercept the username as it is being sent to the server, and intercept the password as it is being sent back to the client. The malicious user will be able to clearly read the username and password since no form of encryption is being used. More details can be found on the [[Rednet_(API)|Rednet API]] page.&lt;br /&gt;
=== Password Forgery (Active Attack) ===&lt;br /&gt;
A malicious user can enter a random username and password on the target computer. He can then make another computer send the password he typed in to the target computer immediately after it sends the username. The target computer will recieve the forged password and compare it with the malicious user's password, and finding them to be equal, will grant the malicious user access to the computer.&lt;br /&gt;
=== Error code spoof (Active Attack) ===&lt;br /&gt;
A malicious user can simply send the not whitelisted or invalid credentials error codes to the target computer before a legitamate error code appears, causing it to assume that the user is not whitelisted or has an invalid username every time the user tries to log in. This works because the target computer has no way of detecting whether the error code messages are forged or authentic.&lt;br /&gt;
=== Program Terminate (Passive Attack) ===&lt;br /&gt;
A malicious user can press and hold Ctrl+T on the computer to terminate the startup program and use the computer.&lt;br /&gt;
=== Bypass username (Passive Attack) ===&lt;br /&gt;
A malicious user can create a malicious floppy disk with a startup program that copies the computer's files to itself. A transfer the floppy disk to another computer and view the bypass credentials.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Old Server ==&lt;br /&gt;
''Note: This is here for reference for people who need the older version. I recommend using the programs above.''&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;This is a password server. There is no user interaction here.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please find a computer and login there.&amp;quot;) &lt;br /&gt;
 local firstCycle = true&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 local modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 local valid = false&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } --make sure users and passwords line up&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; }&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- computer ID's of the computers you want to accept requests from&lt;br /&gt;
 function bootUp()&lt;br /&gt;
  rednet.open(modemSide)&lt;br /&gt;
 end&lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  if firstCycle then&lt;br /&gt;
   bootUp()&lt;br /&gt;
   firstCycle = false&lt;br /&gt;
  end&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
     valid = true&lt;br /&gt;
     password = passwords[i]&lt;br /&gt;
     break&lt;br /&gt;
    else&lt;br /&gt;
     valid = false&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   if valid then&lt;br /&gt;
    rednet.send(senderId, password, true)&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;Not Valid&amp;quot;, true)&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Old Client ==&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local locker = true&lt;br /&gt;
 local failed = true&lt;br /&gt;
 local attempted_login = true&lt;br /&gt;
 local password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while locker do&lt;br /&gt;
  attempted_login = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome to a USERS PC : Roaming Profile Enabled&amp;quot;)&lt;br /&gt;
  print(&amp;quot;What would you like to do?&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[1] Login (*)&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
  write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
  local input = read()&lt;br /&gt;
  if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
   os.shutdown()&lt;br /&gt;
  elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
   attempted_login = true&lt;br /&gt;
   print(&amp;quot;Please login...&amp;quot;)&lt;br /&gt;
   write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
   local username = read()&lt;br /&gt;
   write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
   local password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
   rednet.send(password_server, username, true)&lt;br /&gt;
   senderId, message, distance = rednet.receive(5)&lt;br /&gt;
   if password == message then&lt;br /&gt;
    failed = false&lt;br /&gt;
    locker = false&lt;br /&gt;
    term.clear()&lt;br /&gt;
    term.setCursorPos(1,1)&lt;br /&gt;
    print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
   else&lt;br /&gt;
    print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
    sleep(3)&lt;br /&gt;
   end&lt;br /&gt;
  else&lt;br /&gt;
   print(&amp;quot;Command not recognised...&amp;quot;)&lt;br /&gt;
   sleep(2)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Thoughts and Notes ==&lt;br /&gt;
''Note: You do not have to read these if you use the new system.''&amp;lt;br /&amp;gt;&lt;br /&gt;
Although this may work very well as a login system, it is insecure by the flaw that a malicious sniffer can unnoticeably obtain a copy of the password while it is being sent as described on the [[Rednet_(API)|Rednet API]] page, and use the password to login.&lt;br /&gt;
&lt;br /&gt;
If you change the client code, to &amp;quot;startup&amp;quot; and put it in the root directory, it works very well as a login system.&lt;br /&gt;
You may also want to put in the line &lt;br /&gt;
 os.pullEvent = os.pullEventRaw -- disables Ctrl+T&lt;br /&gt;
as if it doesn't work first time it can be difficult to get out of the program.&lt;br /&gt;
&lt;br /&gt;
If you have either Railcraft or Additional Pipes, find the 'World Anchor' or 'Teleport Tether' block. If your server can afford the resources, place the block within a 3x3 grid of your password server. It will ensure that even if you leave the chunk, the password server still is operational. Otherwise you may find that you cannot login because you've left the chunk and the password server is no longer dealing with requests.&lt;br /&gt;
&lt;br /&gt;
This is a minor security flaw but it is only if someone has access to a computer that is 'whitelisted' to access the password server. The security flaw is that if they use the password Not Valid on that computer they are allowed access;&lt;br /&gt;
&lt;br /&gt;
 if valid then&lt;br /&gt;
  --send client password&lt;br /&gt;
 else&lt;br /&gt;
  --send client Not Valid&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
to fix remove the else statement&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Programs]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5981</id>
		<title>Login with Roaming Profiles</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5981"/>
				<updated>2013-09-06T18:30:54Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: Latias1290 decided to publish his new login system and claim that the security flaws for the old one don't apply to his, although they do. I added a list of issues just to keep users aware...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This tutorial covers how to make a password server and a password client. The server will host a Lua table of usernames and passwords and the client will remotely connect each start up, ask the user for their username and password and compare it to that on the password server.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Setting Up ==&lt;br /&gt;
First of all, you must know how to craft a [[Wireless_Modem|wireless modem]] and a [[Computer|computer]]. You need to craft at least 2 wireless modems and 2 computers if you want to have a practical use for this system. Then, attach 1 modem to each computer you want to add to the system.&lt;br /&gt;
&lt;br /&gt;
Second, since typing on normal computers is relatively slow and annoying, I recommend to write the programs in [[Advanced_Computers|advanced computers]](because in advanced computers you can click to move the cursor around, and there are colors to distinguis between different statements), copying them into a [[Floppy|disk]] and moving them into each computer you want to include(with their respective programs of course). Alternatively, if you are the server owner(this tutorial assumes you are in Multiplayer because this system does not have any practical use in Singleplayer), you can go into the world folder and write copy/paste the source code into the folders of each computer you want to use. The folders you should use are the named the IDs of the computers(so if you have 3 computers, with the IDs 5, 7 and 9, you should copy them into the folders 5, 7 and 9). &lt;br /&gt;
&lt;br /&gt;
It does not matter wether you are using Normal or Advanced computers for this tutorial. I recommend to use Normal ones for the server.&lt;br /&gt;
&lt;br /&gt;
When writing the programs, I HIGHLY recommend using a [[Disk_Drive|disk drive]] like stated above, so you dont have to write in prograns for every computer you add.&lt;br /&gt;
Remember to read the text behind the --. These are comments, and you can safely leave them in the code.&lt;br /&gt;
&lt;br /&gt;
== Server ==&lt;br /&gt;
 print(&amp;quot;Initializing...&amp;quot;)&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 valid = false&lt;br /&gt;
 tserved, vserved, dserved = 0&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading startup settings...&amp;quot;)&lt;br /&gt;
 count = true -- If you dont want the server to count request statics, set the value of this variable to &amp;quot;false&amp;quot; without qoutes.&lt;br /&gt;
 modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 whitelist = true -- If you dont want to use a whitelist, change the value to &amp;quot;false&amp;quot; without quotes. This is not recommended on Multiplayer, but it does not make any difference on a Singleplayer World.&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading user database...&amp;quot;)&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } -- Change this to the names for the users you want to have. Make sure the usernames are in the same order as in the password table. Changing the order is fine, but you must maintain the same order in both the users and passwords tables. Incorrect orders WILL cause 2 or more users not being able to log in!&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; } -- Change this to the passwords for the users defined in the variable above. Again, make sure the passwords for users are in the same order as the usernames.&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- change this to the ID's of the all computers you want to accept requests from if you use a whitelist. If you do not use a whitelist, DO NOT REMOVE THIS LINE! Doing so will cause the program to crash everytime it is run, even though the variable is not used.&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Loading core functions...&amp;quot;)&lt;br /&gt;
 function clear()&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1, 1)&lt;br /&gt;
 print(&amp;quot;CCLS Server 1.0 for CC 1.53&amp;quot;) &lt;br /&gt;
 print(&amp;quot;There is no user interaction here. Please contact your system administrator for assistance regarding the system.&amp;quot;)&lt;br /&gt;
 if count == true then&lt;br /&gt;
  print(tserved..&amp;quot; total requests received this session.&amp;quot;)&lt;br /&gt;
  print(vserved..&amp;quot; requests completed this session.&amp;quot;)&lt;br /&gt;
  print(dserved..&amp;quot; requests denied this session.&amp;quot;)&lt;br /&gt;
 elseif count == false then&lt;br /&gt;
  print(&amp;quot;Request statics have been disabled.&amp;quot;)&lt;br /&gt;
 else&lt;br /&gt;
  rednet.close(modemSide)&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1, 1)&lt;br /&gt;
  print(&amp;quot;Error: Counter setting is not boolean and the server can not continue.&amp;quot;)&lt;br /&gt;
  print(&amp;quot;The server program will exit automatically in 10 minutes. Or you can hold down Ctrl+T for 1 second.&amp;quot;)&lt;br /&gt;
  print(&amp;quot;After that, please set the variable \&amp;quot;count\&amp;quot; in the source code to either \&amp;quot;true\&amp;quot; or \&amp;quot;false\&amp;quot; WITHOUT QUOTATION MARKS. Doing this with quotation marks will cause the same error.&amp;quot;)&lt;br /&gt;
  sleep(600)&lt;br /&gt;
  shell.exit()&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 print(&amp;quot;Starting up...&amp;quot;)&lt;br /&gt;
 rednet.open(modemSide) -- Opens the modem to wait for incoming login requests&lt;br /&gt;
 &lt;br /&gt;
 clear()&lt;br /&gt;
 &lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   tserved = tserved + 1&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;301&amp;quot;, true) -- Send response code 301 - which means Not Whitelisted.&lt;br /&gt;
    dserved = dserved + 1&lt;br /&gt;
    clear()&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
  password = passwords[i]&lt;br /&gt;
  rednet.send(senderId, password, true)&lt;br /&gt;
  vserved = vserved + 1&lt;br /&gt;
  clear()&lt;br /&gt;
  break&lt;br /&gt;
    else&lt;br /&gt;
  rednet.send(senderId, &amp;quot;300&amp;quot;, true) -- Send response code 300 - which means Bad Auth.&lt;br /&gt;
  dserved = dserved + 1&lt;br /&gt;
  clear()&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local failed = true&lt;br /&gt;
 busr = &amp;quot;nsliq&amp;quot; -- If you ever happen to be unable to log in for some reason, you can use this username as a backup.&lt;br /&gt;
 bpass = &amp;quot;zuFUkVEjQKjkLQhTdpFMheNF&amp;quot; -- If you ever happen to be unable to log in for some reason, you can use this password as a backup.&lt;br /&gt;
 &lt;br /&gt;
 password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while true do&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;Welcome to CCLS 1.0 by Latias1290.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please select an option.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;[1] Login&amp;quot;)&lt;br /&gt;
 print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
 write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
 input = read()&lt;br /&gt;
 if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
  os.shutdown()&lt;br /&gt;
 elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
  print(&amp;quot;Please login.&amp;quot;)&lt;br /&gt;
  write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
  username = read()&lt;br /&gt;
  write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
  password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
  if username == busr then&lt;br /&gt;
  if password == bpass then&lt;br /&gt;
 print(&amp;quot;Access granted&amp;quot;)&lt;br /&gt;
 break&lt;br /&gt;
  end&lt;br /&gt;
  end&lt;br /&gt;
  rednet.send(password_server, username, true)&lt;br /&gt;
  senderId, message, distance = rednet.receive(5)&lt;br /&gt;
  if message == &amp;quot;300&amp;quot; then&lt;br /&gt;
  print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
  sleep(3)&lt;br /&gt;
  elseif password == message then&lt;br /&gt;
  failed = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
  break;&lt;br /&gt;
  else&lt;br /&gt;
  print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
  sleep(3)&lt;br /&gt;
  end&lt;br /&gt;
 else&lt;br /&gt;
  print(&amp;quot;Invalid Command.&amp;quot;)&lt;br /&gt;
  sleep(2)&lt;br /&gt;
 end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Flaws ==&lt;br /&gt;
The above login system has several flaws and vulnerabilities. &lt;br /&gt;
=== Credentials stored on volatile memory (Storage flaw) ===&lt;br /&gt;
The login credentials are stored in a table. Since tables are stored on volatile memory, the computer requires to be on at all times in order for the server to retain login credentials. Computers are automatically restarted on server reload or world reload, rendering this login system inefficient for long-term usage.&lt;br /&gt;
=== Spoof Attack (Active Attack) ===&lt;br /&gt;
Although this system is designed to protect a computer rather than a system, the login server is undeniably vulnerable to ID spoof, where a malicious user assumes the ID of a whitelisted computer, and defeats the purpose of an ID whitelist entirely. More details can be found on the [[Rednet_(API)|Rednet API]] page.&lt;br /&gt;
=== Wiretapping (Passive Attack) ===&lt;br /&gt;
In this system, the username is sent to the server, which replies with the password for that username. A malicious user can intercept the username as it is being sent to the server, and intercept the password as it is being sent back to the client. The malicious user will be able to clearly read the username and password since no form of encryption is being used. More details can be found on the [[Rednet_(API)|Rednet API]] page.&lt;br /&gt;
=== Password Forgery (Active Attack) ===&lt;br /&gt;
A malicious user can enter a random username and password on the target computer. He can then make another computer send the password he typed in to the target computer immediately after it sends the username. The target computer will recieve the forged password and compare it with the malicious user's password, and finding them to be equal, will grant the malicious user access to the computer.&lt;br /&gt;
=== Error code spoof ===&lt;br /&gt;
A malicious user can simply send the not whitelisted or invalid credentials error codes to the target computer before a legitamate error code appears, causing it to assume that the user is not whitelisted or has an invalid username every time the user tries to log in. This works because the target computer has no way of detecting whether the error code messages are forged or spoofed&lt;br /&gt;
=== Program Terminate ===&lt;br /&gt;
A malicious user can press and hold Ctrl+T on the computer to terminate the startup program and use the computer.&lt;br /&gt;
=== Bypass username ===&lt;br /&gt;
A malicious user can create a malicious floppy disk with a startup program that copies the computer's files to itself. A transfer the floppy disk to another computer and view the bypass credentials.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Old Server ==&lt;br /&gt;
''Note: This is here for reference for people who need the older version. I recommend using the programs above.''&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;This is a password server. There is no user interaction here.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please find a computer and login there.&amp;quot;) &lt;br /&gt;
 local firstCycle = true&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 local modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 local valid = false&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } --make sure users and passwords line up&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; }&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- computer ID's of the computers you want to accept requests from&lt;br /&gt;
 function bootUp()&lt;br /&gt;
  rednet.open(modemSide)&lt;br /&gt;
 end&lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  if firstCycle then&lt;br /&gt;
   bootUp()&lt;br /&gt;
   firstCycle = false&lt;br /&gt;
  end&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
     valid = true&lt;br /&gt;
     password = passwords[i]&lt;br /&gt;
     break&lt;br /&gt;
    else&lt;br /&gt;
     valid = false&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   if valid then&lt;br /&gt;
    rednet.send(senderId, password, true)&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;Not Valid&amp;quot;, true)&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Old Client ==&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local locker = true&lt;br /&gt;
 local failed = true&lt;br /&gt;
 local attempted_login = true&lt;br /&gt;
 local password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while locker do&lt;br /&gt;
  attempted_login = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome to a USERS PC : Roaming Profile Enabled&amp;quot;)&lt;br /&gt;
  print(&amp;quot;What would you like to do?&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[1] Login (*)&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
  write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
  local input = read()&lt;br /&gt;
  if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
   os.shutdown()&lt;br /&gt;
  elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
   attempted_login = true&lt;br /&gt;
   print(&amp;quot;Please login...&amp;quot;)&lt;br /&gt;
   write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
   local username = read()&lt;br /&gt;
   write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
   local password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
   rednet.send(password_server, username, true)&lt;br /&gt;
   senderId, message, distance = rednet.receive(5)&lt;br /&gt;
   if password == message then&lt;br /&gt;
    failed = false&lt;br /&gt;
    locker = false&lt;br /&gt;
    term.clear()&lt;br /&gt;
    term.setCursorPos(1,1)&lt;br /&gt;
    print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
   else&lt;br /&gt;
    print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
    sleep(3)&lt;br /&gt;
   end&lt;br /&gt;
  else&lt;br /&gt;
   print(&amp;quot;Command not recognised...&amp;quot;)&lt;br /&gt;
   sleep(2)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Thoughts and Notes ==&lt;br /&gt;
''Note: You do not have to read these if you use the new system.''&amp;lt;br /&amp;gt;&lt;br /&gt;
Although this may work very well as a login system, it is insecure by the flaw that a malicious sniffer can unnoticeably obtain a copy of the password while it is being sent as described on the [[Rednet_(API)|Rednet API]] page, and use the password to login.&lt;br /&gt;
&lt;br /&gt;
If you change the client code, to &amp;quot;startup&amp;quot; and put it in the root directory, it works very well as a login system.&lt;br /&gt;
You may also want to put in the line &lt;br /&gt;
 os.pullEvent = os.pullEventRaw -- disables Ctrl+T&lt;br /&gt;
as if it doesn't work first time it can be difficult to get out of the program.&lt;br /&gt;
&lt;br /&gt;
If you have either Railcraft or Additional Pipes, find the 'World Anchor' or 'Teleport Tether' block. If your server can afford the resources, place the block within a 3x3 grid of your password server. It will ensure that even if you leave the chunk, the password server still is operational. Otherwise you may find that you cannot login because you've left the chunk and the password server is no longer dealing with requests.&lt;br /&gt;
&lt;br /&gt;
This is a minor security flaw but it is only if someone has access to a computer that is 'whitelisted' to access the password server. The security flaw is that if they use the password Not Valid on that computer they are allowed access;&lt;br /&gt;
&lt;br /&gt;
 if valid then&lt;br /&gt;
  --send client password&lt;br /&gt;
 else&lt;br /&gt;
  --send client Not Valid&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
to fix remove the else statement&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Programs]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Getting_Started&amp;diff=5938</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Getting_Started&amp;diff=5938"/>
				<updated>2013-08-23T23:24:15Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Prerequisite: Installing the mods ==&lt;br /&gt;
'''It is very important to read everything carefully before asking questions.'''&lt;br /&gt;
'''Also, the latest version of this mod may not be compatible with the current Minecraft release.'''&lt;br /&gt;
&lt;br /&gt;
# Install [http://jenkins.minecraftforge.net/job/forge/forge-recommended/ Minecraft Forge Recommended Build]&lt;br /&gt;
# Download the latest version of [http://computercraft.info ComputerCraft]&lt;br /&gt;
# Copy OR extract the .zip file into *minecraft folder*\mods\. (Tip: If on Windows, on the main screen of Minecraft, go to 'Texture Packs' and click on 'Open texture pack folder'. Go up one folder, there's your Minecraft folder. If on Mac, open Finder, hit Command+Shift+G and type ~/Library/ then hit enter, open 'Application Support' then open 'minecraft')&lt;br /&gt;
&amp;lt;!-- Both the zip or folder work. Please do not edit this without proof.  --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Crafting ==&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Crafting grid&lt;br /&gt;
|A1=stone |B1=stone      |C1=stone&lt;br /&gt;
|A2=stone |B2=Redstone   |C2=stone&lt;br /&gt;
|A3=stone |B3=glass pane |C3=stone&lt;br /&gt;
|Output=Computer&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Right click on the computer to use it.&amp;lt;br /&amp;gt;&lt;br /&gt;
Some important key combinations to remember:&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
!style=&amp;quot;background:#EEE&amp;quot; width=&amp;quot;200px&amp;quot;|Key Combination&lt;br /&gt;
!style=&amp;quot;background:#EEE&amp;quot; width=&amp;quot;*&amp;quot;|Usage&lt;br /&gt;
|-&lt;br /&gt;
|{{Keypress|key=CTRL}} + {{Keypress|key=T}}&lt;br /&gt;
|Closes the current program.&lt;br /&gt;
|-&lt;br /&gt;
|{{Keypress|key=CTRL}} + {{Keypress|key=R}}&lt;br /&gt;
|Reboots the computer.&lt;br /&gt;
|-&lt;br /&gt;
|{{Keypress|key=CTRL}} + {{Keypress|key=S}}&lt;br /&gt;
|Forcefully shuts down the computer.&lt;br /&gt;
|}&lt;br /&gt;
You usually will have to hold down the key combinations for at least 1 second&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Attaching hardware ==&lt;br /&gt;
You can a bunch of stuff to your computer. There are 6 sides to the sides of your computer, and the computer can interact with almost anything there that it can interact with. This includes [[Modem|modems]] [[Modem_(API)|(API)]], [[Disk_Drive|disk drives]] [[Fs_(API)|(API)]], [[Printer|Printers]] [[Printer_(API)|(API)]], [[Monitor|monitors]] [[Term_(API)|(API)]], and even redstone [[Rs_(API)|(API)]]! Connect these to the sides of your computer and use the appropriate API to control your hardware.&lt;br /&gt;
&lt;br /&gt;
== Using the computer 's shell ==&lt;br /&gt;
Your computer should come with CraftOS as long as you didn't mod the mod.&lt;br /&gt;
If you have ever used the Linux terminal or Command Prompt or DOS or something similar, shell usage should be pretty simple. &lt;br /&gt;
&lt;br /&gt;
However the CraftOS Shell is even simpler and it only has one thing you can do: Type the name of a program (along with arguments) and it will run.&lt;br /&gt;
&lt;br /&gt;
A few useful programs that will help you magically appear on every computer you use, because they are in the universal ''rom'' folder that every computer can access. &lt;br /&gt;
{| border=&amp;quot;2&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|cd&lt;br /&gt;
|'''C'''hanges the current working '''d'''irectory of the shell, so you can do something else.&lt;br /&gt;
|-&lt;br /&gt;
|ls&lt;br /&gt;
|'''L'''i'''s'''ts the contents of the working directory, with directories in green and files in white.&lt;br /&gt;
|-&lt;br /&gt;
|rm&lt;br /&gt;
|'''R'''e'''m'''oves (deletes) a file or folder&lt;br /&gt;
|-&lt;br /&gt;
|mkdir&lt;br /&gt;
|'''M'''a'''k'''es an empty '''dir'''ectory&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Programming your computer ==&lt;br /&gt;
    For programming tutorials, ''go to'': [[Tutorials]]&lt;br /&gt;
&lt;br /&gt;
Programming ComputerCraft computers is done with a programming language called Lua. Lua is intended to be pretty simple to use, but if you don't know how, you can check out the programming tutorials on this wiki. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Do you recall that one time ages ago when you looked up &amp;quot;how to play Minecraft&amp;quot;, and you got a basic guide: punch trees, make bench, make tools, build house, make torches. But do you remember the end?&lt;br /&gt;
&lt;br /&gt;
''The rest is up to you...''&lt;br /&gt;
&lt;br /&gt;
ComputerCraft works the same way. The goals and uses for ComputerCraft are limitless, and now you've gotten started. There is no definite thing to do next, the rest is up to you.&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Getting_Started&amp;diff=5937</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Getting_Started&amp;diff=5937"/>
				<updated>2013-08-23T22:48:11Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Prerequisite: Installing the mods ==&lt;br /&gt;
'''It is very important to read everything carefully before asking questions.'''&lt;br /&gt;
'''Also, the latest version of this mod may not be compatible with the current Minecraft release.'''&lt;br /&gt;
&lt;br /&gt;
# Install [http://jenkins.minecraftforge.net/job/forge/forge-recommended/ Minecraft Forge Recommended Build]&lt;br /&gt;
# Download the latest version of [http://computercraft.info ComputerCraft]&lt;br /&gt;
# Copy OR extract the .zip file into *minecraft folder*\mods\. (Tip: If on Windows, on the main screen of Minecraft, go to 'Texture Packs' and click on 'Open texture pack folder'. Go up one folder, there's your Minecraft folder. If on Mac, open Finder, hit Command+Shift+G and type ~/Library/ then hit enter, open 'Application Support' then open 'minecraft')&lt;br /&gt;
&amp;lt;!-- Both the zip or folder work. Please do not edit this without proof.  --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 1: Crafting your first computer ==&lt;br /&gt;
The recipe is simple:&amp;lt;br /&amp;gt;&lt;br /&gt;
{{Crafting grid&lt;br /&gt;
|A1=stone |B1=stone      |C1=stone&lt;br /&gt;
|A2=stone |B2=Redstone   |C2=stone&lt;br /&gt;
|A3=stone |B3=glass pane |C3=stone&lt;br /&gt;
|Output=Computer&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Right click on the computer to use it.&amp;lt;br /&amp;gt;&lt;br /&gt;
Some important key combinations to remember:&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
!style=&amp;quot;background:#EEE&amp;quot; width=&amp;quot;200px&amp;quot;|Shortcut&lt;br /&gt;
!style=&amp;quot;background:#EEE&amp;quot; width=&amp;quot;*&amp;quot;|Usage&lt;br /&gt;
|-&lt;br /&gt;
|{{Keypress|key=CTRL}} + {{Keypress|key=T}}&lt;br /&gt;
|Closes the current program.&lt;br /&gt;
|-&lt;br /&gt;
|{{Keypress|key=CTRL}} + {{Keypress|key=R}}&lt;br /&gt;
|Reboots the console.&lt;br /&gt;
|-&lt;br /&gt;
|{{Keypress|key=CTRL}} + {{Keypress|key=S}}&lt;br /&gt;
|Forcefully shuts down the computer.&lt;br /&gt;
|}&lt;br /&gt;
NOTE: You have to hold the keyboard shortcuts down for at least 1 second!&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 2: Wiring it all up ==&lt;br /&gt;
The computer accepts many forms of redstone. For simple structures, such as a password protected door, only a single line of redstone is needed.&lt;br /&gt;
However, this mod can do much more. If you need to connect multiple wires to one side, you can just use RedPower's  bundled cables, wich will let you connect 16 redstone wires to each side of the computer, or a total of 96 input/output lines when using all sides of the computer (As if you'd ever need all of them).&lt;br /&gt;
&lt;br /&gt;
== Step 3: Programming your system ==&lt;br /&gt;
If you've programmed anything before this shouldn't be hard. It'll feel very comfortable.&lt;br /&gt;
&lt;br /&gt;
NOTE: You may also want to make a [[Floppy Disk]] or two to use along with your machine&lt;br /&gt;
&lt;br /&gt;
Type&lt;br /&gt;
edit &amp;lt;filename&amp;gt;&lt;br /&gt;
in the terminal to open the included feature-rich text editor. To get the hang of Lua if you're new, use&lt;br /&gt;
 edit /rom/programs/hello&lt;br /&gt;
to view the code of a simple program 'hello'.&lt;br /&gt;
&lt;br /&gt;
Navigating is easy.&lt;br /&gt;
 &amp;gt; ls&lt;br /&gt;
 rom&lt;br /&gt;
 &amp;gt; cd rom&lt;br /&gt;
 rom&amp;gt; ls&lt;br /&gt;
 apis   help   programs&lt;br /&gt;
 startup&lt;br /&gt;
 rom&amp;gt; cd programs&lt;br /&gt;
 rom/programs&amp;gt; cd /&lt;br /&gt;
 &amp;gt;&lt;br /&gt;
To say it in English: ls '''l'''i'''s'''ts the files and folders in a directory, while cd changes the '''c'''urrent '''d'''irectory. '''/''' is the root of the computer.&lt;br /&gt;
&lt;br /&gt;
== Step 4: Test it ==&lt;br /&gt;
Make sure that your program is bug-proof before using it as something important. A system controlling the state of an IndustrialCraft² Mark-III Nuclear Reactor to prevent it from overheating shouldn't crash every now and then with &amp;quot;Too long without yielding&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Step 5: Extend it ==&lt;br /&gt;
Give back your part to the community. Help others on the forums or improve the wiki. Or, make your own OS or shell to run on the computers and share it with everybody. You can even create your own peripheral blocks using the API to create even a bigger system. A mainframe, for example.&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5936</id>
		<title>Login with Roaming Profiles</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Login_with_Roaming_Profiles&amp;diff=5936"/>
				<updated>2013-08-23T22:42:41Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This tutorial covers how to make a password server and a password client. The server will host a Lua table of usernames and passwords and the client will remotely connect each start up, ask the user for their username and password and compare it to that on the password server.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Setting Up ==&lt;br /&gt;
As I'm sure you're aware, writing code directly into the computer terminal can be difficult, slow, and therefore annoying. I highly recommend writing/copying the following code into a Lua editor and then using FTP to transfer the documents across to the computer or disk. Please ensure you do not add the .lua extension.  Programs are saved in your minecraft world under the &amp;quot;computer&amp;quot; directory, with one folder for each computer plus the folder &amp;quot;disk&amp;quot; which contains a directory for each disk.&lt;br /&gt;
&lt;br /&gt;
First craft two or more computers. One will act as your password server, any others will be connecting to that computer. Find the computer ID of your password server. This is important as we don't want to broadcast password requests and replies. In the following code I have also locked the requests to certain computers to ensure security but it is not a needed component of the code. If you decide to take the security as well, make a note of all of the ID's of the client computers. I found it useful to give each computer a label and then search for labels.txt on the server to map it out easily.&lt;br /&gt;
&lt;br /&gt;
Each computer you craft needs a [[modem|rednet modem]].&lt;br /&gt;
&lt;br /&gt;
== Server ==&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 term.clear()&lt;br /&gt;
 term.setCursorPos(1,1)&lt;br /&gt;
 print(&amp;quot;This is a password server. There is no user interaction here.&amp;quot;)&lt;br /&gt;
 print(&amp;quot;Please find a computer and login there.&amp;quot;) &lt;br /&gt;
 local firstCycle = true&lt;br /&gt;
 local validSender = false&lt;br /&gt;
 local modemSide = &amp;quot;left&amp;quot; -- change to the side of the computer your modem is on&lt;br /&gt;
 local valid = false&lt;br /&gt;
 users = {&amp;quot;username1&amp;quot;, &amp;quot;username2&amp;quot; } --make sure users and passwords line up&lt;br /&gt;
 passwords = {&amp;quot;password1&amp;quot;, &amp;quot;password2&amp;quot; }&lt;br /&gt;
 senders = { 1, 2, 3, 4 } -- computer ID's of the computers you want to accept requests from&lt;br /&gt;
 function bootUp()&lt;br /&gt;
  rednet.open(modemSide)&lt;br /&gt;
 end&lt;br /&gt;
 while true do &lt;br /&gt;
  validSender = false&lt;br /&gt;
  if firstCycle then&lt;br /&gt;
   bootUp()&lt;br /&gt;
   firstCycle = false&lt;br /&gt;
  end&lt;br /&gt;
  senderId, message, distance = rednet.receive()&lt;br /&gt;
  for i,v in ipairs(senders) do&lt;br /&gt;
   if v == senderId then&lt;br /&gt;
    validSender = true&lt;br /&gt;
    break&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
  if validSender then&lt;br /&gt;
   for i,v in ipairs(users) do&lt;br /&gt;
    if message == v then&lt;br /&gt;
     valid = true&lt;br /&gt;
     password = passwords[i]&lt;br /&gt;
     break&lt;br /&gt;
    else&lt;br /&gt;
     valid = false&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   if valid then&lt;br /&gt;
    rednet.send(senderId, password, true)&lt;br /&gt;
   else&lt;br /&gt;
    rednet.send(senderId, &amp;quot;Not Valid&amp;quot;, true)&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Client ==&lt;br /&gt;
&lt;br /&gt;
 os.pullEvent = os.pullEventRaw&lt;br /&gt;
 local locker = true&lt;br /&gt;
 local failed = true&lt;br /&gt;
 local attempted_login = true&lt;br /&gt;
 local password_server = 0 -- change to the ID of your password server computer&lt;br /&gt;
 rednet.open(&amp;quot;left&amp;quot;) -- change to the side your rednet modem is on&lt;br /&gt;
 while locker do&lt;br /&gt;
  attempted_login = false&lt;br /&gt;
  term.clear()&lt;br /&gt;
  term.setCursorPos(1,1)&lt;br /&gt;
  print(&amp;quot;Welcome to a USERS PC : Roaming Profile Enabled&amp;quot;)&lt;br /&gt;
  print(&amp;quot;What would you like to do?&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[1] Login (*)&amp;quot;)&lt;br /&gt;
  print(&amp;quot;[2] Shutdown&amp;quot;)&lt;br /&gt;
  write(&amp;quot;&amp;gt; &amp;quot;)&lt;br /&gt;
  local input = read()&lt;br /&gt;
  if input == &amp;quot;2&amp;quot; then&lt;br /&gt;
   os.shutdown()&lt;br /&gt;
  elseif input == &amp;quot;1&amp;quot; then&lt;br /&gt;
   attempted_login = true&lt;br /&gt;
   print(&amp;quot;Please login...&amp;quot;)&lt;br /&gt;
   write(&amp;quot;Username: &amp;quot;)&lt;br /&gt;
   local username = read()&lt;br /&gt;
   write(&amp;quot;Password: &amp;quot;)&lt;br /&gt;
   local password = read(&amp;quot;*&amp;quot;)&lt;br /&gt;
   rednet.send(password_server, username, true)&lt;br /&gt;
   senderId, message, distance = rednet.receive(5)&lt;br /&gt;
   if password == message then&lt;br /&gt;
    failed = false&lt;br /&gt;
    locker = false&lt;br /&gt;
    term.clear()&lt;br /&gt;
    term.setCursorPos(1,1)&lt;br /&gt;
    print(&amp;quot;Welcome &amp;quot;, username)&lt;br /&gt;
   else&lt;br /&gt;
    print(&amp;quot;Invalid Username or Password.&amp;quot;)&lt;br /&gt;
    sleep(3)&lt;br /&gt;
   end&lt;br /&gt;
  else&lt;br /&gt;
   print(&amp;quot;Command not recognised...&amp;quot;)&lt;br /&gt;
   sleep(2)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
== Thoughts and Notes ==&lt;br /&gt;
Although this may work very well as a login system, it is insecure by the flaw that a malicious sniffer can unnoticeably obtain a copy of the password while it is being sent as described on the [[Rednet_(API)|Rednet API]] page, and use the password to login.&lt;br /&gt;
&lt;br /&gt;
If you change the client code, to &amp;quot;startup&amp;quot; and put it in the root directory, it works very well as a login system.&lt;br /&gt;
You may also want to put in the line &lt;br /&gt;
 os.pullEvent = os.pullEventRaw -- disables Ctrl+T&lt;br /&gt;
as if it doesn't work first time it can be difficult to get out of the program.&lt;br /&gt;
&lt;br /&gt;
If you have either Railcraft or Additional Pipes, find the 'World Anchor' or 'Teleport Tether' block. If your server can afford the resources, place the block within a 3x3 grid of your password server. It will ensure that even if you leave the chunk, the password server still is operational. Otherwise you may find that you cannot login because you've left the chunk and the password server is no longer dealing with requests.&lt;br /&gt;
&lt;br /&gt;
This is a minor security flaw but it is only if someone has access to a computer that is 'whitelisted' to access the password server. The security flaw is that if they use the password Not Valid on that computer they are allowed access;&lt;br /&gt;
&lt;br /&gt;
 if valid then&lt;br /&gt;
  --send client password&lt;br /&gt;
 else&lt;br /&gt;
  --send client Not Valid&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
to fix remove the else statement&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Programs]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Rednet_(API)&amp;diff=5935</id>
		<title>Rednet (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Rednet_(API)&amp;diff=5935"/>
				<updated>2013-08-23T13:22:30Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{msgbox&lt;br /&gt;
|title=Please Note&lt;br /&gt;
|text=As of ComputerCraft 1.5, [[Modem_(API)|channels]] have been added, and no longer supports&amp;lt;br&amp;gt;transmitting data through Bundled Cables. However interacting with Bundled Cables is still available via the [[Redstone_(API)|Redstone API]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The Rednet API allows computers to communicate between themselves without using redstone wires. In order to send and receive data, a [[modem]] is required. The data is received immediately after sending it, but only by computers within a certain range. That range depends on the altitude of the sending computer increasing with higher altitudes to a max of 384.&lt;br /&gt;
'''NOTE:''' The distance variable that is sent/received through the Rednet API is based off of the computer location, not the modem location. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Rednet (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.open]]({{type|string}} side)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Tells the computer that the side can be used for networking.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.close]]({{type|string}} side)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Tells the computer that the side can no longer be used for networking.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.announce]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Broadcasts an empty rednet message.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.send]]({{type|number}} receiverID, {{type|string}} message)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sends a message to the computer using the opened sides. The receiver ID is the ID (number, not string) of the computer you're sending the message to. ID as nil will do the same as a broadcast. The message must be a string to send across rednet, if you are wanting to send a table see [[textutils.serialize]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.broadcast]]({{type|string}} message)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sends the message to ALL connected and open computers.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.receive]]({{type|number}} timeout)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Waits until it received a rednet message or &amp;lt;var&amp;gt;timeout&amp;lt;/var&amp;gt; has passed. Leave args empty to wait for a message forever.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.isOpen]]({{type|string}} side)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns true if the wireless modem is open.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Events==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;1&amp;quot; | Event Name&lt;br /&gt;
! colspan=&amp;quot;1&amp;quot; | Description&lt;br /&gt;
! colspan=&amp;quot;1&amp;quot; | Parameters&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | rednet_message&lt;br /&gt;
|Fired when a rednet message is received (can be used as alternative for rednet.receive())&lt;br /&gt;
|{{type|number}} senderId, {{type|string}} message, {{type|number}} distance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==History==&lt;br /&gt;
Before the creation of the in-game wireless networking API, the term &amp;quot;Rednet&amp;quot; referred to a system created by one of the ComputerCraft users based on bundled cables from a popular Minecraft mod - RedPower. It also allowed communication between computers, but the data was transferred slowly - every bit was converted to redstone signal, that lasted about 0,1 seconds. On the release of ComputerCraft 1.3, the system became useless, as the wireless networking was officially implemented to the mod.&lt;br /&gt;
&lt;br /&gt;
== Security ==&lt;br /&gt;
'''ID Whitelists are useless, and messages sent by Rednet can be viewed by anyone, even if they are not the target computer.'''&lt;br /&gt;
&lt;br /&gt;
Rednet alone is completely insecure. Any messages send via rednet can actually be sniffed, contrary to popular belief, and people can pretend to be a certain computer and fool rednet easily. &lt;br /&gt;
&lt;br /&gt;
Rednet simply utilizes the Modem API. A user can easily sniff and find out what messages a computer is receiving if he knows it's ID. All he has to do is use the [[Modem_(API)|Modem API]] to listen, where the channel to listen on is the target computer's ID. Additionally, a malicious user can 'pretend' to be a certain computer by using the Modem API to send a message to the target computer's ID with the message, but using the ID of the computer to pretend to be for the reply channel parameter. If they do so, the computer receiving the message with rednet will be fooled into thinking it came from a different computer.&lt;br /&gt;
&lt;br /&gt;
When using rednet for anything with security critical, be sure to implement your own security measures.&lt;br /&gt;
&lt;br /&gt;
== Technical Details ==&lt;br /&gt;
'''Overview''': Rednet functions by having a modem listen on the channel of the computers ID, and the rednet broadcast channel for messages. It uses the ''replyChannel'' parameter of the modem_message event as the senders, computer ID. It broadcasts by sending a simple modem message on the rednet broadcast channel, and receives by receiving a modem message on the broadcast channel or the channel of it's computer's ID. &lt;br /&gt;
&lt;br /&gt;
'''CHANNEL_BROADCAST''': 65535&lt;br /&gt;
&lt;br /&gt;
(local) '''tValidSides''': Contains valid values of strings containing computer sides, used by ''open'' and ''close''&lt;br /&gt;
&lt;br /&gt;
'''rednet.open(sSide)''': Checks if ''sSide'' is a string, a valid side, and a side with a modem on it. Then it opens the modem on ''CHANNEL_BROADCAST'' and ''os.getComputerID()''&lt;br /&gt;
&lt;br /&gt;
'''rednet.close(sSide)''': Checks if ''sSide'' is a string, a valid side, and a side with a modem on it. Then it closes the modem on ''CHANNEL_BROADCAST'' and ''os.getComputerID()''&lt;br /&gt;
&lt;br /&gt;
'''rednet.isOpen(sSide)''': Checks if ''sSide'' is a string, a valid side, and if it is a side containing a modem, it returns true if the modem on ''sSide'' is open on both ''CHANNEL_BROADCAST'' and ''os.getComputerID()''&lt;br /&gt;
&lt;br /&gt;
'''rednet.send(nRecipient, sMessage)''': For each side ''sSide'' in ''rs.getSides()'', it calls ''isOpen(sSide)''. If the result is true, it executes&lt;br /&gt;
 peripheral.call( sSide, &amp;quot;transmit&amp;quot;, nRecipient, os.getComputerID(), sMessage )&lt;br /&gt;
&lt;br /&gt;
'''rednet.broadcast(sMessage)''': Calls ''send(CHANNEL_BROADCAST, sMessage)''&lt;br /&gt;
&lt;br /&gt;
'''rednet.receive(nTimeout)''': If ''nTimeout'' is there, it starts a timer for ''nTimeout'' seconds-stored in ''timer'', and sets ''sFilter'' to nil. Otherwise, ''sFilter'' is set to &amp;quot;rednet_message&amp;quot;. In a loop, &lt;br /&gt;
 local e, p1, p2, p3, p4, p5 = os.pullEvent( sFilter )&lt;br /&gt;
is called. If ''e'' is &amp;quot;rednet_message&amp;quot; then it returns ''p1'', ''p2'', and ''p3'', but if ''e'' is &amp;quot;timer&amp;quot;, and ''p1'' is ''timer'' then it returns nil.&lt;br /&gt;
&lt;br /&gt;
(local) '''bRunning''': false&lt;br /&gt;
&lt;br /&gt;
'''rednet.run()''': If ''bRunning'' is true, then it errors &amp;quot;rednet is already running&amp;quot;. It then sets ''bRunning'' to true to indicate that it is running. Looping while ''bRunning'', it pulls&lt;br /&gt;
 local sEvent, sSide, sChannel, sReplyChannel, sMessage, nDistance = os.pullEventRaw( &amp;quot;modem_message&amp;quot; )&lt;br /&gt;
Then if ''sEvent'' is &amp;quot;modem_message&amp;quot;, ''isOpen(sSide)'' is true, and ''sChannel'' is ''os.getComputerID()'' or it is ''CHANNEL_BROADCAST'', then it queues &lt;br /&gt;
 os.queueEvent( &amp;quot;rednet_message&amp;quot;, sReplyChannel, sMessage, nDistance )&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	<entry>
		<id>https://www.computercraft.info/wiki/index.php?title=Rednet_(API)&amp;diff=5934</id>
		<title>Rednet (API)</title>
		<link rel="alternate" type="text/html" href="https://www.computercraft.info/wiki/index.php?title=Rednet_(API)&amp;diff=5934"/>
				<updated>2013-08-23T13:05:18Z</updated>
		
		<summary type="html">&lt;p&gt;Bwhodle: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{msgbox&lt;br /&gt;
|title=Please Note&lt;br /&gt;
|text=As of ComputerCraft 1.5, [[Modem_(API)|channels]] have been added, and no longer supports&amp;lt;br&amp;gt;transmitting data through Bundled Cables. However interacting with Bundled Cables is still available via the [[Redstone_(API)|Redstone API]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The Rednet API allows computers to communicate between themselves without using redstone wires. In order to send and receive data, a [[modem]] is required. The data is received immediately after sending it, but only by computers within a certain range. That range depends on the altitude of the sending computer increasing with higher altitudes to a max of 384.&lt;br /&gt;
'''NOTE:''' The distance variable that is sent/received through the Rednet API is based off of the computer location, not the modem location. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%; border: solid 1px black; margin: 2px; border-spacing: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; style=&amp;quot;font-weight: bold; font-size: large; padding-bottom: .3em; border-bottom: solid #C9C9C9 1px; background: #D3FFC2; line-height:28px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Grid_disk.png|24px]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
Rednet (API)&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;width: 350px; background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Method Name&amp;lt;/td&amp;gt;&amp;lt;td style=&amp;quot;background: #E0E0E0; padding: .4em; font-weight:bold;&amp;quot;&amp;gt;Description&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.open]]({{type|string}} side)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Tells the computer that the side can be used for networking.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.close]]({{type|string}} side)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Tells the computer that the side can no longer be used for networking.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.announce]]()&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Broadcasts an empty rednet message.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.send]]({{type|number}} receiverID, {{type|string}} message)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sends a message to the computer using the opened sides. The receiver ID is the ID (number, not string) of the computer you're sending the message to. ID as nil will do the same as a broadcast. The message must be a string to send across rednet, if you are wanting to send a table see [[textutils.serialize]]&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.broadcast]]({{type|string}} message)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Sends the message to ALL connected and open computers.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #E8E8E8;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.receive]]({{type|number}} timeout)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Waits until it received a rednet message or &amp;lt;var&amp;gt;timeout&amp;lt;/var&amp;gt; has passed. Leave args empty to wait for a message forever.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr style=&amp;quot;background-color: #FFFFFF;&amp;quot;&amp;gt;&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;[[rednet.isOpen]]({{type|string}} side)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td style=&amp;quot;border-top: solid #C9C9C9 1px; padding: .4em;&amp;quot;&amp;gt;Returns true if the wireless modem is open.&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Events==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;1&amp;quot; | Event Name&lt;br /&gt;
! colspan=&amp;quot;1&amp;quot; | Description&lt;br /&gt;
! colspan=&amp;quot;1&amp;quot; | Parameters&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;row&amp;quot; | rednet_message&lt;br /&gt;
|Fired when a rednet message is received (can be used as alternative for rednet.receive())&lt;br /&gt;
|{{type|number}} senderId, {{type|string}} message, {{type|number}} distance&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==History==&lt;br /&gt;
Before the creation of the in-game wireless networking API, the term &amp;quot;Rednet&amp;quot; referred to a system created by one of the ComputerCraft users based on bundled cables from a popular Minecraft mod - RedPower. It also allowed communication between computers, but the data was transferred slowly - every bit was converted to redstone signal, that lasted about 0,1 seconds. On the release of ComputerCraft 1.3, the system became useless, as the wireless networking was officially implemented to the mod.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Technical Details ==&lt;br /&gt;
'''Overview''': Rednet functions by having a modem listen on the channel of the computers ID, and the rednet broadcast channel for messages. It uses the ''replyChannel'' parameter of the modem_message event as the senders, computer ID. &lt;br /&gt;
&lt;br /&gt;
'''CHANNEL_BROADCAST''': 65535&lt;br /&gt;
&lt;br /&gt;
(local) '''tValidSides''': Contains valid values of strings containing computer sides, used by ''open'' and ''close''&lt;br /&gt;
&lt;br /&gt;
'''rednet.open(sSide)''': Checks if ''sSide'' is a string, a valid side, and a side with a modem on it. Then it opens the modem on ''CHANNEL_BROADCAST'' and ''os.getComputerID()''&lt;br /&gt;
&lt;br /&gt;
'''rednet.close(sSide)''': Checks if ''sSide'' is a string, a valid side, and a side with a modem on it. Then it closes the modem on ''CHANNEL_BROADCAST'' and ''os.getComputerID()''&lt;br /&gt;
&lt;br /&gt;
'''rednet.isOpen(sSide)''': Checks if ''sSide'' is a string, a valid side, and if it is a side containing a modem, it returns true if the modem on ''sSide'' is open on both ''CHANNEL_BROADCAST'' and ''os.getComputerID()''&lt;br /&gt;
&lt;br /&gt;
'''rednet.send(nRecipient, sMessage)''': For each side ''sSide'' in ''rs.getSides()'', it calls ''isOpen(sSide)''. If the result is true, it executes&lt;br /&gt;
 peripheral.call( sSide, &amp;quot;transmit&amp;quot;, nRecipient, os.getComputerID(), sMessage )&lt;br /&gt;
&lt;br /&gt;
'''rednet.broadcast(sMessage)''': Calls ''send(CHANNEL_BROADCAST, sMessage)''&lt;br /&gt;
&lt;br /&gt;
'''rednet.receive(nTimeout)''': If ''nTimeout'' is there, it starts a timer for ''nTimeout'' seconds-stored in ''timer'', and sets ''sFilter'' to nil. Otherwise, ''sFilter'' is set to &amp;quot;rednet_message&amp;quot;. In a loop, &lt;br /&gt;
 local e, p1, p2, p3, p4, p5 = os.pullEvent( sFilter )&lt;br /&gt;
is called. If ''e'' is &amp;quot;rednet_message&amp;quot; then it returns ''p1'', ''p2'', and ''p3'', but if ''e'' is &amp;quot;timer&amp;quot;, and ''p1'' is ''timer'' then it returns nil.&lt;br /&gt;
&lt;br /&gt;
(local) '''bRunning''': false&lt;br /&gt;
&lt;br /&gt;
'''rednet.run()''': If ''bRunning'' is true, then it errors &amp;quot;rednet is already running&amp;quot;. It then sets ''bRunning'' to true to indicate that it is running. Looping while ''bRunning'', it pulls&lt;br /&gt;
 local sEvent, sSide, sChannel, sReplyChannel, sMessage, nDistance = os.pullEventRaw( &amp;quot;modem_message&amp;quot; )&lt;br /&gt;
Then if ''sEvent'' is &amp;quot;modem_message&amp;quot;, ''isOpen(sSide)'' is true, and ''sChannel'' is ''os.getComputerID()'' or it is ''CHANNEL_BROADCAST'', then it queues &lt;br /&gt;
 os.queueEvent( &amp;quot;rednet_message&amp;quot;, sReplyChannel, sMessage, nDistance )&lt;br /&gt;
&lt;br /&gt;
[[Category:APIs]]&lt;/div&gt;</summary>
		<author><name>Bwhodle</name></author>	</entry>

	</feed>