Mercurial > hg > orthanc
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 } |