Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.71 KB | None | 0 0
  1. #!/usr/bin/python
  2. import socket
  3. import urlparse
  4. import cgi
  5. import threading
  6. import sys
  7. import traceback
  8. import re
  9. import os
  10. import mimetypes
  11. import sqlite3
  12. import Cookie # wtf why is this capitalized
  13. import random
  14. import crypt
  15.  
  16. # per-site secret; only first two characters are used.
  17. secret = 'GG IS MY SECRET'
  18.  
  19. # initialize random number generator from the system time on import.
  20. random.seed()
  21.  
  22. def generate_session_id(user):
  23. """
  24. Generate a unique session ID based on the user name with the given
  25. site-specific secret. How secure is this, really?
  26. """
  27. salt = secret[:2]
  28. return crypt.crypt(user + str(random.random()), salt)
  29. conn = sqlite3.connect('webserve-info.db')
  30.  
  31. def serve(interface, port):
  32. sock = socket.socket()
  33. sock.bind((interface, port))
  34. sock.listen(10)
  35. print 'Listening on port', port
  36. while True:
  37. (client_sock, client_address) = sock.accept()
  38. process = threading.Thread(target=handle_connection, args=(client_sock, client_address))
  39. process.start()
  40.  
  41. def handle_connection(client_sock, client_address):
  42. full_data = ''
  43. while True:
  44. data = client_sock.recv(1)
  45. full_data += data
  46. if full_data.endswith('\r\n\r\n'):
  47. break
  48. header_lines = full_data.split('\r\n')[:-2]
  49. method, path, _ = header_lines[0].split()
  50. _, _, path, query, _ = urlparse.urlsplit(path)
  51. query = cgi.parse_qs(query)
  52. headers = [h.split(': ', 1) for h in header_lines[1:]]
  53.  
  54. post_data = None
  55. if method == 'POST':
  56. length = int(re.findall(r'Content-Length: (\d+)', full_data)[0])
  57. post_data = client_sock.recv(length)
  58. post_data = cgi.parse_qs(post_data)
  59.  
  60. try:
  61. status, head, data = delegate(method, path, headers, query, post_data)
  62. except:
  63. print "Exception in user code:"
  64. print '-' * 60
  65. traceback.print_exc(file=sys.stdout)
  66. print '-' * 60
  67. status, head, data = 500, [], '<h1>500 Internal Server Error</h1>'
  68.  
  69.  
  70. if status == 200: # we dont got any html pages to serve up for failures, sry
  71. if not any(h[0] == 'Content-Type' for h in head):
  72. head.insert(0, ('Content-Type', 'text/html'))
  73.  
  74.  
  75. if ('Content-Type', 'text/html') in head:
  76. # add top and bottom halves
  77. data = open('files/top.html').read() + data + open('files/bottom.html').read()
  78.  
  79. head.append(('Content-Length', str(len(data))))
  80.  
  81. head = '\r\n'.join(["%s: %s" % (k, v) for (k, v) in head])
  82.  
  83. status_responses = {200: '200 OK', 401: '401 Unauthorized', 404: '404 Not Found', 500: '500 Internal Server Error'}
  84.  
  85. if status not in status_responses:
  86. status = 500
  87. client_sock.sendall("HTTP/1.1 %s\r\n%s\r\n\r\n%s" % (status_responses[status], head, data))
  88. client_sock.close()
  89.  
  90. def delegate(request_type, path, headers, get, post = None):
  91. if(path.endswith('/')):
  92. path += 'index.html'
  93. if(os.path.isfile("files%s" % path)):
  94. return read_file(headers, get, post, path)
  95. go = '_'.join(path[1:].split('/'))
  96. if go in globals():
  97. return globals()[go](headers, get, post)
  98. return page_missing(headers, get, post, path)
  99.  
  100. def read_file(received_headers, get, post, path):
  101. mime = mimetypes.guess_type("files%s" % path)[0]
  102. return 200, [('Content-Type', mime)], open("files%s" % path).read()
  103.  
  104. def page_missing(received_headers, get, post, path):
  105. if path.startswith('/test/'):
  106. data = 'hello, %s' % path
  107. for request_data, name in ((get, 'get_data:'), (post, 'post_data:')):
  108. if request_data:
  109. data += " %s" % name
  110. for key in request_data:
  111. for val in request_data[key]:
  112. data += " key=%s; value=%s;" % (key, val)
  113. return 200, [], data
  114. else:
  115. return 404, [], ''
  116.  
  117. def auth_login(received_headers, get, post):
  118. print repr(post['username'][0]), ' is trying to login.'
  119. if post:
  120. _conn = sqlite3.connect('webserve-info.db')
  121. c = _conn.cursor()
  122. c.execute("SELECT * FROM users WHERE username = ? AND password = ? LIMIT 1", (post['username'][0], post['password'][0]))
  123. results = c.fetchone()
  124. if results:
  125. session = generate_session_id(post['username'][0])
  126. c.execute("""INSERT INTO sessions (user_id, session_id) VALUES(?, ?)""", (results[0], session))
  127. _conn.commit()
  128. C = Cookie.SimpleCookie()
  129. C['session'] = session
  130. C['session']['Path'] = '/'
  131. cookie_header = C.output().split(': ', 1)
  132. return 200, [cookie_header], ''
  133. return 401, [], '<h1>401 Unauthorized</h1>'
  134.  
  135. def auth_logout(received_headers, get, post):
  136. cookies_in = Cookie.SimpleCookie()
  137. for (k, v) in received_headers:
  138. if k.lower() == 'cookie':
  139. cookies_in.load(v)
  140.  
  141. C = Cookie.SimpleCookie()
  142. C['session'] = ''
  143. C['session']['Path'] = '/'
  144. _conn = sqlite3.connect('webserve-info.db')
  145. c = _conn.cursor()
  146. c.execute("""DELETE FROM sessions WHERE session_id = ?""", (cookies_in['session'].value,))
  147.  
  148. cookie_header = C.output().split(': ', 1)
  149. return 200, [("Set-Cookie", "user=; Path=/"), cookie_header], ''
  150.  
  151. def auth_print(received_headers, get, post):
  152. cookies_in = Cookie.SimpleCookie()
  153. for (k, v) in received_headers:
  154. if k.lower() == 'cookie':
  155. cookies_in.load(v)
  156. if 'session' in cookies_in:
  157. user = cookies_in['session'].value
  158.  
  159. _conn = sqlite3.connect('webserve-info.db')
  160. c = _conn.cursor()
  161. c.execute("SELECT * FROM users INNER JOIN sessions WHERE users.id = sessions.user_id AND sessions.session_id = ? LIMIT 1", (user,))
  162. user = c.fetchone()
  163. if user:
  164. return 200, [], 'you are user %s' % (user[1],)
  165. return 200, [], 'no user specified'
  166.  
  167. def movies_search_pair(received_headers, get, post):
  168. data = 'Movies Found:'
  169. actress = post['actress'][0]
  170. actor = post['actor'][0]
  171.  
  172. _conn = sqlite3.connect('webserve-info.db')
  173. c = _conn.cursor()
  174. c.execute(
  175. """SELECT title FROM movies
  176. WHERE id IN (
  177. SELECT movie_id FROM roles INNER JOIN actors ON actors.id = actor_id
  178. WHERE (name = ? and male = 1) OR (name = ? and male = 0)
  179. GROUP BY movie_id
  180. HAVING count(*) = 2
  181. )
  182. """, (actor, actress))
  183.  
  184. results = c.fetchall()
  185. if results:
  186. data += "<ul>"
  187. for movie in results:
  188. data += "<li>%s</li>" % (movie)
  189. return 200, [], data
  190.  
  191. def add_user(username, password):
  192. _conn = sqlite3.connect('webserve-info.db')
  193. c = _conn.cursor()
  194. c.execute('INSERT INTO users (username, password) VALUES(?, ?)', (username, password))
  195. _conn.commit()
  196.  
  197.  
  198. def generate_session_id(user):
  199. """
  200. Generate a unique session ID based on the user name with the given
  201. site-specific secret. How secure is this, really? ANSWER: VERY SECURE
  202. """
  203. salt = secret[:2]
  204. return crypt.crypt(user + str(random.random()), salt)
  205.  
  206. if __name__ == '__main__':
  207. host, port = sys.argv[1:]
  208. serve(host, int(port))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement