### HTTP implemented in epic4's scripting language ### by Zachary White (skullY on EFnet and FEFnet) /* General program flow bind some port, make the default 6667. Store each in some variable that can be set from within the client. Upon connection, note the IP and port. Set the status variable to note that the connection has happened, we are just waiting for the client request. When the client sends the HTTP request, note all the pertinent info, then figure out what to do. If they don't have an authentication header, then return the proper noauth code. username should be set by client, and must not be the same as the user's nick or system username. Same for the passwd. Maybe run the passwd against a dictionary and do basic checks like that? If the client doesn't present a cookie, try to set one, and note that the client didn't return the cookie. If the client tries to connect again and doesn't return the cookie, deny the client. I need some sort of auth to prevent spoofed requests, and this is about the best I can come up with short of SSL. Maybe some javascript that implements blowfish or idea or something..... Requests and commands: GET's should only be made to update the irc frame, and it should happen once every 5 or 6 seconds. Any more than that and you're a freak and should be using a real client, not a web browser. All text submission should be done on a POST method. Initially, there will be two "scripts" to post to. /SAY which will put anything you type into the channel, and /DO which will run a command in a hopefully sane mannor. So as to avoid anything really bad happening to an owned client, we should $encode() the input of both upon reading, and $decode() it when using it, being careful not to further evaluate it. The Web Browser should be broken up into 3 frames. The bottom one where all the commands and text entry happens, the top one where all output goes, and a small middle bar that acts like a status bar. *evil grin* Possible do commands, and their arguments: WHO NAMES WHOIS KICK [reason] OP [nick1] [nick...] DEOP [nick1] [nick...] MOP MDOP JOIN LEAVE AWAY [reason] IGNORE Connection status: 1 Waiting for request 2 Request recieved, send reply 3 Closing connection */ ### Variables eval assign HTTP_PORT $listen(6667) @ connection_num=0 eval : $setitem(message 0 ~) eval : $setitem(message 1 ~) eval : $setitem(message 2 ~) eval : $setitem(message 3 ~) eval : $setitem(message 4 ~) eval : $setitem(message 5 ~) eval : $setitem(message 6 ~) eval : $setitem(message 7 ~) eval : $setitem(message 8 ~) eval : $setitem(message 9 ~) eval : $setitem(message 10 ~) eval : $setitem(client 0 ~) eval : $setitem(client 1 ~) eval : $setitem(client 2 ~) eval : $setitem(client 3 ~) eval : $setitem(client 4 ~) eval : $setitem(client 5 ~) eval : $setitem(client 6 ~) eval : $setitem(client 7 ~) eval : $setitem(client 8 ~) eval : $setitem(client 9 ~) eval : $setitem(client 10 ~) eval : $setitem(client_headers 0 referer:) eval : $setitem(client_headers 1 via:) eval : $setitem(client_headers 2 authorization:) eval : $setitem(client_headers 3 cookie:) eval : $setitem(client_headers 4 host:) eval : $setitem(client_headers 5 user-agent:) /* Needed /ons: on connection 6667 { Note file descripter assign to status of 1 } */ eval on ^dcc_raw "% % N $HTTP_PORT" { eval :$setitem(client $0 $1) xecho -banner HTTP connection from $1 } /* on data 6667 { if hostname:port = status1 { check request against possible URLs { command_to_serve_that_url }{ command_to_serve 404 } }{ elsif hostname:port = status2 # data should not be coming in right now. Ignore it }{ # Data should especially not be coming in now. } } */ eval on dcc_raw "% % D *" { if ([$tolower($3)]==[get]) { http_get $0 $1 $encode($4-) }{ http_header $0 $1 $encode($3-) } } /* on {public,public_other,msg,notice} * { add_message_to_stack } Aliases: */ # Passed: A message to add to the stack alias add_message_to_stack { eval : $delitem(message 0) eval : $setitem(message 10 $*) } # Passed: fd remotehost $decode(URI protocol/version) alias http_get { dcc raw $0 $1 You requested $decode($2) xecho -banner HTTP Request from $1 for $decode($2) } alias http_header { # This should search the referer array, and if it finds a match, do something # with the information if ([$2]) { xecho -banner $1 sent the following header: $decode($2) }{ xecho -banner $1 sent a blank line, sending request } } /* # Passed: channel/nick and all pertitent client info alias http_who { on who { store in list } who wait format and send to client } # Passed: channel/nick alias http_names { # I think there's an epic function for this. That makes it easy add_message_to_stack $names_list } # Passed: nick alias http_whois { # Set /on hooks for all the whois types on whois hooks whois nick wait foreach_on_whois_input { add_message_to_stack } } # Passed: $encode(nick channel reason) alias http_kick { //kick $decode($nick $channel $reason) } # Passed: channel nick0 alias http_op { //mode $channel +ooo $1 $2 $3 if ($4) { http_op $4- } } # Passed: channel nick0 alias http_deop { //mode $channel -ooo $1 $2 $3 if ($4) { http_deop $4- } } # Passed: $encode(channel ) alias http_join { join $decode($0) } # Passed: $encode(channel) alias http_leave { leave $decode($0) } # Passed: $encode(reason) alias http_away { away $decode($0) } # Passed: $encode(mask type) alias http_ignore { ignore $decode($0) } */