Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add server module #1067

Merged
merged 8 commits into from
Dec 11, 2017
Merged

Add server module #1067

merged 8 commits into from
Dec 11, 2017

Conversation

devneal
Copy link
Contributor

@devneal devneal commented Nov 13, 2017

server

Adds a class pwnlib.tubes.server.server, similar to pwnlib.tubes.listen.listen, but able to accept multiple connections.

A few things worth mentioning that I'm unsure how to fix:

  • There is no way to kill the server other than using pkill
  • python -m doctest server.py hangs upon creation of the server
  • I'd like to add functionality similar to spawn_process for pwnlib.tubes.listen.listen, but I'm not sure how to best go about implementing this

h.success('Got connection from %s on port %d' % (rhost, rport))

self._accepter = context.Thread(target = accepter)
self._accepter.daemon = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be set to True.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When this is set to True, a program which only initializes a server with a callback function exits immediately rather than listen for connections. Do you know a good way to wait on the server when it is initialized as a daemon?

s = remote.readline()
remote.send(s)

if not callback:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the default argument to be a echo and move echo to the module level

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, if the callback is None, then we should just queue the sockets and pop them out of the queue wait_for_connection() a la listen.py.


r = remote(rhost, rport, sock = sock)
t = context.Thread(target = callback, args = (r,))
t.daemon = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set daemon = True

@zachriggle
Copy link
Member

Thanks for this! Overall it looks good, with only some minor tweaks necessary.

Because this is ~50% copy-pasted from listen.py, it might make sense to add this functionality to the listen class rather than a whole new one.

continue

h.status("Trying %s" % self.sockaddr[0])
listen_sock = socket.socket(self.family, self.type, self.proto)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We never set self.sock, which makes inheritance from sock behave oddly. Consider setting self.sock = listen_sock once we have the listener.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also ended up setting self.rhost and self.rport on each new connection so that closing wouldn't crash.

r"""Creates an TCP or UDP-server to listen for connections. It supports
both IPv4 and IPv6.

The callback function should take a :class:`pwnlib.tubes.remote` as
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit of documentation should go on the callback argument documentation below

return

r = remote(rhost, rport, sock = sock)
t = context.Thread(target = callback, args = (r,))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be useful to support non-threaded (i.e. blocking) callbacks via an optional argument to __init__.

@zachriggle zachriggle self-assigned this Nov 13, 2017
@devneal
Copy link
Contributor Author

devneal commented Nov 14, 2017

I'd like to keep the two modules separate until the server is ready, then see if combining the two is still feasible.

@devneal
Copy link
Contributor Author

devneal commented Nov 21, 2017

Any update on the review?

@zachriggle
Copy link
Member

zachriggle commented Nov 23, 2017 via email

@devneal
Copy link
Contributor Author

devneal commented Dec 4, 2017

Any update on this?

@zachriggle
Copy link
Member

You need to add a server.rst file like listen.rst in docs/source so that the doctests are actually executed and run. Then, the doctests need to pass :)

self.connections_waiting.set()

self._accepter = context.Thread(target = accepter)
self._accepter.daemon = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still needs to be set to True.

@devneal
Copy link
Contributor Author

devneal commented Dec 9, 2017

I've added a server.rst file, but there is no listen.rst to go off of.

@zachriggle
Copy link
Member

It looks like we actually just put them all in sockets.rst, so I was wrong about needing server.rst. Just mention the module in sockets.rst.

https://github.com/Gallopsled/pwntools/blob/dev/docs/source/tubes/sockets.rst

Thanks!

@zachriggle zachriggle merged commit ab8879a into Gallopsled:dev Dec 11, 2017
@zachriggle zachriggle added this to the 3.12.0 milestone Jan 2, 2018
Arusekk added a commit to Arusekk/pwntools that referenced this pull request Oct 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants