#include "librpc/rpc/dcerpc_roh.h"
#include "librpc/rpc/dcerpc_proto.h"
#include "lib/param/param.h"
+#include "lib/http/http.h"
static ssize_t tstream_roh_pending_bytes(struct tstream_context *stream);
static struct tevent_req * tstream_roh_readv_send(
ZERO_STRUCTP(roh_stream_ctx);
roh_stream_ctx->roh_conn = talloc_move(mem_ctx, &state->roh);
- *queue = roh_stream_ctx->roh_conn->default_channel_in->send_queue;
+ *queue = http_conn_send_queue(
+ roh_stream_ctx->roh_conn->default_channel_in->http_conn);
tevent_req_received(req);
static ssize_t tstream_roh_pending_bytes(struct tstream_context *stream)
{
struct tstream_roh_context *ctx = NULL;
+ struct tstream_context *tstream = NULL;
ctx = tstream_context_data(stream, struct tstream_roh_context);
if (!ctx->roh_conn) {
return -1;
}
- return tstream_pending_bytes(ctx->roh_conn->default_channel_out->streams.active);
+ tstream = http_conn_tstream(
+ ctx->roh_conn->default_channel_out->http_conn);
+ if (stream == NULL) {
+ errno = ENOTCONN;
+ return -1;
+ }
+ return tstream_pending_bytes(tstream);
}
struct tstream_roh_readv_state {
struct tstream_roh_context *ctx = NULL;
struct tstream_roh_readv_state *state;
struct tevent_req *req, *subreq;
+ struct tstream_context *channel_stream = NULL;
req = tevent_req_create(mem_ctx, &state, struct tstream_roh_readv_state);
if (!req) {
tevent_req_error(req, ENOTCONN);
goto post;
}
- if (!ctx->roh_conn->default_channel_out->streams.active) {
+ channel_stream = http_conn_tstream(
+ ctx->roh_conn->default_channel_out->http_conn);
+ if (channel_stream == NULL) {
tevent_req_error(req, ENOTCONN);
goto post;
}
state->roh_conn = ctx->roh_conn;
subreq = tstream_readv_send(state, ev,
- ctx->roh_conn->default_channel_out->streams.active,
+ channel_stream,
vector, count);
if (tevent_req_nomem(subreq, req)) {
goto post;
struct tstream_roh_writev_state *state = NULL;
struct tevent_req *req = NULL;
struct tevent_req *subreq = NULL;
+ struct tstream_context *channel_stream = NULL;
req = tevent_req_create(mem_ctx, &state,
struct tstream_roh_writev_state);
tevent_req_error(req, ENOTCONN);
goto post;
}
- if (!ctx->roh_conn->default_channel_in->streams.active) {
+ channel_stream = http_conn_tstream(
+ ctx->roh_conn->default_channel_in->http_conn);
+ if (channel_stream == NULL) {
tevent_req_error(req, ENOTCONN);
goto post;
}
state->roh_conn = ctx->roh_conn;
subreq = tstream_writev_send(state, ev,
- ctx->roh_conn->default_channel_in->streams.active,
+ channel_stream,
vector, count);
if (tevent_req_nomem(subreq, req)) {
goto post;
tevent_req_error(req, ENOTCONN);
goto post;
}
- if (!ctx->roh_conn->default_channel_in->streams.active) {
- tevent_req_error(req, ENOTCONN);
- goto post;
- }
- subreq = tstream_disconnect_send(state, ev, ctx->roh_conn->default_channel_in->streams.active);
+ subreq = http_disconnect_send(
+ state,
+ ev,
+ ctx->roh_conn->default_channel_in->http_conn);
if (tevent_req_nomem(subreq, req)) {
goto post;
}
struct tstream_context *stream;
struct tstream_roh_context *roh_stream;
int ret;
- int sys_errno;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct tstream_roh_disconnect_state);
stream = state->stream;
roh_stream = tstream_context_data(stream, struct tstream_roh_context);
- ret = tstream_disconnect_recv(subreq, &sys_errno);
+ ret = http_disconnect_recv(subreq);
TALLOC_FREE(subreq);
- if (ret == -1) {
- tevent_req_error(req, sys_errno);
+ if (ret != 0) {
+ tevent_req_error(req, ret);
return;
}
TALLOC_FREE(roh_stream->roh_conn->default_channel_in);
- subreq = tstream_disconnect_send(state,
- state->ev,
- roh_stream->roh_conn->default_channel_out->streams.raw);
+ subreq = http_disconnect_send(
+ state,
+ state->ev,
+ roh_stream->roh_conn->default_channel_out->http_conn);
if (tevent_req_nomem(subreq, req)) {
return;
}
struct tstream_context *stream;
struct tstream_roh_context *roh_stream;
int ret;
- int sys_errno;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct tstream_roh_disconnect_state);
stream = state->stream;
roh_stream = tstream_context_data(stream, struct tstream_roh_context);
- ret = tstream_disconnect_recv(subreq, &sys_errno);
+ ret = http_disconnect_recv(subreq);
TALLOC_FREE(subreq);
- if (ret == -1) {
- tevent_req_error(req, sys_errno);
+ if (ret != 0) {
+ tevent_req_error(req, ret);
return;
}
TALLOC_FREE(roh_stream->roh_conn->default_channel_out);
struct GUID channel_cookie;
- struct tevent_queue *send_queue;
- struct {
- struct tstream_context *raw;
- struct tstream_context *tls;
- struct tstream_context *active;
- } streams;
+ struct http_conn *http_conn;
};
enum roh_protocol_version {
struct roh_connect_channel_state {
struct tevent_context *ev;
- struct tsocket_address *local_address;
- struct tsocket_address *remote_address;
struct cli_credentials *credentials;
struct roh_connection *roh;
- bool tls;
struct tstream_tls_params *tls_params;
};
bool tls,
struct tstream_tls_params *tls_params)
{
- NTSTATUS status;
struct tevent_req *req;
struct tevent_req *subreq;
struct roh_connect_channel_state *state;
- int ret;
DEBUG(8, ("%s: Connecting channel in socket, RPC proxy is %s:%d (TLS: %s)\n",
__func__, rpcproxy_ip_address, rpcproxy_port,
state->ev = ev;
state->credentials = credentials;
state->roh = roh;
- state->tls = tls;
state->tls_params = tls_params;
- ret = tsocket_address_inet_from_strings(state, "ip", NULL, 0,
- &state->local_address);
- if (ret != 0) {
- DEBUG(0, ("%s: Cannot create local socket address, error: %s (%d)\n",
- __func__, strerror(errno), errno));
- status = map_nt_error_from_unix_common(errno);
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- }
-
- ret = tsocket_address_inet_from_strings(state, "ip",
- rpcproxy_ip_address,
- rpcproxy_port,
- &state->remote_address);
- if (ret != 0) {
- DEBUG(0, ("%s: Cannot create remote socket address, error: %s (%d)\n",
- __func__, strerror(errno), errno));
- status = map_nt_error_from_unix_common(errno);
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- }
/* Initialize channel structure */
state->roh->default_channel_in = talloc_zero(roh, struct roh_channel);
return tevent_req_post(req, ev);
}
- state->roh->default_channel_in->send_queue =
- tevent_queue_create(state->roh->default_channel_in,
- "RoH IN virtual channel send queue");
- if (tevent_req_nomem(state->roh->default_channel_in->send_queue, req)) {
- return tevent_req_post(req, ev);
- }
-
state->roh->default_channel_in->channel_cookie = GUID_random();
- subreq = tstream_inet_tcp_connect_send(state, ev, state->local_address,
- state->remote_address);
+
+ subreq = http_connect_send(state,
+ ev,
+ rpcproxy_ip_address,
+ rpcproxy_port,
+ credentials,
+ tls ? tls_params : NULL);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
return req;
}
-static void roh_connect_channel_in_tls_done(struct tevent_req *subreq);
static void roh_connect_channel_in_done(struct tevent_req *subreq)
{
NTSTATUS status;
struct tevent_req *req;
struct roh_connect_channel_state *state;
- int ret;
- int sys_errno;
+ int ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct roh_connect_channel_state);
- ret = tstream_inet_tcp_connect_recv(subreq, &sys_errno, state,
- &state->roh->default_channel_in->streams.raw,
- NULL);
- talloc_steal(state->roh->default_channel_in,
- state->roh->default_channel_in->streams.raw);
- state->roh->default_channel_in->streams.active = state->roh->default_channel_in->streams.raw;
- TALLOC_FREE(subreq);
- if (ret != 0) {
- status = map_nt_error_from_unix_common(sys_errno);
- tevent_req_nterror(req, status);
- return;
- }
-
- DEBUG(8, ("%s: Socket connected\n", __func__));
- if (state->tls) {
- DEBUG(8, ("%s: Starting TLS handshake\n", __func__));
- subreq = _tstream_tls_connect_send(state,
- state->ev,
- state->roh->default_channel_in->streams.raw,
- state->tls_params,
- __location__);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, roh_connect_channel_in_tls_done, req);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static void roh_connect_channel_in_tls_done(struct tevent_req *subreq)
-{
- NTSTATUS status;
- struct tevent_req *req;
- struct roh_connect_channel_state *state;
- int ret;
- int sys_errno;
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct roh_connect_channel_state);
- ret = tstream_tls_connect_recv(subreq, &sys_errno, state,
- &state->roh->default_channel_in->streams.tls);
- talloc_steal(state->roh->default_channel_in,
- state->roh->default_channel_in->streams.tls);
- state->roh->default_channel_in->streams.active = state->roh->default_channel_in->streams.tls;
+ ret = http_connect_recv(subreq,
+ state->roh->default_channel_in,
+ &state->roh->default_channel_in->http_conn);
TALLOC_FREE(subreq);
if (ret != 0) {
- status = map_nt_error_from_unix_common(sys_errno);
+ status = map_nt_error_from_unix_common(ret);
tevent_req_nterror(req, status);
return;
}
- DEBUG(8, ("%s: TLS handshake completed\n", __func__));
+ DBG_DEBUG("HTTP connected\n");
tevent_req_done(req);
}
const char *path;
char *query;
char *uri;
+ struct tstream_context *stream = NULL;
+ struct tevent_queue *send_queue = NULL;
DEBUG(8, ("%s: Sending RPC_IN_DATA request\n", __func__));
http_add_header(state, &state->request->headers,
"Pragma", "no-cache");
+ stream = http_conn_tstream(roh->default_channel_in->http_conn);
+ send_queue = http_conn_send_queue(roh->default_channel_in->http_conn);
+
subreq = http_send_auth_request_send(state,
ev,
- roh->default_channel_in->streams.active,
- roh->default_channel_in->send_queue,
+ stream,
+ send_queue,
state->request,
credentials,
lp_ctx,
struct dcerpc_rts rts;
struct ncacn_packet pkt;
struct ndr_push *ndr;
+ struct tstream_context *stream = NULL;
+ struct tevent_queue *send_queue = NULL;
DEBUG(8, ("%s: Sending CONN/B1 request\n", __func__));
state->iov.iov_base = (char *) state->buffer.data;
state->iov.iov_len = state->buffer.length;
+ stream = http_conn_tstream(roh->default_channel_in->http_conn);
+ send_queue = http_conn_send_queue(roh->default_channel_in->http_conn);
+
subreq = tstream_writev_queue_send(mem_ctx,
ev,
- roh->default_channel_in->streams.active,
- roh->default_channel_in->send_queue,
+ stream,
+ send_queue,
&state->iov,
1);
if (tevent_req_nomem(subreq, req)) {
struct roh_connect_channel_state {
struct tevent_context *ev;
- struct tsocket_address *local_address;
- struct tsocket_address *remote_address;
struct cli_credentials *credentials;
struct roh_connection *roh;
- bool tls;
struct tstream_tls_params *tls_params;
};
bool tls,
struct tstream_tls_params *tls_params)
{
- NTSTATUS status;
struct tevent_req *req;
struct tevent_req *subreq;
struct roh_connect_channel_state *state;
- int ret;
DEBUG(8, ("%s: Connecting channel out socket, RPC proxy is %s:%d (TLS: %s)\n",
__func__, rpcproxy_ip_address, rpcproxy_port,
state->ev = ev;
state->credentials = credentials;
state->roh = roh;
- state->tls = tls;
state->tls_params = tls_params;
- ret = tsocket_address_inet_from_strings(state, "ip", NULL, 0,
- &state->local_address);
- if (ret != 0) {
- DEBUG(0, ("%s: Cannot create local socket address, error: %s (%d)\n",
- __func__, strerror(errno), errno));
- status = map_nt_error_from_unix_common(errno);
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- }
-
- ret = tsocket_address_inet_from_strings(state, "ip",
- rpcproxy_ip_address,
- rpcproxy_port,
- &state->remote_address);
- if (ret != 0) {
- DEBUG(0, ("%s: Cannot create remote socket address, error: %s (%d)\n",
- __func__, strerror(errno), errno));
- status = map_nt_error_from_unix_common(errno);
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- }
/* Initialize channel structure */
state->roh->default_channel_out = talloc_zero(roh, struct roh_channel);
return tevent_req_post(req, ev);
}
- state->roh->default_channel_out->send_queue =
- tevent_queue_create(state->roh->default_channel_out,
- "RoH OUT virtual channel send queue");
- if (tevent_req_nomem(state->roh->default_channel_out->send_queue, req)) {
- return tevent_req_post(req, ev);
- }
-
state->roh->default_channel_out->channel_cookie = GUID_random();
- subreq = tstream_inet_tcp_connect_send(state, ev, state->local_address,
- state->remote_address);
+
+ subreq = http_connect_send(state,
+ ev,
+ rpcproxy_ip_address,
+ rpcproxy_port,
+ credentials,
+ tls ? tls_params : NULL);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
return req;
}
-static void roh_connect_channel_out_tls_done(struct tevent_req *subreq);
static void roh_connect_channel_out_done(struct tevent_req *subreq)
{
- NTSTATUS status;
struct tevent_req *req;
struct roh_connect_channel_state *state;
- int ret;
- int sys_errno;
+ NTSTATUS status;
+ int ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct roh_connect_channel_state);
- ret = tstream_inet_tcp_connect_recv(subreq, &sys_errno, state,
- &state->roh->default_channel_out->streams.raw,
- NULL);
- talloc_steal(state->roh->default_channel_out,
- state->roh->default_channel_out->streams.raw);
- state->roh->default_channel_out->streams.active = state->roh->default_channel_out->streams.raw;
- TALLOC_FREE(subreq);
- if (ret != 0) {
- status = map_nt_error_from_unix_common(sys_errno);
- tevent_req_nterror(req, status);
- return;
- }
- DEBUG(8, ("%s: Socket connected\n", __func__));
- if (state->tls) {
- DEBUG(8, ("%s: Starting TLS handshake\n", __func__));
- subreq = _tstream_tls_connect_send(state,
- state->ev,
- state->roh->default_channel_out->streams.raw,
- state->tls_params,
- __location__);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, roh_connect_channel_out_tls_done, req);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static void roh_connect_channel_out_tls_done(struct tevent_req *subreq)
-{
- NTSTATUS status;
- struct tevent_req *req;
- struct roh_connect_channel_state *state;
- int ret;
- int sys_errno;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct roh_connect_channel_state);
- ret = tstream_tls_connect_recv(subreq, &sys_errno, state,
- &state->roh->default_channel_out->streams.tls);
- talloc_steal(state->roh->default_channel_out,
- state->roh->default_channel_out->streams.tls);
- state->roh->default_channel_out->streams.active = state->roh->default_channel_out->streams.tls;
+ ret = http_connect_recv(subreq,
+ state->roh->default_channel_out,
+ &state->roh->default_channel_out->http_conn);
TALLOC_FREE(subreq);
if (ret != 0) {
- status = map_nt_error_from_unix_common(sys_errno);
+ status = map_nt_error_from_unix_common(ret);
tevent_req_nterror(req, status);
return;
}
- DEBUG(8, ("%s: TLS handshake completed\n", __func__));
+ DBG_DEBUG("HTTP connected\n");
tevent_req_done(req);
}
const char *path;
char *query;
char *uri;
+ struct tstream_context *stream = NULL;
+ struct tevent_queue *send_queue = NULL;
DEBUG(8, ("%s: Sending RPC_OUT_DATA request\n", __func__));
http_add_header(state, &state->request->headers,
"Pragma", "no-cache");
+ stream = http_conn_tstream(roh->default_channel_out->http_conn);
+ send_queue = http_conn_send_queue(roh->default_channel_out->http_conn);
+
subreq = http_send_auth_request_send(state,
ev,
- roh->default_channel_out->streams.active,
- roh->default_channel_out->send_queue,
+ stream,
+ send_queue,
state->request,
credentials,
lp_ctx,
struct dcerpc_rts rts;
struct ncacn_packet pkt;
struct ndr_push *ndr;
+ struct tstream_context *stream = NULL;
+ struct tevent_queue *send_queue = NULL;
DEBUG(8, ("%s: Sending CONN/A1 request\n", __func__));
state->iov.iov_base = (char *) state->buffer.data;
state->iov.iov_len = state->buffer.length;
+ stream = http_conn_tstream(roh->default_channel_out->http_conn);
+ send_queue = http_conn_send_queue(roh->default_channel_out->http_conn);
+
subreq = tstream_writev_queue_send(mem_ctx,
ev,
- roh->default_channel_out->streams.active,
- roh->default_channel_out->send_queue,
+ stream,
+ send_queue,
&state->iov,
1);
if (tevent_req_nomem(subreq, req)) {
struct tevent_req *req;
struct tevent_req *subreq;
struct roh_recv_response_state *state;
+ struct tstream_context *stream = NULL;
DEBUG(8, ("%s: Waiting for RPC_OUT_DATA response\n", __func__));
return NULL;
}
+ stream = http_conn_tstream(roh->default_channel_out->http_conn);
+
subreq = http_read_response_send(state, ev,
- roh->default_channel_out->streams.active,
+ stream,
0); /* we'll get the content later */
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
struct tevent_req *req;
struct tevent_req *subreq;
struct roh_recv_pdu_state *state;
+ struct tstream_context *stream = NULL;
req = tevent_req_create(mem_ctx, &state, struct roh_recv_pdu_state);
if (req == NULL) {
}
DEBUG(8, ("%s: Waiting for CONN/A3\n", __func__));
- subreq = dcerpc_read_ncacn_packet_send(state, ev,
- roh->default_channel_out->streams.active);
+
+ stream = http_conn_tstream(roh->default_channel_out->http_conn);
+
+ subreq = dcerpc_read_ncacn_packet_send(state, ev, stream);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
struct tevent_req *req;
struct tevent_req *subreq;
struct roh_recv_pdu_state *state;
+ struct tstream_context *stream = NULL;
req = tevent_req_create(mem_ctx, &state, struct roh_recv_pdu_state);
if (req == NULL) {
}
DEBUG(8, ("%s: Waiting for CONN/C2\n", __func__));
- subreq = dcerpc_read_ncacn_packet_send(state, ev,
- roh->default_channel_out->streams.active);
+ stream = http_conn_tstream(roh->default_channel_out->http_conn);
+
+ subreq = dcerpc_read_ncacn_packet_send(state, ev, stream);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}