Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: callback_server.cc

Issue 6874035: entd: require a per-entd-invocation session id in every request (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/entd.git@master
Patch Set: Allow a developer switch to disable session id' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « callback_server.h ('k') | main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "entd/callback_server.h" 5 #include "entd/callback_server.h"
6 6
7 #include <base/scoped_ptr.h> 7 #include <base/scoped_ptr.h>
8 8
9 #include "entd/entd.h" 9 #include "entd/entd.h"
10 10
11 namespace entd { 11 namespace entd {
12 12
13 using std::string; 13 using std::string;
14 14
15 std::string CallbackServer::session_id_;
16
15 namespace { 17 namespace {
16 // Max 1k request entity 18 // Max 1k request entity
17 const int kMaxRequestSize = 1024; 19 const int kMaxRequestSize = 1024;
18 20
19 // libevent defines some of these but not all, so we define what we need here 21 // libevent defines some of these but not all, so we define what we need here
20 const int kHttpOk = 200; 22 const int kHttpOk = 200;
21 const int kHttpBadRequest = 400; 23 const int kHttpBadRequest = 400;
22 const int kHttpNotFound = 404; 24 const int kHttpNotFound = 404;
23 const int kHttpBadMethod = 405; 25 const int kHttpBadMethod = 405;
24 const int kHttpBadEntitySize = 413; 26 const int kHttpBadEntitySize = 413;
25 const int kHttpBadMedia = 415; 27 const int kHttpBadMedia = 415;
26 const int kHttpServerError = 500; 28 const int kHttpServerError = 500;
27 29
28 const uint32_t kDefaultPort = 5199; // Atomic weight of Cr, sorta 30 const uint32_t kDefaultPort = 5199; // Atomic weight of Cr, sorta
29 const uint32_t kMinPort = 5000; 31 const uint32_t kMinPort = 5000;
30 const uint32_t kMaxPort = 5999; 32 const uint32_t kMaxPort = 5999;
31 33
32 // Incoming requests must have this content type 34 // Incoming requests must have this content type
33 const std::string kContentType = "application/json; charset=UTF-8"; 35 const std::string kContentType = "application/json; charset=UTF-8";
34 36
35 // Default value of request_header_value_
36 const std::string kDefaultRequestHeaderValue = "magic";
37
38 // Callback functions must have this prefix, so we can avoid dispatching 37 // Callback functions must have this prefix, so we can avoid dispatching
39 // against default properties that aren't actually intended to be callbacks. 38 // against default properties that aren't actually intended to be callbacks.
40 const std::string kCallbackPrefix = "cb:"; 39 const std::string kCallbackPrefix = "cb:";
41 40
42 // Called by libevent when it accepts an http request. 41 // Called by libevent when it accepts an http request.
43 void dispatch_OnRequest(struct evhttp_request* request, void* data) { 42 void dispatch_OnRequest(struct evhttp_request* request, void* data) {
44 CallbackServer* cbs = reinterpret_cast<CallbackServer*>(data); 43 CallbackServer* cbs = reinterpret_cast<CallbackServer*>(data);
45 cbs->SetBusy(true); 44 cbs->SetBusy(true);
46 cbs->OnRequest(request); 45 cbs->OnRequest(request);
47 cbs->SetBusy(false); 46 cbs->SetBusy(false);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 if (cs->IsBusy()) { 100 if (cs->IsBusy()) {
102 utils::ThrowV8Exception("Can't stop server while busy"); 101 utils::ThrowV8Exception("Can't stop server while busy");
103 return v8::Undefined(); 102 return v8::Undefined();
104 } 103 }
105 104
106 cs->Stop(); 105 cs->Stop();
107 106
108 return v8::Undefined(); 107 return v8::Undefined();
109 } 108 }
110 109
111 // Called by v8 when someone trys to read from callbackServer.requestHeaderValue
112 v8::Handle<v8::Value> dispatch_GetRequestHeaderValue(
113 v8::Local<v8::String> name,
114 const v8::AccessorInfo& info) {
115 CallbackServer* cs = CallbackServer::Unwrap(info.Holder());
116 return v8::String::New(cs->request_header_value().c_str());
117 }
118
119 // Called by v8 when someone trys to assign to callbackServer.requestHeaderValue
120 void dispatch_SetRequestHeaderValue(v8::Local<v8::String> name,
121 v8::Local<v8::Value> value,
122 const v8::AccessorInfo& info) {
123 CallbackServer* cs = CallbackServer::Unwrap(info.Holder());
124 cs->set_request_header_value(*v8::String::Utf8Value(value));
125 }
126
127 } // namespace 110 } // namespace
128 111
129 std::string CallbackServer::required_origin = ""; 112 std::string CallbackServer::required_origin = "";
130 113
131 CallbackServer::CallbackServer(Entd* entd) 114 CallbackServer::CallbackServer(Entd* entd)
132 : busy_(false), 115 : busy_(false),
133 entd_(entd), 116 entd_(entd),
134 request_header_value_(kDefaultRequestHeaderValue),
135 evhttp_(NULL) 117 evhttp_(NULL)
136 {} 118 {}
137 119
138 CallbackServer::~CallbackServer() { 120 CallbackServer::~CallbackServer() {
139 CleanupTemplate(); 121 CleanupTemplate();
140 Stop(); 122 Stop();
141 } 123 }
142 124
143 // static 125 // static
144 void CallbackServer::SetTemplateBindings( 126 void CallbackServer::SetTemplateBindings(
145 v8::Handle<v8::ObjectTemplate> template_object) { 127 v8::Handle<v8::ObjectTemplate> template_object) {
146 template_object->Set(v8::String::NewSymbol("start"), 128 template_object->Set(v8::String::NewSymbol("start"),
147 v8::FunctionTemplate::New(dispatch_Start)); 129 v8::FunctionTemplate::New(dispatch_Start));
148 template_object->Set(v8::String::NewSymbol("stop"), 130 template_object->Set(v8::String::NewSymbol("stop"),
149 v8::FunctionTemplate::New(dispatch_Stop)); 131 v8::FunctionTemplate::New(dispatch_Stop));
150 template_object->SetAccessor(v8::String::NewSymbol("requestHeaderValue"),
151 dispatch_GetRequestHeaderValue,
152 dispatch_SetRequestHeaderValue);
153 } 132 }
154 133
155 void CallbackServer::OnRequest(struct evhttp_request* request) { 134 void CallbackServer::OnRequest(struct evhttp_request* request) {
156 const char* uri = evhttp_request_uri(request); 135 const char* uri = evhttp_request_uri(request);
157 136
158 // It might be nicer (certainly more RESTful) if the function were part 137 // It might be nicer (certainly more RESTful) if the function were part
159 // of the URI, but that would be more parsing which might add to the 138 // of the URI, but that would be more parsing which might add to the
160 // exploitability of this code. Instead we only accept requests for 139 // exploitability of this code. Instead we only accept requests for
161 // "/dispatch", and leave the parsing to v8's native JSON parser. 140 // "/dispatch", and leave the parsing to v8's native JSON parser.
162 if (strcmp("/dispatch", uri) != 0) { 141 if (strcmp("/dispatch", uri) != 0) {
(...skipping 13 matching lines...) Expand all
176 // Content type must be json. We won't be doing any form parsing, 155 // Content type must be json. We won't be doing any form parsing,
177 // multipart or otherwise. 156 // multipart or otherwise.
178 const char* header = evhttp_find_header(request->input_headers, 157 const char* header = evhttp_find_header(request->input_headers,
179 "Content-Type"); 158 "Content-Type");
180 if (!header || strcmp(kContentType.c_str(), header) != 0) { 159 if (!header || strcmp(kContentType.c_str(), header) != 0) {
181 LOG(ERROR) << "Invalid Content-Type: " << header; 160 LOG(ERROR) << "Invalid Content-Type: " << header;
182 evhttp_send_error(request, kHttpBadMedia, "Bad Content-Type"); 161 evhttp_send_error(request, kHttpBadMedia, "Bad Content-Type");
183 return; 162 return;
184 } 163 }
185 164
186 // This header must be present, since Chrome's XMLHttpRequest object 165 // Check the session ID.
187 // won't let you set an unknown header for cross domain XHR. 166 header = evhttp_find_header(request->input_headers, "X-Entd-Session-Id");
188 header = evhttp_find_header(request->input_headers, "X-Entd-Request"); 167 if (!header || header != session_id_) {
189 if (!header || strcmp(request_header_value_.c_str(), header) != 0) { 168 LOG(ERROR) << "Bad or missing X-Entd-Session-Id header: " << header;
190 LOG(ERROR) << "Bad or missing X-Entd-Request header"; 169 evhttp_send_error(request, kHttpBadRequest,
191 evhttp_send_error(request, kHttpBadRequest, "Bad X-Entd-Request header"); 170 "Bad or missing session id header");
192 return; 171 return;
193 } 172 }
194 173
195 if (!CallbackServer::required_origin.empty()) { 174 if (!CallbackServer::required_origin.empty()) {
196 header = evhttp_find_header(request->input_headers, "Origin"); 175 header = evhttp_find_header(request->input_headers, "Origin");
197 if (!header || 176 if (!header ||
198 strcmp(CallbackServer::required_origin.c_str(), header) != 0) { 177 strcmp(CallbackServer::required_origin.c_str(), header) != 0) {
199 LOG(ERROR) << "Bad or missing Origin header: " << header; 178 LOG(ERROR) << "Bad or missing Origin header: " << header;
200 evhttp_send_error(request, kHttpBadRequest, 179 evhttp_send_error(request, kHttpBadRequest,
201 "Bad or missing Origin header"); 180 "Bad or missing Origin header");
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 evhttp_ = NULL; 324 evhttp_ = NULL;
346 port_ = 0; 325 port_ = 0;
347 callbacks_.Dispose(); 326 callbacks_.Dispose();
348 } 327 }
349 328
350 bool CallbackServer::IsRunning() { 329 bool CallbackServer::IsRunning() {
351 return evhttp_ != NULL; 330 return evhttp_ != NULL;
352 } 331 }
353 332
354 } // namespace entd 333 } // namespace entd
OLDNEW
« no previous file with comments | « callback_server.h ('k') | main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698