Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pop3testserver.py 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. #!/usr/bin/env python
  2. # -*- test-case-name: twisted.mail.test.test_pop3client -*-
  3. # Copyright (c) Twisted Matrix Laboratories.
  4. # See LICENSE for details.
  5. import sys
  6. from twisted.internet import reactor
  7. from twisted.internet.protocol import Factory
  8. from twisted.protocols import basic
  9. USER = "test"
  10. PASS = "twisted"
  11. PORT = 1100
  12. SSL_SUPPORT = True
  13. UIDL_SUPPORT = True
  14. INVALID_SERVER_RESPONSE = False
  15. INVALID_CAPABILITY_RESPONSE = False
  16. INVALID_LOGIN_RESPONSE = False
  17. DENY_CONNECTION = False
  18. DROP_CONNECTION = False
  19. BAD_TLS_RESPONSE = False
  20. TIMEOUT_RESPONSE = False
  21. TIMEOUT_DEFERRED = False
  22. SLOW_GREETING = False
  23. """Commands"""
  24. CONNECTION_MADE = b"+OK POP3 localhost v2003.83 server ready"
  25. CAPABILITIES = [b"TOP", b"LOGIN-DELAY 180", b"USER", b"SASL LOGIN"]
  26. CAPABILITIES_SSL = b"STLS"
  27. CAPABILITIES_UIDL = b"UIDL"
  28. INVALID_RESPONSE = b"-ERR Unknown request"
  29. VALID_RESPONSE = b"+OK Command Completed"
  30. AUTH_DECLINED = b"-ERR LOGIN failed"
  31. AUTH_ACCEPTED = b"+OK Mailbox open, 0 messages"
  32. TLS_ERROR = b"-ERR server side error start TLS handshake"
  33. LOGOUT_COMPLETE = b"+OK quit completed"
  34. NOT_LOGGED_IN = b"-ERR Unknown AUHORIZATION state command"
  35. STAT = b"+OK 0 0"
  36. UIDL = b"+OK Unique-ID listing follows\r\n."
  37. LIST = b"+OK Mailbox scan listing follows\r\n."
  38. CAP_START = b"+OK Capability list follows:"
  39. class POP3TestServer(basic.LineReceiver):
  40. def __init__(self, contextFactory=None):
  41. self.loggedIn = False
  42. self.caps = None
  43. self.tmpUser = None
  44. self.ctx = contextFactory
  45. def sendSTATResp(self, req):
  46. self.sendLine(STAT)
  47. def sendUIDLResp(self, req):
  48. self.sendLine(UIDL)
  49. def sendLISTResp(self, req):
  50. self.sendLine(LIST)
  51. def sendCapabilities(self):
  52. if self.caps is None:
  53. self.caps = [CAP_START]
  54. if UIDL_SUPPORT:
  55. self.caps.append(CAPABILITIES_UIDL)
  56. if SSL_SUPPORT:
  57. self.caps.append(CAPABILITIES_SSL)
  58. for cap in CAPABILITIES:
  59. self.caps.append(cap)
  60. resp = b"\r\n".join(self.caps)
  61. resp += b"\r\n."
  62. self.sendLine(resp)
  63. def connectionMade(self):
  64. if DENY_CONNECTION:
  65. self.disconnect()
  66. return
  67. if SLOW_GREETING:
  68. reactor.callLater(20, self.sendGreeting)
  69. else:
  70. self.sendGreeting()
  71. def sendGreeting(self):
  72. self.sendLine(CONNECTION_MADE)
  73. def lineReceived(self, line):
  74. """Error Conditions"""
  75. uline = line.upper()
  76. find = lambda s: uline.find(s) != -1
  77. if TIMEOUT_RESPONSE:
  78. # Do not respond to clients request
  79. return
  80. if DROP_CONNECTION:
  81. self.disconnect()
  82. return
  83. elif find(b"CAPA"):
  84. if INVALID_CAPABILITY_RESPONSE:
  85. self.sendLine(INVALID_RESPONSE)
  86. else:
  87. self.sendCapabilities()
  88. elif find(b"STLS") and SSL_SUPPORT:
  89. self.startTLS()
  90. elif find(b"USER"):
  91. if INVALID_LOGIN_RESPONSE:
  92. self.sendLine(INVALID_RESPONSE)
  93. return
  94. resp = None
  95. try:
  96. self.tmpUser = line.split(" ")[1]
  97. resp = VALID_RESPONSE
  98. except BaseException:
  99. resp = AUTH_DECLINED
  100. self.sendLine(resp)
  101. elif find(b"PASS"):
  102. resp = None
  103. try:
  104. pwd = line.split(" ")[1]
  105. if self.tmpUser is None or pwd is None:
  106. resp = AUTH_DECLINED
  107. elif self.tmpUser == USER and pwd == PASS:
  108. resp = AUTH_ACCEPTED
  109. self.loggedIn = True
  110. else:
  111. resp = AUTH_DECLINED
  112. except BaseException:
  113. resp = AUTH_DECLINED
  114. self.sendLine(resp)
  115. elif find(b"QUIT"):
  116. self.loggedIn = False
  117. self.sendLine(LOGOUT_COMPLETE)
  118. self.disconnect()
  119. elif INVALID_SERVER_RESPONSE:
  120. self.sendLine(INVALID_RESPONSE)
  121. elif not self.loggedIn:
  122. self.sendLine(NOT_LOGGED_IN)
  123. elif find(b"NOOP"):
  124. self.sendLine(VALID_RESPONSE)
  125. elif find(b"STAT"):
  126. if TIMEOUT_DEFERRED:
  127. return
  128. self.sendLine(STAT)
  129. elif find(b"LIST"):
  130. if TIMEOUT_DEFERRED:
  131. return
  132. self.sendLine(LIST)
  133. elif find(b"UIDL"):
  134. if TIMEOUT_DEFERRED:
  135. return
  136. elif not UIDL_SUPPORT:
  137. self.sendLine(INVALID_RESPONSE)
  138. return
  139. self.sendLine(UIDL)
  140. def startTLS(self):
  141. if SSL_SUPPORT and self.ctx is not None:
  142. self.sendLine(b"+OK Begin TLS negotiation now")
  143. self.transport.startTLS(self.ctx)
  144. else:
  145. self.sendLine(b"-ERR TLS not available")
  146. def disconnect(self):
  147. self.transport.loseConnection()
  148. usage = """popServer.py [arg] (default is Standard POP Server with no messages)
  149. no_ssl - Start with no SSL support
  150. no_uidl - Start with no UIDL support
  151. bad_resp - Send a non-RFC compliant response to the Client
  152. bad_cap_resp - send a non-RFC compliant response when the Client sends a 'CAPABILITY' request
  153. bad_login_resp - send a non-RFC compliant response when the Client sends a 'LOGIN' request
  154. deny - Deny the connection
  155. drop - Drop the connection after sending the greeting
  156. bad_tls - Send a bad response to a STARTTLS
  157. timeout - Do not return a response to a Client request
  158. to_deferred - Do not return a response on a 'Select' request. This
  159. will test Deferred callback handling
  160. slow - Wait 20 seconds after the connection is made to return a Server Greeting
  161. """
  162. def printMessage(msg):
  163. print("Server Starting in %s mode" % msg)
  164. def processArg(arg):
  165. if arg.lower() == "no_ssl":
  166. global SSL_SUPPORT
  167. SSL_SUPPORT = False
  168. printMessage("NON-SSL")
  169. elif arg.lower() == "no_uidl":
  170. global UIDL_SUPPORT
  171. UIDL_SUPPORT = False
  172. printMessage("NON-UIDL")
  173. elif arg.lower() == "bad_resp":
  174. global INVALID_SERVER_RESPONSE
  175. INVALID_SERVER_RESPONSE = True
  176. printMessage("Invalid Server Response")
  177. elif arg.lower() == "bad_cap_resp":
  178. global INVALID_CAPABILITY_RESPONSE
  179. INVALID_CAPABILITY_RESPONSE = True
  180. printMessage("Invalid Capability Response")
  181. elif arg.lower() == "bad_login_resp":
  182. global INVALID_LOGIN_RESPONSE
  183. INVALID_LOGIN_RESPONSE = True
  184. printMessage("Invalid Capability Response")
  185. elif arg.lower() == "deny":
  186. global DENY_CONNECTION
  187. DENY_CONNECTION = True
  188. printMessage("Deny Connection")
  189. elif arg.lower() == "drop":
  190. global DROP_CONNECTION
  191. DROP_CONNECTION = True
  192. printMessage("Drop Connection")
  193. elif arg.lower() == "bad_tls":
  194. global BAD_TLS_RESPONSE
  195. BAD_TLS_RESPONSE = True
  196. printMessage("Bad TLS Response")
  197. elif arg.lower() == "timeout":
  198. global TIMEOUT_RESPONSE
  199. TIMEOUT_RESPONSE = True
  200. printMessage("Timeout Response")
  201. elif arg.lower() == "to_deferred":
  202. global TIMEOUT_DEFERRED
  203. TIMEOUT_DEFERRED = True
  204. printMessage("Timeout Deferred Response")
  205. elif arg.lower() == "slow":
  206. global SLOW_GREETING
  207. SLOW_GREETING = True
  208. printMessage("Slow Greeting")
  209. elif arg.lower() == "--help":
  210. print(usage)
  211. sys.exit()
  212. else:
  213. print(usage)
  214. sys.exit()
  215. def main():
  216. if len(sys.argv) < 2:
  217. printMessage("POP3 with no messages")
  218. else:
  219. args = sys.argv[1:]
  220. for arg in args:
  221. processArg(arg)
  222. f = Factory()
  223. f.protocol = POP3TestServer
  224. reactor.listenTCP(PORT, f)
  225. reactor.run()
  226. if __name__ == "__main__":
  227. main()