Revision 3062d395

b/lib/cli.py
2594 2594
  utils.SetupLogging(pathutils.LOG_COMMANDS, logname, debug=options.debug,
2595 2595
                     stderr_logging=True)
2596 2596

  
2597
  logging.info("Command line: %s", cmdline)
2597
  logging.debug("Command line: %s", cmdline)
2598 2598

  
2599 2599
  try:
2600 2600
    result = func(options, args)
b/lib/daemon.py
670 670
def GenericMain(daemon_name, optionparser,
671 671
                check_fn, prepare_fn, exec_fn,
672 672
                multithreaded=False, console_logging=False,
673
                default_ssl_cert=None, default_ssl_key=None):
673
                default_ssl_cert=None, default_ssl_key=None,
674
                warn_breach=False):
674 675
  """Shared main function for daemons.
675 676

  
676 677
  @type daemon_name: string
......
697 698
  @param default_ssl_cert: Default SSL certificate path
698 699
  @type default_ssl_key: string
699 700
  @param default_ssl_key: Default SSL key path
701
  @type warn_breach: bool
702
  @param warn_breach: issue a warning at daemon launch time, before
703
      daemonizing, about the possibility of breaking parameter privacy
704
      invariants through the otherwise helpful debug logging.
700 705

  
701 706
  """
702 707
  optionparser.add_option("-f", "--foreground", dest="fork",
......
800 805

  
801 806
  log_filename = constants.DAEMONS_LOGFILES[daemon_name]
802 807

  
808
  # node-daemon logging in lib/http/server.py, _HandleServerRequestInner
809
  if options.debug and warn_breach:
810
    sys.stderr.write(constants.DEBUG_MODE_CONFIDENTIALITY_WARNING % daemon_name)
811

  
803 812
  if options.fork:
804 813
    utils.CloseFDs()
805 814
    (wpipe, stdio_reopen_fn) = utils.Daemonize(logfile=log_filename)
b/lib/server/noded.py
1297 1297
  daemon.GenericMain(constants.NODED, parser, CheckNoded, PrepNoded, ExecNoded,
1298 1298
                     default_ssl_cert=pathutils.NODED_CERT_FILE,
1299 1299
                     default_ssl_key=pathutils.NODED_CERT_FILE,
1300
                     console_logging=True)
1300
                     console_logging=True,
1301
                     warn_breach=True)
b/src/Ganeti/Daemon.hs
49 49
import Control.Exception
50 50
import Control.Monad
51 51
import Data.Maybe (fromMaybe, listToMaybe)
52
import Text.Printf
52 53
import Data.Word
53 54
import GHC.IO.Handle (hDuplicateTo)
54 55
import Network.BSD (getHostName)
......
383 384

  
384 385
  (opts, args) <- parseArgs progname options
385 386

  
387
  -- Modify handleClient in Ganeti.UDSServer to remove this logging from luxid.
388
  when (optDebug opts && daemon == GanetiLuxid) .
389
    hPutStrLn stderr $
390
      printf C.debugModeConfidentialityWarning (daemonName daemon)
391

  
386 392
  ensureNode daemon
387 393

  
388 394
  exitUnless (null args) "This program doesn't take any arguments"
b/src/Ganeti/Logging.hs
47 47
  , syslogUsageToRaw
48 48
  , syslogUsageFromRaw
49 49
  , withErrorLogAt
50
  , isDebugMode
50 51
  ) where
51 52

  
53
import Control.Applicative ((<$>))
52 54
import Control.Monad
53 55
import Control.Monad.Error (Error(..), MonadError(..), catchError)
54 56
import Control.Monad.Reader
......
175 177
logEmergency :: (MonadLog m) => String -> m ()
176 178
logEmergency = logAt EMERGENCY
177 179

  
180
-- | Check if the logging is at DEBUG level.
181
-- DEBUG logging is unacceptable for production.
182
isDebugMode :: IO Bool
183
isDebugMode = (Just DEBUG ==) . getLevel <$> getRootLogger
184

  
178 185
-- * Logging in an error monad with rethrowing errors
179 186

  
180 187
-- | If an error occurs within a given computation, it annotated
b/src/Ganeti/UDSServer.hs
58 58
import Control.Applicative
59 59
import Control.Concurrent (forkIO)
60 60
import Control.Exception (catch)
61
import Data.IORef
61
import Control.Monad
62 62
import qualified Data.ByteString as B
63 63
import qualified Data.ByteString.Lazy as BL
64 64
import qualified Data.ByteString.UTF8 as UTF8
65 65
import qualified Data.ByteString.Lazy.UTF8 as UTF8L
66
import Data.IORef
67
import Data.List
66 68
import Data.Word (Word8)
67
import Control.Monad
68 69
import qualified Network.Socket as S
69 70
import System.Directory (removeFile)
70 71
import System.IO (hClose, hFlush, hWaitForInput, Handle, IOMode(..))
......
81 82
import Ganeti.Runtime (GanetiDaemon(..), MiscGroup(..), GanetiGroup(..))
82 83
import Ganeti.THH
83 84
import Ganeti.Utils
84

  
85
import Ganeti.Constants (privateParametersBlacklist)
85 86

  
86 87
-- * Utility functions
87 88

  
......
350 351
        let (status, response) = prepareMsg call_result_json
351 352
        return (close, buildResponse status response)
352 353

  
354
isRisky :: RecvResult -> Bool
355
isRisky msg = case msg of
356
  RecvOk payload -> any (`isInfixOf` payload) privateParametersBlacklist
357
  _ -> False
358

  
353 359
-- | Reads a request, passes it to a handler and sends a response back to the
354 360
-- client.
355 361
handleClient
......
359 365
    -> IO Bool
360 366
handleClient handler client = do
361 367
  msg <- recvMsgExt client
368

  
369
  debugMode <- isDebugMode
370
  when (debugMode && isRisky msg) $
371
    logAlert "POSSIBLE LEAKING OF CONFIDENTIAL PARAMETERS. \
372
             \Daemon is running in debug mode. \
373
             \The text of the request has been logged."
362 374
  logDebug $ "Received message: " ++ show msg
375

  
363 376
  case msg of
364 377
    RecvConnClosed -> logDebug "Connection closed" >>
365 378
                      return False
......
370 383
      sendMsg client outMsg
371 384
      return close
372 385

  
386

  
373 387
-- | Main client loop: runs one loop of 'handleClient', and if that
374 388
-- doesn't report a finished (closed) connection, restarts itself.
375 389
clientLoop

Also available in: Unified diff