comparison OrthancServer/Internals/CommandDispatcher.cpp @ 620:4aa6f0d79947 find-move-scp

security filter for dicom requests
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 25 Oct 2013 12:36:00 +0200
parents 273e7ad98ea9
children d233b5090105
comparison
equal deleted inserted replaced
619:70d0f27e5bd3 620:4aa6f0d79947
324 LOG(INFO) << cond.text(); 324 LOG(INFO) << cond.text();
325 } 325 }
326 AssociationCleanup(assoc); 326 AssociationCleanup(assoc);
327 return NULL; 327 return NULL;
328 } 328 }
329
330 std::string callingIP;
331 std::string callingTitle;
329 332
330 /* check the AETs */ 333 /* check the AETs */
331 { 334 {
332 DIC_AE callingTitle_C; 335 DIC_AE callingTitle_C;
333 DIC_AE calledTitle_C; 336 DIC_AE calledTitle_C;
345 ASC_rejectAssociation(assoc, &rej); 348 ASC_rejectAssociation(assoc, &rej);
346 AssociationCleanup(assoc); 349 AssociationCleanup(assoc);
347 return NULL; 350 return NULL;
348 } 351 }
349 352
350 std::string callingIP(/*OFSTRING_GUARD*/(callingIP_C)); 353 callingIP = std::string(/*OFSTRING_GUARD*/(callingIP_C));
351 std::string callingTitle(/*OFSTRING_GUARD*/(callingTitle_C)); 354 callingTitle = std::string(/*OFSTRING_GUARD*/(callingTitle_C));
352 std::string calledTitle(/*OFSTRING_GUARD*/(calledTitle_C)); 355 std::string calledTitle(/*OFSTRING_GUARD*/(calledTitle_C));
353 Toolbox::ToUpperCase(callingIP); 356 Toolbox::ToUpperCase(callingIP);
354 Toolbox::ToUpperCase(callingTitle); 357 Toolbox::ToUpperCase(callingTitle);
355 Toolbox::ToUpperCase(calledTitle); 358 Toolbox::ToUpperCase(calledTitle);
356 359
367 AssociationCleanup(assoc); 370 AssociationCleanup(assoc);
368 return NULL; 371 return NULL;
369 } 372 }
370 373
371 if (server.HasApplicationEntityFilter() && 374 if (server.HasApplicationEntityFilter() &&
372 !server.GetApplicationEntityFilter().IsAllowed(callingIP, callingTitle)) 375 !server.GetApplicationEntityFilter().IsAllowedConnection(callingIP, callingTitle))
373 { 376 {
374 T_ASC_RejectParameters rej = 377 T_ASC_RejectParameters rej =
375 { 378 {
376 ASC_RESULT_REJECTEDPERMANENT, 379 ASC_RESULT_REJECTEDPERMANENT,
377 ASC_SOURCE_SERVICEUSER, 380 ASC_SOURCE_SERVICEUSER,
414 LOG(INFO) << "Association Acknowledged (Max Send PDV: " << assoc->sendPDVLength << ")"; 417 LOG(INFO) << "Association Acknowledged (Max Send PDV: " << assoc->sendPDVLength << ")";
415 if (ASC_countAcceptedPresentationContexts(assoc->params) == 0) 418 if (ASC_countAcceptedPresentationContexts(assoc->params) == 0)
416 LOG(INFO) << " (but no valid presentation contexts)"; 419 LOG(INFO) << " (but no valid presentation contexts)";
417 } 420 }
418 421
419 return new CommandDispatcher(server, assoc); 422 IApplicationEntityFilter* filter = server.HasApplicationEntityFilter() ? &server.GetApplicationEntityFilter() : NULL;
423 return new CommandDispatcher(server, assoc, callingIP, callingTitle, filter);
420 } 424 }
421 425
422 bool CommandDispatcher::Step() 426 bool CommandDispatcher::Step()
423 /* 427 /*
424 * This function receives DIMSE commmands over the network connection 428 * This function receives DIMSE commmands over the network connection
461 else if (cond == EC_Normal) 465 else if (cond == EC_Normal)
462 { 466 {
463 // Reset the client timeout counter 467 // Reset the client timeout counter
464 elapsedTimeSinceLastCommand_ = 0; 468 elapsedTimeSinceLastCommand_ = 0;
465 469
466 // in case we received a valid message, process this command 470 // Convert the type of request to Orthanc's internal type
467 // note that storescp can only process a C-ECHO-RQ and a C-STORE-RQ 471 bool supported = false;
472 DicomRequestType request;
468 switch (msg.CommandField) 473 switch (msg.CommandField)
469 { 474 {
470 case DIMSE_C_ECHO_RQ: 475 case DIMSE_C_ECHO_RQ:
471 // process C-ECHO-Request 476 request = DicomRequestType_Echo;
472 cond = EchoScp(assoc_, &msg, presID); 477 supported = true;
473 break; 478 break;
474 479
475 case DIMSE_C_STORE_RQ: 480 case DIMSE_C_STORE_RQ:
476 // process C-STORE-Request 481 request = DicomRequestType_Store;
477 if (server_.HasStoreRequestHandlerFactory()) 482 supported = true;
483 break;
484
485 case DIMSE_C_MOVE_RQ:
486 request = DicomRequestType_Move;
487 supported = true;
488 break;
489
490 case DIMSE_C_FIND_RQ:
491 request = DicomRequestType_Find;
492 supported = true;
493 break;
494
495 default:
496 // we cannot handle this kind of message
497 cond = DIMSE_BADCOMMANDTYPE;
498 LOG(ERROR) << "cannot handle command: 0x" << std::hex << msg.CommandField;
499 break;
500 }
501
502
503 // Check whether this request is allowed by the security filter
504 if (supported &&
505 filter_ != NULL &&
506 !filter_->IsAllowedRequest(callingIP_, callingAETitle_, request))
507 {
508 LOG(ERROR) << EnumerationToString(request)
509 << " requests are disallowed for the AET \""
510 << callingAETitle_ << "\"";
511 cond = DIMSE_BADCOMMANDTYPE;
512 supported = false;
513 }
514
515 // in case we received a supported message, process this command
516 if (supported)
517 {
518 // If anything goes wrong, there will be a "BADCOMMANDTYPE" answer
519 cond = DIMSE_BADCOMMANDTYPE;
520
521 switch (request)
478 { 522 {
479 std::auto_ptr<IStoreRequestHandler> handler 523 case DicomRequestType_Echo:
480 (server_.GetStoreRequestHandlerFactory().ConstructStoreRequestHandler()); 524 cond = EchoScp(assoc_, &msg, presID);
481 cond = Internals::storeScp(assoc_, &msg, presID, *handler); 525 break;
526
527 case DicomRequestType_Store:
528 if (server_.HasStoreRequestHandlerFactory()) // Should always be true
529 {
530 std::auto_ptr<IStoreRequestHandler> handler
531 (server_.GetStoreRequestHandlerFactory().ConstructStoreRequestHandler());
532 cond = Internals::storeScp(assoc_, &msg, presID, *handler);
533 }
534 break;
535
536 case DicomRequestType_Move:
537 if (server_.HasMoveRequestHandlerFactory()) // Should always be true
538 {
539 std::auto_ptr<IMoveRequestHandler> handler
540 (server_.GetMoveRequestHandlerFactory().ConstructMoveRequestHandler());
541 cond = Internals::moveScp(assoc_, &msg, presID, *handler);
542 }
543 break;
544
545 case DicomRequestType_Find:
546 if (server_.HasFindRequestHandlerFactory()) // Should always be true
547 {
548 std::auto_ptr<IFindRequestHandler> handler
549 (server_.GetFindRequestHandlerFactory().ConstructFindRequestHandler());
550 cond = Internals::findScp(assoc_, &msg, presID, *handler);
551 }
552 break;
553
554 default:
555 // Should never happen
556 break;
482 } 557 }
483 else
484 cond = DIMSE_BADCOMMANDTYPE; // Should never happen
485 break;
486
487 case DIMSE_C_MOVE_RQ:
488 // process C-MOVE-Request
489 if (server_.HasMoveRequestHandlerFactory())
490 {
491 std::auto_ptr<IMoveRequestHandler> handler
492 (server_.GetMoveRequestHandlerFactory().ConstructMoveRequestHandler());
493 cond = Internals::moveScp(assoc_, &msg, presID, *handler);
494 }
495 else
496 cond = DIMSE_BADCOMMANDTYPE; // Should never happen
497 break;
498
499 case DIMSE_C_FIND_RQ:
500 // process C-FIND-Request
501 if (server_.HasFindRequestHandlerFactory())
502 {
503 std::auto_ptr<IFindRequestHandler> handler
504 (server_.GetFindRequestHandlerFactory().ConstructFindRequestHandler());
505 cond = Internals::findScp(assoc_, &msg, presID, *handler);
506 }
507 else
508 cond = DIMSE_BADCOMMANDTYPE; // Should never happen
509 break;
510
511 default:
512 // we cannot handle this kind of message
513 cond = DIMSE_BADCOMMANDTYPE;
514 LOG(ERROR) << "cannot handle command: 0x" << std::hex << msg.CommandField;
515 break;
516 } 558 }
517 } 559 }
518 else 560 else
519 { 561 {
520 // Bad status, which indicates the closing of the connection by 562 // Bad status, which indicates the closing of the connection by