{"action":"closed","number":6692,"pull_request":{"url":"https://api.github.com/repos/rapid7/metasploit-framework/pulls/6692","id":63528955,"html_url":"https://github.com/rapid7/metasploit-framework/pull/6692","diff_url":"https://github.com/rapid7/metasploit-framework/pull/6692.diff","patch_url":"https://github.com/rapid7/metasploit-framework/pull/6692.patch","issue_url":"https://api.github.com/repos/rapid7/metasploit-framework/issues/6692","number":6692,"state":"closed","locked":false,"title":"Implement consistent socket abstraction","user":{"login":"sempervictus","id":1331084,"avatar_url":"https://avatars.githubusercontent.com/u/1331084?v=3","gravatar_id":"","url":"https://api.github.com/users/sempervictus","html_url":"https://github.com/sempervictus","followers_url":"https://api.github.com/users/sempervictus/followers","following_url":"https://api.github.com/users/sempervictus/following{/other_user}","gists_url":"https://api.github.com/users/sempervictus/gists{/gist_id}","starred_url":"https://api.github.com/users/sempervictus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sempervictus/subscriptions","organizations_url":"https://api.github.com/users/sempervictus/orgs","repos_url":"https://api.github.com/users/sempervictus/repos","events_url":"https://api.github.com/users/sempervictus/events{/privacy}","received_events_url":"https://api.github.com/users/sempervictus/received_events","type":"User","site_admin":false},"body":"Background:\r\n\r\nIn current nomenclature, Rex Sockets are objects created by calls\r\nto Rex::Socket::[Transport].create and Rex::Socket.create_...\r\nWhen the LocalHost or Comm parameters are set to remotely routed\r\naddresses (currently via Meterpreter sessions), Rex will create a\r\nChannel which will abstract communications with the remote end of\r\nthe session. These channel based abstractions are called pivots,\r\nand present in three separate flavors:\r\n1 - TcpClientChannel, a fully abstracted, selectable Socket.\r\n2 - TcpServerChannel, a virtual Channel which distributes client\r\nchannels.\r\n3 - UdpChannel, a virtual Channel which provides common methods for\r\nUDP socket operations, but is not a full (selectable) abstraction.\r\n\r\nUnfortunately this differentiation results in inconsistent returns\r\nfrom the aforementioned socket creation calls, as the call chain\r\ncreates parameters and supplies them to the create method on the\r\ncomm object referenced in the params. The comm object may be a\r\nchannel, and produce a virtual representation of a socket with\r\nfunctional methods analogous to Sockets, but without a kernel FD.\r\n\r\nThis commit begins the work of ensuring that all calls for socket\r\ncreation return selectable Rex::Socket objects with semantics\r\nfamiliar to Ruby developers who have not read into the details of\r\nRex::Socket and Rex::Post.\r\n\r\n-----\r\n\r\nSummary of changes:\r\n\r\nConvert Rex::IO::StreamAbstraction to SocketAbstraction and use\r\nthe new mixin in StreamAbstraction and DatagramAbstraction. This\r\napproach allows for common methods to reuse the abstraction data\r\nflow, while initializing separate types of socket obects and an\r\noptional monitor as needed.\r\n\r\nIn the Rex::Post::Meterpreter namespace, extract common methods\r\nfrom Stream to a SocketAbstraction mixin, include that mixin in\r\nStream, and add Datagram with the dio_write handler override\r\nexported from the current implementation of UdpChannel, also using\r\nthe mixin. This relies on the Rex::IO work above to implement the\r\nproper type of socket abstraction to the Channel descendants.\r\n\r\nIn Rex::Post::Meterpreter::Extensions::Stdapi::Net, convert the\r\nUdpChannel to inherit from the Rex::Post::Meterpreter::Datagram\r\nclass, implementing only the send method at this tier. Convert\r\ncreate_udp_channel to return the local socket side of the datagram\r\nabstraction presented analogous to the TcpClientChannel approach\r\nused before.\r\n\r\n-----\r\n\r\nNotes and intricacies:\r\n\r\nIn order to implement recvfrom on the UDP abstraction, a shim layer\r\nhas been put in place to forward the sockaddr information from the\r\nremote peer to the local UDP socketpair in the abstraction. This\r\ninformation takes up buffer space in the UDP socket, and in order\r\nto maintain compatibility with consumers, the dio_write_handler\r\npushes the data buffer, and in a separate send call, he sockaddr\r\ninformation from the remote socket. On the abstraction side, the\r\nrecvfrom_nonblock call of the real UDPSocket has been overriden\r\nvia the mixed in module to call the real method twice, once for\r\nthe data buffer, and once for the packed sockaddr data. The Rex\r\nlevel consumer for recvfrom calls the underlying nonblock method\r\nand expects this exact set of returns (as opposed to what standard\r\nlibrary UDPSocket.recvfrom returns, which is a data buffer and an\r\nArray of sockaddr data).\r\n\r\n-----\r\n\r\nTesting:\r\n  Local and lab testing only so far.\r\n  Test RC script to be added in GH comments.\r\n\r\n-----\r\n\r\nIssues:\r\n  RESOLVED - Currently, sendto on a remote socket does not appear\r\nto honor LocalPort which causes DNS responses (#6611) to come\r\nfrom the wrong port to remote clients being serviced over a pivot socket. ","created_at":"2016-03-21T07:35:20Z","updated_at":"2016-03-25T18:06:41Z","closed_at":"2016-03-25T18:06:41Z","merged_at":"2016-03-25T18:06:41Z","merge_commit_sha":"c871ceea0a55cf92142f0bf066abe6dbf68205d2","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rapid7/metasploit-framework/pulls/6692/commits","review_comments_url":"https://api.github.com/repos/rapid7/metasploit-framework/pulls/6692/comments","review_comment_url":"https://api.github.com/repos/rapid7/metasploit-framework/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rapid7/metasploit-framework/issues/6692/comments","statuses_url":"https://api.github.com/repos/rapid7/metasploit-framework/statuses/c871ceea0a55cf92142f0bf066abe6dbf68205d2","head":{"label":"sempervictus:feature-selectable_socket_abstractions","ref":"feature-selectable_socket_abstractions","sha":"c871ceea0a55cf92142f0bf066abe6dbf68205d2","user":{"login":"sempervictus","id":1331084,"avatar_url":"https://avatars.githubusercontent.com/u/1331084?v=3","gravatar_id":"","url":"https://api.github.com/users/sempervictus","html_url":"https://github.com/sempervictus","followers_url":"https://api.github.com/users/sempervictus/followers","following_url":"https://api.github.com/users/sempervictus/following{/other_user}","gists_url":"https://api.github.com/users/sempervictus/gists{/gist_id}","starred_url":"https://api.github.com/users/sempervictus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sempervictus/subscriptions","organizations_url":"https://api.github.com/users/sempervictus/orgs","repos_url":"https://api.github.com/users/sempervictus/repos","events_url":"https://api.github.com/users/sempervictus/events{/privacy}","received_events_url":"https://api.github.com/users/sempervictus/received_events","type":"User","site_admin":false},"repo":{"id":3182335,"name":"metasploit-framework","full_name":"sempervictus/metasploit-framework","owner":{"login":"sempervictus","id":1331084,"avatar_url":"https://avatars.githubusercontent.com/u/1331084?v=3","gravatar_id":"","url":"https://api.github.com/users/sempervictus","html_url":"https://github.com/sempervictus","followers_url":"https://api.github.com/users/sempervictus/followers","following_url":"https://api.github.com/users/sempervictus/following{/other_user}","gists_url":"https://api.github.com/users/sempervictus/gists{/gist_id}","starred_url":"https://api.github.com/users/sempervictus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sempervictus/subscriptions","organizations_url":"https://api.github.com/users/sempervictus/orgs","repos_url":"https://api.github.com/users/sempervictus/repos","events_url":"https://api.github.com/users/sempervictus/events{/privacy}","received_events_url":"https://api.github.com/users/sempervictus/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sempervictus/metasploit-framework","description":"Metasploit Framework","fork":true,"url":"https://api.github.com/repos/sempervictus/metasploit-framework","forks_url":"https://api.github.com/repos/sempervictus/metasploit-framework/forks","keys_url":"https://api.github.com/repos/sempervictus/metasploit-framework/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sempervictus/metasploit-framework/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sempervictus/metasploit-framework/teams","hooks_url":"https://api.github.com/repos/sempervictus/metasploit-framework/hooks","issue_events_url":"https://api.github.com/repos/sempervictus/metasploit-framework/issues/events{/number}","events_url":"https://api.github.com/repos/sempervictus/metasploit-framework/events","assignees_url":"https://api.github.com/repos/sempervictus/metasploit-framework/assignees{/user}","branches_url":"https://api.github.com/repos/sempervictus/metasploit-framework/branches{/branch}","tags_url":"https://api.github.com/repos/sempervictus/metasploit-framework/tags","blobs_url":"https://api.github.com/repos/sempervictus/metasploit-framework/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sempervictus/metasploit-framework/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sempervictus/metasploit-framework/git/refs{/sha}","trees_url":"https://api.github.com/repos/sempervictus/metasploit-framework/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sempervictus/metasploit-framework/statuses/{sha}","languages_url":"https://api.github.com/repos/sempervictus/metasploit-framework/languages","stargazers_url":"https://api.github.com/repos/sempervictus/metasploit-framework/stargazers","contributors_url":"https://api.github.com/repos/sempervictus/metasploit-framework/contributors","subscribers_url":"https://api.github.com/repos/sempervictus/metasploit-framework/subscribers","subscription_url":"https://api.github.com/repos/sempervictus/metasploit-framework/subscription","commits_url":"https://api.github.com/repos/sempervictus/metasploit-framework/commits{/sha}","git_commits_url":"https://api.github.com/repos/sempervictus/metasploit-framework/git/commits{/sha}","comments_url":"https://api.github.com/repos/sempervictus/metasploit-framework/comments{/number}","issue_comment_url":"https://api.github.com/repos/sempervictus/metasploit-framework/issues/comments{/number}","contents_url":"https://api.github.com/repos/sempervictus/metasploit-framework/contents/{+path}","compare_url":"https://api.github.com/repos/sempervictus/metasploit-framework/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sempervictus/metasploit-framework/merges","archive_url":"https://api.github.com/repos/sempervictus/metasploit-framework/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sempervictus/metasploit-framework/downloads","issues_url":"https://api.github.com/repos/sempervictus/metasploit-framework/issues{/number}","pulls_url":"https://api.github.com/repos/sempervictus/metasploit-framework/pulls{/number}","milestones_url":"https://api.github.com/repos/sempervictus/metasploit-framework/milestones{/number}","notifications_url":"https://api.github.com/repos/sempervictus/metasploit-framework/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sempervictus/metasploit-framework/labels{/name}","releases_url":"https://api.github.com/repos/sempervictus/metasploit-framework/releases{/id}","deployments_url":"https://api.github.com/repos/sempervictus/metasploit-framework/deployments","created_at":"2012-01-15T05:45:04Z","updated_at":"2015-03-24T08:40:49Z","pushed_at":"2016-03-22T07:36:26Z","git_url":"git://github.com/sempervictus/metasploit-framework.git","ssh_url":"git@github.com:sempervictus/metasploit-framework.git","clone_url":"https://github.com/sempervictus/metasploit-framework.git","svn_url":"https://github.com/sempervictus/metasploit-framework","homepage":"http://www.metasploit.com/","size":283508,"stargazers_count":3,"watchers_count":3,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":3,"default_branch":"master"}},"base":{"label":"rapid7:master","ref":"master","sha":"6e12e74e02ce3ab0e3704e2092c789bf3f368113","user":{"login":"rapid7","id":1013671,"avatar_url":"https://avatars.githubusercontent.com/u/1013671?v=3","gravatar_id":"","url":"https://api.github.com/users/rapid7","html_url":"https://github.com/rapid7","followers_url":"https://api.github.com/users/rapid7/followers","following_url":"https://api.github.com/users/rapid7/following{/other_user}","gists_url":"https://api.github.com/users/rapid7/gists{/gist_id}","starred_url":"https://api.github.com/users/rapid7/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rapid7/subscriptions","organizations_url":"https://api.github.com/users/rapid7/orgs","repos_url":"https://api.github.com/users/rapid7/repos","events_url":"https://api.github.com/users/rapid7/events{/privacy}","received_events_url":"https://api.github.com/users/rapid7/received_events","type":"Organization","site_admin":false},"repo":{"id":2293158,"name":"metasploit-framework","full_name":"rapid7/metasploit-framework","owner":{"login":"rapid7","id":1013671,"avatar_url":"https://avatars.githubusercontent.com/u/1013671?v=3","gravatar_id":"","url":"https://api.github.com/users/rapid7","html_url":"https://github.com/rapid7","followers_url":"https://api.github.com/users/rapid7/followers","following_url":"https://api.github.com/users/rapid7/following{/other_user}","gists_url":"https://api.github.com/users/rapid7/gists{/gist_id}","starred_url":"https://api.github.com/users/rapid7/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rapid7/subscriptions","organizations_url":"https://api.github.com/users/rapid7/orgs","repos_url":"https://api.github.com/users/rapid7/repos","events_url":"https://api.github.com/users/rapid7/events{/privacy}","received_events_url":"https://api.github.com/users/rapid7/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rapid7/metasploit-framework","description":"Metasploit Framework","fork":false,"url":"https://api.github.com/repos/rapid7/metasploit-framework","forks_url":"https://api.github.com/repos/rapid7/metasploit-framework/forks","keys_url":"https://api.github.com/repos/rapid7/metasploit-framework/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rapid7/metasploit-framework/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rapid7/metasploit-framework/teams","hooks_url":"https://api.github.com/repos/rapid7/metasploit-framework/hooks","issue_events_url":"https://api.github.com/repos/rapid7/metasploit-framework/issues/events{/number}","events_url":"https://api.github.com/repos/rapid7/metasploit-framework/events","assignees_url":"https://api.github.com/repos/rapid7/metasploit-framework/assignees{/user}","branches_url":"https://api.github.com/repos/rapid7/metasploit-framework/branches{/branch}","tags_url":"https://api.github.com/repos/rapid7/metasploit-framework/tags","blobs_url":"https://api.github.com/repos/rapid7/metasploit-framework/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rapid7/metasploit-framework/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rapid7/metasploit-framework/git/refs{/sha}","trees_url":"https://api.github.com/repos/rapid7/metasploit-framework/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rapid7/metasploit-framework/statuses/{sha}","languages_url":"https://api.github.com/repos/rapid7/metasploit-framework/languages","stargazers_url":"https://api.github.com/repos/rapid7/metasploit-framework/stargazers","contributors_url":"https://api.github.com/repos/rapid7/metasploit-framework/contributors","subscribers_url":"https://api.github.com/repos/rapid7/metasploit-framework/subscribers","subscription_url":"https://api.github.com/repos/rapid7/metasploit-framework/subscription","commits_url":"https://api.github.com/repos/rapid7/metasploit-framework/commits{/sha}","git_commits_url":"https://api.github.com/repos/rapid7/metasploit-framework/git/commits{/sha}","comments_url":"https://api.github.com/repos/rapid7/metasploit-framework/comments{/number}","issue_comment_url":"https://api.github.com/repos/rapid7/metasploit-framework/issues/comments{/number}","contents_url":"https://api.github.com/repos/rapid7/metasploit-framework/contents/{+path}","compare_url":"https://api.github.com/repos/rapid7/metasploit-framework/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rapid7/metasploit-framework/merges","archive_url":"https://api.github.com/repos/rapid7/metasploit-framework/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rapid7/metasploit-framework/downloads","issues_url":"https://api.github.com/repos/rapid7/metasploit-framework/issues{/number}","pulls_url":"https://api.github.com/repos/rapid7/metasploit-framework/pulls{/number}","milestones_url":"https://api.github.com/repos/rapid7/metasploit-framework/milestones{/number}","notifications_url":"https://api.github.com/repos/rapid7/metasploit-framework/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rapid7/metasploit-framework/labels{/name}","releases_url":"https://api.github.com/repos/rapid7/metasploit-framework/releases{/id}","deployments_url":"https://api.github.com/repos/rapid7/metasploit-framework/deployments","created_at":"2011-08-30T06:13:20Z","updated_at":"2016-03-25T18:02:13Z","pushed_at":"2016-03-25T18:06:34Z","git_url":"git://github.com/rapid7/metasploit-framework.git","ssh_url":"git@github.com:rapid7/metasploit-framework.git","clone_url":"https://github.com/rapid7/metasploit-framework.git","svn_url":"https://github.com/rapid7/metasploit-framework","homepage":"http://www.metasploit.com/","size":472526,"stargazers_count":5436,"watchers_count":5436,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":3836,"mirror_url":null,"open_issues_count":287,"forks":3836,"open_issues":287,"watchers":5436,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rapid7/metasploit-framework/pulls/6692"},"html":{"href":"https://github.com/rapid7/metasploit-framework/pull/6692"},"issue":{"href":"https://api.github.com/repos/rapid7/metasploit-framework/issues/6692"},"comments":{"href":"https://api.github.com/repos/rapid7/metasploit-framework/issues/6692/comments"},"review_comments":{"href":"https://api.github.com/repos/rapid7/metasploit-framework/pulls/6692/comments"},"review_comment":{"href":"https://api.github.com/repos/rapid7/metasploit-framework/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rapid7/metasploit-framework/pulls/6692/commits"},"statuses":{"href":"https://api.github.com/repos/rapid7/metasploit-framework/statuses/c871ceea0a55cf92142f0bf066abe6dbf68205d2"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"egypt","id":287967,"avatar_url":"https://avatars.githubusercontent.com/u/287967?v=3","gravatar_id":"","url":"https://api.github.com/users/egypt","html_url":"https://github.com/egypt","followers_url":"https://api.github.com/users/egypt/followers","following_url":"https://api.github.com/users/egypt/following{/other_user}","gists_url":"https://api.github.com/users/egypt/gists{/gist_id}","starred_url":"https://api.github.com/users/egypt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/egypt/subscriptions","organizations_url":"https://api.github.com/users/egypt/orgs","repos_url":"https://api.github.com/users/egypt/repos","events_url":"https://api.github.com/users/egypt/events{/privacy}","received_events_url":"https://api.github.com/users/egypt/received_events","type":"User","site_admin":false},"comments":2,"review_comments":4,"commits":1,"additions":470,"deletions":434,"changed_files":9}}