File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\jenkins\security\ConfidentialStore.java.html

1 package jenkins.security;
2
3 import hudson.Extension;
4 import hudson.Lookup;
5 import hudson.init.InitMilestone;
6 import hudson.util.Secret;
7 import hudson.util.Service;
8 import jenkins.model.Jenkins;
9 import org.kohsuke.MetaInfServices;
10
11 import javax.annotation.CheckForNull;
12 import javax.annotation.Nonnull;
13 import java.io.IOException;
14 import java.security.SecureRandom;
15 import java.util.List;
16 import java.util.logging.Level;
17 import java.util.logging.Logger;
18
19 /**
20 * The actual storage for the data held by {@link ConfidentialKey}s, and the holder
21 * of the master secret.
22 *
23 * <p>
24 * This class is only relevant for the implementers of {@link ConfidentialKey}s.
25 * Most plugin code should interact with {@link ConfidentialKey}s.
26 *
27 * <p>
28 * OEM distributions of Jenkins can provide a custom {@link ConfidentialStore} implementation
29 * by writing a subclass, mark it with {@link MetaInfServices} annotation, package it as a Jenkins module,
30 * and bundling it with the war file. This doesn't use {@link Extension} because some plugins
31 * have been found to use {@link Secret} before we get to {@link InitMilestone#PLUGINS_PREPARED}, and
32 * therefore {@link Extension}s aren't loaded yet. (Similarly, it's conceivable that some future
33 * core code might need this early on during the boot sequence.)
34 *
35 * @author Kohsuke Kawaguchi
36 * @since 1.498
37 */
38 public abstract class ConfidentialStore {
39 /**
40 * Persists the payload of {@link ConfidentialKey} to a persisted storage (such as disk.)
41 * The expectation is that the persisted form is secure.
42 */
43 protected abstract void store(ConfidentialKey key, byte[] payload) throws IOException;
44
45 /**
46 * Reverse operation of {@link #store(ConfidentialKey, byte[])}
47 *
48 * @return
49 * null the data has not been previously persisted, or if the data was tampered.
50 */
51 protected abstract @CheckForNull byte[] load(ConfidentialKey key) throws IOException;
52
53 /**
54 * Works like {@link SecureRandom#nextBytes(byte[])}.
55 *
56 * This enables implementations to consult other entropy sources, if it's available.
57 */
58 public abstract byte[] randomBytes(int size);
59
60 /**
61 * Retrieves the currently active singleton instance of {@link ConfidentialStore}.
62 */
63 public static @Nonnull ConfidentialStore get() {
64 if (TEST!=null) return TEST.get();
65
66 Lookup lookup = Jenkins.getInstance().lookup;
67 ConfidentialStore cs = lookup.get(ConfidentialStore.class);
68 if (cs==null) {
69 try {
70 List<ConfidentialStore> r = (List) Service.loadInstances(ConfidentialStore.class.getClassLoader(), ConfidentialStore.class);
71 if (!r.isEmpty())
72 cs = r.get(0);
73 } catch (IOException e) {
74 LOGGER.log(Level.WARNING, "Failed to list up ConfidentialStore implementations",e);
75 // fall through
76 }
77
78 if (cs==null)
79 try {
80 cs = new DefaultConfidentialStore();
81 } catch (Exception e) {
82 // if it's still null, bail out
83 throw new Error(e);
84 }
85
86 cs = lookup.setIfNull(ConfidentialStore.class,cs);
87 }
88 return cs;
89 }
90
91 /**
92 * Testing only. Used for testing {@link ConfidentialKey} without {@link Jenkins}
93 */
94 /*package*/ static ThreadLocal<ConfidentialStore> TEST = null;
95
96 private static final Logger LOGGER = Logger.getLogger(ConfidentialStore.class.getName());
97 }
98