comparison Core/HttpServer/MongooseServer.cpp @ 34:96e57b863dd9

option to disallow remote access
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 30 Aug 2012 11:22:21 +0200
parents dd1489098265
children 9be852ad33d2
comparison
equal deleted inserted replaced
32:0c3e317f35e8 34:96e57b863dd9
36 #include "mongoose.h" 36 #include "mongoose.h"
37 37
38 38
39 #define PALANTIR_REALM "Palantir Secure Area" 39 #define PALANTIR_REALM "Palantir Secure Area"
40 40
41 static const long LOCALHOST = (127ll << 24) + 1ll;
42
41 43
42 namespace Palantir 44 namespace Palantir
43 { 45 {
44 static const char multipart[] = "multipart/form-data; boundary="; 46 static const char multipart[] = "multipart/form-data; boundary=";
45 static unsigned int multipartLength = sizeof(multipart) / sizeof(char) - 1; 47 static unsigned int multipartLength = sizeof(multipart) / sizeof(char) - 1;
395 397
396 return PostDataStatus_Pending; 398 return PostDataStatus_Pending;
397 } 399 }
398 400
399 401
402 static void SendUnauthorized(HttpOutput& output)
403 {
404 std::string s = "HTTP/1.1 401 Unauthorized\r\n"
405 "WWW-Authenticate: Basic realm=\"" PALANTIR_REALM "\""
406 "\r\n\r\n";
407 output.Send(&s[0], s.size());
408 }
409
410
400 static bool Authorize(const MongooseServer& that, 411 static bool Authorize(const MongooseServer& that,
401 const HttpHandler::Arguments& headers, 412 const HttpHandler::Arguments& headers,
402 HttpOutput& output) 413 HttpOutput& output)
403 { 414 {
404 bool granted = false; 415 bool granted = false;
414 } 425 }
415 } 426 }
416 427
417 if (!granted) 428 if (!granted)
418 { 429 {
419 std::string s = "HTTP/1.1 401 Unauthorized\r\n" 430 SendUnauthorized(output);
420 "WWW-Authenticate: Basic realm=\"" PALANTIR_REALM "\""
421 "\r\n\r\n";
422 output.Send(&s[0], s.size());
423 return false; 431 return false;
424 } 432 }
425 else 433 else
426 { 434 {
427 return true; 435 return true;
435 const struct mg_request_info *request) 443 const struct mg_request_info *request)
436 { 444 {
437 if (event == MG_NEW_REQUEST) 445 if (event == MG_NEW_REQUEST)
438 { 446 {
439 MongooseServer* that = (MongooseServer*) (request->user_data); 447 MongooseServer* that = (MongooseServer*) (request->user_data);
448 MongooseOutput output(connection);
449
450 if (!that->IsRemoteAccessAllowed() &&
451 request->remote_ip != LOCALHOST)
452 {
453 SendUnauthorized(output);
454 return (void*) "";
455 }
440 456
441 HttpHandler::Arguments arguments, headers; 457 HttpHandler::Arguments arguments, headers;
442 MongooseOutput c(connection);
443 458
444 for (int i = 0; i < request->num_headers; i++) 459 for (int i = 0; i < request->num_headers; i++)
445 { 460 {
446 std::string name = request->http_headers[i].name; 461 std::string name = request->http_headers[i].name;
447 std::transform(name.begin(), name.end(), name.begin(), ::tolower); 462 std::transform(name.begin(), name.end(), name.begin(), ::tolower);
448 headers.insert(std::make_pair(name, request->http_headers[i].value)); 463 headers.insert(std::make_pair(name, request->http_headers[i].value));
449 } 464 }
450 465
451 // Authenticate this connection 466 // Authenticate this connection
452 if (that->IsAuthenticationEnabled() && 467 if (that->IsAuthenticationEnabled() &&
453 !Authorize(*that, headers, c)) 468 !Authorize(*that, headers, output))
454 { 469 {
455 return (void*) ""; 470 return (void*) "";
456 } 471 }
457 472
458 std::string postData; 473 std::string postData;
464 else if (!strcmp(request->request_method, "POST")) 479 else if (!strcmp(request->request_method, "POST"))
465 { 480 {
466 HttpHandler::Arguments::const_iterator ct = headers.find("content-type"); 481 HttpHandler::Arguments::const_iterator ct = headers.find("content-type");
467 if (ct == headers.end()) 482 if (ct == headers.end())
468 { 483 {
469 c.SendHeader(HttpStatus_400_BadRequest); 484 output.SendHeader(HttpStatus_400_BadRequest);
470 return (void*) ""; 485 return (void*) "";
471 } 486 }
472 487
473 PostDataStatus status; 488 PostDataStatus status;
474 489
484 } 499 }
485 500
486 switch (status) 501 switch (status)
487 { 502 {
488 case PostDataStatus_NoLength: 503 case PostDataStatus_NoLength:
489 c.SendHeader(HttpStatus_411_LengthRequired); 504 output.SendHeader(HttpStatus_411_LengthRequired);
490 return (void*) ""; 505 return (void*) "";
491 506
492 case PostDataStatus_Failure: 507 case PostDataStatus_Failure:
493 c.SendHeader(HttpStatus_400_BadRequest); 508 output.SendHeader(HttpStatus_400_BadRequest);
494 return (void*) ""; 509 return (void*) "";
495 510
496 case PostDataStatus_Pending: 511 case PostDataStatus_Pending:
497 c.AnswerBuffer(""); 512 output.AnswerBuffer("");
498 return (void*) ""; 513 return (void*) "";
499 514
500 default: 515 default:
501 break; 516 break;
502 } 517 }
508 HttpHandler* handler = that->FindHandler(uri); 523 HttpHandler* handler = that->FindHandler(uri);
509 if (handler) 524 if (handler)
510 { 525 {
511 try 526 try
512 { 527 {
513 handler->Handle(c, std::string(request->request_method), 528 handler->Handle(output, std::string(request->request_method),
514 uri, headers, arguments, postData); 529 uri, headers, arguments, postData);
515 } 530 }
516 catch (PalantirException& e) 531 catch (PalantirException& e)
517 { 532 {
518 std::cerr << "MongooseServer Exception [" << e.What() << "]" << std::endl; 533 std::cerr << "MongooseServer Exception [" << e.What() << "]" << std::endl;
519 c.SendHeader(HttpStatus_500_InternalServerError); 534 output.SendHeader(HttpStatus_500_InternalServerError);
520 } 535 }
521 } 536 }
522 else 537 else
523 { 538 {
524 c.SendHeader(HttpStatus_404_NotFound); 539 output.SendHeader(HttpStatus_404_NotFound);
525 } 540 }
526 541
527 // Mark as processed 542 // Mark as processed
528 return (void*) ""; 543 return (void*) "";
529 } 544 }
541 556
542 557
543 MongooseServer::MongooseServer() : pimpl_(new PImpl) 558 MongooseServer::MongooseServer() : pimpl_(new PImpl)
544 { 559 {
545 pimpl_->context_ = NULL; 560 pimpl_->context_ = NULL;
561 remoteAllowed_ = false;
546 authentication_ = false; 562 authentication_ = false;
547 ssl_ = false; 563 ssl_ = false;
548 port_ = 8000; 564 port_ = 8000;
549 } 565 }
550 566
662 { 678 {
663 Stop(); 679 Stop();
664 certificate_ = path; 680 certificate_ = path;
665 } 681 }
666 682
683 void MongooseServer::SetRemoteAccessAllowed(bool allowed)
684 {
685 Stop();
686 remoteAllowed_ = allowed;
687 }
688
689
667 bool MongooseServer::IsValidBasicHttpAuthentication(const std::string& basic) const 690 bool MongooseServer::IsValidBasicHttpAuthentication(const std::string& basic) const
668 { 691 {
669 return registeredUsers_.find(basic) != registeredUsers_.end(); 692 return registeredUsers_.find(basic) != registeredUsers_.end();
670 } 693 }
671 } 694 }