Advertisement
Guest User

Untitled

a guest
Mar 25th, 2016
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.05 KB | None | 0 0
  1. import os,socket,threading,sys
  2.  
  3. class Connection(threading.Thread):
  4. def __init__(self,conn_addr):
  5. self.conn, self.addr= conn_addr
  6. if (os.getcwd())[0] == 'C':
  7. self.workingdir = 'C:\\'
  8. else:
  9. self.workingdir = '/'
  10. threading.Thread.__init__(self)
  11.  
  12. def run(self):
  13. #220 Service ready for new user.
  14. self.conn.send(('220 Connected!\r\n').encode('utf-8'))
  15. while 1:
  16. msg=self.conn.recv(4096)
  17. if msg:
  18. msg = msg.decode("utf-8")
  19. print ('Recieved:',msg)
  20. try:
  21. #this calls self.whatever function the client specifies
  22. #i.e. if user types mkdir this calls self.MKD(msg)
  23. func=getattr(self,msg[:4].strip().upper())
  24. func(msg)
  25. except Exception as e:
  26. print ('ERROR:',e)
  27. #500 Syntax error, command unrecognized.
  28. #This may include errors such as command line too long.
  29. self.conn.send(('500 ERROR.\r\n').encode('utf-8'))
  30.  
  31. #function names are the same as the command sent over
  32. #by the client, this makes it easy to call the appropriate
  33. #function without needing a giant switch statement
  34. #username function
  35. def USER(self,msg):
  36. #331 User name okay, need password.
  37. self.conn.send(('331 Username is correct.\r\n').encode('utf-8'))
  38. self.username = msg[4:].strip()
  39.  
  40. #password function
  41. def PASS(self,msg):
  42. self.password = msg[4:].strip()
  43. #user is allowed to log in if username and password are the same
  44. if self.password == self.username:
  45. #230 User logged in, proceed.
  46. self.conn.send(('230 Password is correct.\r\n').encode('utf-8'))
  47. else:
  48. #530 Not logged in.
  49. self.conn.send(('530 Login incorrect.\r\n').encode('utf-8'))
  50.  
  51.  
  52. def PWD(self,msg):
  53. #257 "PATHNAME" created.
  54. self.conn.send(('257 '+'\"'+self.workingdir+'\"' +'\r\n').encode('utf-8'))
  55.  
  56. def MKD(self,msg):
  57. #this makes sure that the directory is always in the form
  58. #/stuff/morestuff/evenmorestuff/newdir in a Unix machine or
  59. #C:\stuff\morestuff\evenmorestuff\newdir in a Windows machine
  60. if self.workingdir.endswith('\\') or self.workingdir.endswith('/'):
  61. tempdir = self.workingdir + msg[4:].strip()
  62. elif self.workingdir.startswith('C'):
  63. tempdir = self.workingdir + '\\'+msg[4:].strip()
  64. else:
  65. tempdir = self.workingdir +'/'+ msg[4:].strip()
  66.  
  67. #if directory already exists then it fails
  68. if os.path.exists(tempdir):
  69. self.conn.send(('550 Create directory operation failed.\r\n').encode('utf-8'))
  70. else:
  71. os.mkdir(self.workingdir + msg[4:].strip())
  72. #257 "PATHNAME" created.
  73. self.conn.send(('257 '+ msg[4:].strip() +' created.\r\n').encode('utf-8'))
  74.  
  75. #same as PWD
  76. def XPWD(self,msg):
  77. #257 "PATHNAME" created.
  78. self.conn.send(('257 '+'\"'+self.workingdir+'\"' +'\r\n').encode('utf-8'))
  79.  
  80. #same as MKD
  81. def XMKD(self,msg):
  82. #this makes sure that the directory is always in the form
  83. #/stuff/morestuff/evenmorestuff/newdir in a Unix machine or
  84. #C:\stuff\morestuff\evenmorestuff\newdir in a Windows machine
  85. if self.workingdir.endswith('\\') or self.workingdir.endswith('/'):
  86. tempdir = self.workingdir + msg[4:].strip()
  87. elif self.workingdir.startswith('C'):
  88. tempdir = self.workingdir + '\\'+msg[4:].strip()
  89. else:
  90. tempdir = self.workingdir +'/'+ msg[4:].strip()
  91.  
  92. #if directory already exists then it fails
  93. if os.path.exists(tempdir):
  94. self.conn.send(('550 Create directory operation failed.\r\n').encode('utf-8'))
  95. else:
  96. os.mkdir(self.workingdir + msg[4:].strip())
  97. #257 "PATHNAME" created.
  98. self.conn.send(('257 '+ msg[4:].strip() +' created.\r\n').encode('utf-8'))
  99.  
  100. def CWD(self,msg):
  101. #this makes sure that the directory is always in the form
  102. #/stuff/morestuff/evenmorestuff/ in a Unix machine or
  103. #C:\stuff\morestuff\evenmorestuff\ in a Windows machine
  104. if self.workingdir.endswith('\\') or self.workingdir.endswith('/'):
  105. if msg[4:].strip().endswith('\\') or msg[4:].strip().endswith('/'):
  106. tempdir = self.workingdir + msg[4:].strip()
  107. elif self.workingdir.startswith('C'):
  108. tempdir = self.workingdir + msg[4:].strip() + '\\'
  109. else:
  110. tempdir = self.workingdir + msg[4:].strip() + '/'
  111. elif self.workingdir.startswith('C'):
  112. if msg[4:].strip().endswith('\\'):
  113. tempdir = self.workingdir + '\\'+msg[4:].strip()
  114. else:
  115. tempdir = self.workingdir +'\\'+ msg[4:].strip()+'\\'
  116. else:
  117. if msg[4:].strip().endswith('/'):
  118. tempdir = self.workingdir +'/'+ msg[4:].strip()
  119. else:
  120. tempdir = self.workingdir + '/'+msg[4:].strip()+'/'
  121.  
  122. if os.path.exists(tempdir):
  123. self.workingdir = tempdir
  124. #250 Requested file action okay, completed.
  125. self.conn.send(('250 Working directory updated.\r\n').encode('utf-8'))
  126. else:
  127. #550 Requested action not taken.
  128. #File unavailable (e.g., file not found, no access).
  129. self.conn.send(('550 That directory does not exist.\r\n').encode('utf-8'))
  130.  
  131. #same as CWD
  132. def XCWD(self,msg):
  133. if self.workingdir.endswith('\\') or self.workingdir.endswith('/'):
  134. if msg[4:].strip().endswith('\\') or msg[4:].strip().endswith('/'):
  135. tempdir = self.workingdir + msg[4:].strip()
  136. elif self.workingdir.startswith('C'):
  137. tempdir = self.workingdir + msg[4:].strip() + '\\'
  138. else:
  139. tempdir = self.workingdir + msg[4:].strip() + '/'
  140. elif self.workingdir.startswith('C'):
  141. if msg[4:].strip().endswith('\\'):
  142. tempdir = self.workingdir + '\\'+msg[4:].strip()
  143. else:
  144. tempdir = self.workingdir +'\\'+ msg[4:].strip()+'\\'
  145. else:
  146. if msg[4:].strip().endswith('/'):
  147. tempdir = self.workingdir +'/'+ msg[4:].strip()
  148. else:
  149. tempdir = self.workingdir + '/'+msg[4:].strip()+'/'
  150.  
  151. if os.path.exists(tempdir):
  152. self.workingdir = tempdir
  153. #250 Requested file action okay, completed.
  154. self.conn.send(('250 Working directory updated.\r\n').encode('utf-8'))
  155. else:
  156. #550 Requested action not taken.
  157. #File unavailable (e.g., file not found, no access).
  158. self.conn.send(('550 That directory does not exist.\r\n').encode('utf-8'))
  159.  
  160. def DELE(self,msg):
  161. #this makes sure that the directory is always in the form
  162. #/stuff/morestuff/evenmorestuff/file in a Unix machine or
  163. #C:\stuff\morestuff\evenmorestuff\file in a Windows machine
  164. if self.workingdir.endswith('\\') or self.workingdir.endswith('/'):
  165. tempdir = self.workingdir + msg[4:].strip()
  166. elif self.workingdir.startswith('C'):
  167. tempdir = self.workingdir + '\\'+msg[4:].strip()
  168. else:
  169. tempdir = self.workingdir +'/'+ msg[4:].strip()
  170.  
  171. if os.path.exists(tempdir):
  172. os.remove(tempdir)
  173. self.conn.send(('250 ' + msg[4:].strip() + ' deleted.\r\n').encode('utf-8'))
  174. else:
  175. self.conn.send(('550 Unable to delete file.\r\n').encode('utf-8'))
  176.  
  177. def PORT(self,msg):
  178. address = msg.split(',')
  179. #msg comes in the form of ip,ip,ip,ip,port,port
  180. #according to google to transform the last two numbers
  181. #into the actual port you need to muliply the first port
  182. #number by 2^8 (256) and then add the second port number
  183. self.transport = (int(address[4]))*256+int(address[5])
  184. self.conn.send(('200 Okay.\r\n').encode('utf-8'))
  185.  
  186. #MODE, TYPE and STRU are sometimes called during get
  187. #and put they were mentioned in the provided rfc document
  188. #so I added the functions and sent the 200 to the client
  189. #to prevent any hangups or errors.
  190. def MODE(self,msg):
  191. self.conn.send(('200 Okay.\r\n').encode('utf-8'))
  192.  
  193. def TYPE(self,msg):
  194. self.conn.send(('200 Okay.\r\n').encode('utf-8'))
  195.  
  196. def STRU(self,msg):
  197. self.conn.send(('200 Okay.\r\n').encode('utf-8'))
  198.  
  199. def STOR(self,msg):
  200. if self.workingdir.endswith('\\') or self.workingdir.endswith('/'):
  201. tempdir = self.workingdir + msg[4:].strip()
  202. elif self.workingdir.startswith('C'):
  203. tempdir = self.workingdir + '\\'+msg[4:].strip()
  204. else:
  205. tempdir = self.workingdir +'/'+ msg[4:].strip()
  206.  
  207. f=open(tempdir,'wb')
  208. #150 File status okay; about to open data connection.
  209. self.conn.send(('150 About to open data connection.\r\n').encode('utf-8'))
  210. dataconn=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  211. dataconn.connect((host,self.transport))
  212. data=dataconn.recv(1024)
  213. while data:
  214. f.write(data)
  215. data=dataconn.recv(1024)
  216. f.close()
  217. dataconn.close()
  218. #226 Closing data connection.
  219. #Requested file action successful (for example, file
  220. #transfer or file abort).
  221. self.conn.send(('226 File stored on server.\r\n').encode('utf-8'))
  222.  
  223. def RETR(self,msg):
  224. if self.workingdir.endswith('\\') or self.workingdir.endswith('/'):
  225. tempdir = self.workingdir + msg[4:].strip()
  226. elif self.workingdir.startswith('C'):
  227. tempdir = self.workingdir + '\\'+msg[4:].strip()
  228. else:
  229. tempdir = self.workingdir +'/'+ msg[4:].strip()
  230.  
  231. f=open(tempdir,'rb')
  232. #150 File status okay; about to open data connection.
  233. self.conn.send(('150 About to open data connection.\r\n').encode('utf-8'))
  234. dataconn=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  235. dataconn.connect((host,self.transport))
  236. data=f.read(1024)
  237. while data:
  238. dataconn.send(data)
  239. data=f.read(1024)
  240. f.close()
  241. dataconn.close()
  242. #226 Closing data connection.
  243. #Requested file action successful (for example, file
  244. #transfer or file abort).
  245. self.conn.send(('226 File downloaded.\r\n').encode('utf-8'))
  246.  
  247. def QUIT(self,msg):
  248. #221 Service closing control connection.
  249. #Logged out if appropriate.
  250. self.conn.send(('221 Exiting.\r\n').encode('utf-8'))
  251.  
  252. #main
  253. if __name__=='__main__':
  254. host = '127.0.0.1'
  255. try:
  256. port = int(sys.argv[1])
  257. except Exception:
  258. print("No port provided, defaulting to port 8000")
  259. port = 8000
  260. print("IP: ", host, " Port: ", port)
  261. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  262. s.bind((host,port))
  263. s.listen(5)
  264. while 1:
  265. #every connection is a thread to allow multiple connections
  266. connection=Connection(s.accept())
  267. connection.daemon=True
  268. connection.start()
  269. s.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement