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

1 package jenkins.security;
2
3 import hudson.Extension;
4 import hudson.console.AnnotatedLargeText;
5 import hudson.init.InitMilestone;
6 import hudson.init.Initializer;
7 import hudson.model.AdministrativeMonitor;
8 import hudson.util.HttpResponses;
9 import hudson.util.SecretRewriter;
10 import hudson.util.StreamTaskListener;
11 import hudson.util.VersionNumber;
12 import jenkins.model.Jenkins;
13 import jenkins.util.io.FileBoolean;
14 import org.kohsuke.stapler.HttpResponse;
15 import org.kohsuke.stapler.StaplerProxy;
16 import org.kohsuke.stapler.StaplerRequest;
17 import org.kohsuke.stapler.interceptor.RequirePOST;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.PrintStream;
22 import java.nio.charset.Charset;
23 import java.security.GeneralSecurityException;
24 import java.util.Date;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 /**
29 * Warns the administrator to run {@link SecretRewriter}
30 *
31 * @author Kohsuke Kawaguchi
32 */
33 @Extension
34 public class RekeySecretAdminMonitor extends AdministrativeMonitor implements StaplerProxy {
35
36 /**
37 * Whether we detected a need to run the rewrite program.
38 * Once we set it to true, we'll never turn it off.
39 *
40 * If the admin decides to dismiss this warning, we use {@link #isEnabled()} for that.
41 *
42 * In this way we can correctly differentiate all the different states.
43 */
44 private final FileBoolean needed = state("needed");
45
46 /**
47 * If the scanning process has run to the completion, we set to this true.
48 */
49 private final FileBoolean done = state("done");
50
51 /**
52 * If the rewrite process is scheduled upon the next boot.
53 */
54 private final FileBoolean scanOnBoot = state("scanOnBoot");
55
56 /**
57 * Set to non-null once the rewriting activities starts running.
58 */
59 private volatile RekeyThread rekeyThread;
60
61
62 public RekeySecretAdminMonitor() throws IOException {
63 // if JENKINS_HOME existed <1.497, we need to offer rewrite
64 // this computation needs to be done and the value be captured,
65 // since $JENKINS_HOME/config.xml can be saved later before the user has
66 // actually rewritten XML files.
67 Jenkins j = Jenkins.getInstance();
68 if (j.isUpgradedFromBefore(new VersionNumber("1.496.*"))
69 && new FileBoolean(new File(j.getRootDir(),"secret.key.not-so-secret")).isOff())
70 needed.on();
71 }
72
73 /**
74 * Requires ADMINISTER permission for any operation in here.
75 */
76 public Object getTarget() {
77 Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER);
78 return this;
79 }
80
81 @Override
82 public boolean isActivated() {
83 return needed.isOn();
84 }
85
86 /**
87 * Indicates that the re-keying has run to the completion.
88 */
89 public boolean isDone() {
90 return done.isOn();
91 }
92
93 public void setNeeded() {
94 needed.on();
95 }
96
97 public boolean isScanOnBoot() {
98 return scanOnBoot.isOn();
99 }
100
101 @RequirePOST
102 public HttpResponse doScan(StaplerRequest req) throws IOException, GeneralSecurityException {
103 if(req.hasParameter("background")) {
104 synchronized (this) {
105 if (!isRewriterActive()) {
106 rekeyThread = new RekeyThread();
107 rekeyThread.start();
108 }
109 }
110 } else
111 if(req.hasParameter("schedule")) {
112 scanOnBoot.on();
113 } else
114 if(req.hasParameter("dismiss")) {
115 disable(true);
116 } else
117 throw HttpResponses.error(400,"Invalid request submission");
118
119 return HttpResponses.redirectViaContextPath("/manage");
120 }
121
122 /**
123 * Is there an active rewriting process going on?
124 */
125 public boolean isRewriterActive() {
126 return rekeyThread !=null && rekeyThread.isAlive();
127 }
128
129 /**
130 * Used to URL-bind {@link AnnotatedLargeText}.
131 */
132 public AnnotatedLargeText getLogText() {
133 return new AnnotatedLargeText<RekeySecretAdminMonitor>(getLogFile(), Charset.defaultCharset(),
134 !isRewriterActive(),this);
135 }
136
137 private static FileBoolean state(String name) {
138 return new FileBoolean(new File(getBaseDir(),name));
139 }
140
141 @Initializer(fatal=false,after=InitMilestone.PLUGINS_STARTED,before=InitMilestone.EXTENSIONS_AUGMENTED)
142 // as early as possible, but this needs to be late enough that the ConfidentialStore is available
143 public static void scanOnReboot() throws InterruptedException, IOException, GeneralSecurityException {
144 FileBoolean flag = new RekeySecretAdminMonitor().scanOnBoot;
145 if (flag.isOn()) {
146 flag.off();
147 RekeyThread t = new RekeyThread();
148 t.start();
149 t.join();
150 // block the boot until the rewrite process is complete
151 // don't let the failure in RekeyThread block Jenkins boot.
152 }
153 }
154
155 /**
156 * Rewrite log file.
157 */
158 public static File getLogFile() {
159 return new File(getBaseDir(),"rekey.log");
160 }
161
162 private static File getBaseDir() {
163 return new File(Jenkins.getInstance().getRootDir(),RekeySecretAdminMonitor.class.getName());
164 }
165
166 private static class RekeyThread extends Thread {
167 private final SecretRewriter rewriter;
168
169 RekeyThread() throws GeneralSecurityException {
170 super("Rekey secret thread");
171 rewriter = new SecretRewriter(new File(getBaseDir(),"backups"));
172 }
173
174 @Override
175 public void run() {
176 try {
177 LOGGER.info("Initiating a re-keying of secrets. See "+getLogFile());
178 StreamTaskListener listener = new StreamTaskListener(getLogFile());
179 try {
180 PrintStream log = listener.getLogger();
181 log.println("Started re-keying " + new Date());
182 int count = rewriter.rewriteRecursive(Jenkins.getInstance().getRootDir(), listener);
183 log.printf("Completed re-keying %d files on %s\n",count,new Date());
184 new RekeySecretAdminMonitor().done.on();
185 LOGGER.info("Secret re-keying completed");
186 } catch (Exception e) {
187 LOGGER.log(Level.SEVERE, "Fatal failure in re-keying secrets",e);
188 e.printStackTrace(listener.error("Fatal failure in rewriting secrets"));
189 }
190 } catch (IOException e) {
191 LOGGER.log(Level.SEVERE, "Catastrophic failure to rewrite secrets",e);
192 }
193 }
194 }
195
196 private static final Logger LOGGER = Logger.getLogger(RekeySecretAdminMonitor.class.getName());
197
198 }
199