001/*
002 * IzPack - Copyright 2001-2005 Julien Ponge, All Rights Reserved.
003 * 
004 * http://www.izforge.com/izpack/
005 * http://developer.berlios.de/projects/izpack/
006 * 
007 * Copyright 2003 Jan Blok
008 * 
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *     http://www.apache.org/licenses/LICENSE-2.0
014 *     
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 */
021
022package com.izforge.izpack.panels;
023
024import java.awt.BorderLayout;
025import java.awt.Dimension;
026import java.awt.event.ActionEvent;
027import java.awt.event.ActionListener;
028import java.io.File;
029import java.io.FileOutputStream;
030import java.util.ArrayList;
031import java.util.List;
032import java.util.Properties;
033
034import javax.swing.BorderFactory;
035import javax.swing.Box;
036import javax.swing.BoxLayout;
037import javax.swing.JLabel;
038import javax.swing.JOptionPane;
039import javax.swing.JPanel;
040import javax.swing.JPasswordField;
041import javax.swing.JTextField;
042
043import com.izforge.izpack.ExecutableFile;
044import com.izforge.izpack.ParsableFile;
045import com.izforge.izpack.gui.LabelFactory;
046import com.izforge.izpack.installer.InstallData;
047import com.izforge.izpack.installer.InstallerFrame;
048import com.izforge.izpack.installer.IzPanel;
049import com.izforge.izpack.installer.ScriptParser;
050import com.izforge.izpack.util.FileExecutor;
051import com.izforge.izpack.util.OsConstraint;
052import com.izforge.izpack.util.VariableSubstitutor;
053
054/**
055 * The packs selection panel class.
056 * 
057 * @author Jan Blok
058 * @since November 27, 2003
059 */
060public class SudoPanel extends IzPanel implements ActionListener
061{
062
063    /**
064     * 
065     */
066    private static final long serialVersionUID = 3689628116465561651L;
067
068    private JTextField passwordField;
069
070    private boolean isValid = false;
071
072    /**
073     * The constructor.
074     * 
075     * @param parent The parent window.
076     * @param idata The installation data.
077     */
078    public SudoPanel(InstallerFrame parent, InstallData idata)
079    {
080        super(parent, idata);
081
082        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
083
084        add(LabelFactory
085                .create(
086                        /* parent.langpack.getString("SudoPanel.info") */"For installing administrator privileges are necessary",
087                        JLabel.TRAILING));
088
089        add(Box.createRigidArea(new Dimension(0, 5)));
090
091        add(LabelFactory
092                .create(
093                        /* parent.langpack.getString("SudoPanel.tip") */"Please note that passwords are case-sensitive",
094                        parent.icons.getImageIcon("tip"), JLabel.TRAILING));
095
096        add(Box.createRigidArea(new Dimension(0, 5)));
097
098        JPanel spacePanel = new JPanel();
099        spacePanel.setAlignmentX(LEFT_ALIGNMENT);
100        spacePanel.setAlignmentY(CENTER_ALIGNMENT);
101        spacePanel.setBorder(BorderFactory.createEmptyBorder(80, 30, 0, 50));
102        spacePanel.setLayout(new BorderLayout(5, 5));
103        spacePanel
104                .add(
105                        LabelFactory
106                                .create(
107                                /* parent.langpack.getString("SudoPanel.specifyAdminPassword") */"Please specify your password:"),
108                        BorderLayout.NORTH);
109        passwordField = new JPasswordField();
110        passwordField.addActionListener(this);
111        JPanel space2Panel = new JPanel();
112        space2Panel.setLayout(new BorderLayout());
113        space2Panel.add(passwordField, BorderLayout.NORTH);
114        space2Panel.add(Box.createRigidArea(new Dimension(0, 5)), BorderLayout.CENTER);
115        spacePanel.add(space2Panel, BorderLayout.CENTER);
116        add(spacePanel);
117    }
118
119    /** Called when the panel becomes active. */
120    public void panelActivate()
121    {
122        passwordField.requestFocus();
123    }
124
125    /**
126     * Actions-handling method.
127     * 
128     * @param e The event.
129     */
130    public void actionPerformed(ActionEvent e)
131    {
132        doSudoCmd();
133    }
134
135    // check if sudo password is correct (so sudo can be used in all other
136    // scripts, even without password, lasts for 5 minutes)
137    private void doSudoCmd()
138    {
139        String pass = passwordField.getText();
140
141        File file = null;
142        try
143        {
144            // write file in /tmp
145            file = new File("/tmp/cmd_sudo.sh");// ""c:/temp/run.bat""
146            FileOutputStream fos = new FileOutputStream(file);
147            fos.write("echo $password | sudo -S ls\nexit $?".getBytes()); // "echo
148            // $password
149            // >
150            // pipo.txt"
151            fos.close();
152
153            // execute
154            Properties vars = new Properties();
155            vars.put("password", pass);
156
157            List oses = new ArrayList();
158            oses.add(new OsConstraint("unix", null, null, null));
159
160            ArrayList plist = new ArrayList();
161            ParsableFile pf = new ParsableFile(file.getAbsolutePath(), null, null, oses);
162            plist.add(pf);
163            ScriptParser sp = new ScriptParser(plist, new VariableSubstitutor(vars));
164            sp.parseFiles();
165
166            ArrayList elist = new ArrayList();
167            ExecutableFile ef = new ExecutableFile(file.getAbsolutePath(),
168                    ExecutableFile.POSTINSTALL, ExecutableFile.ABORT, oses, false);
169            elist.add(ef);
170            FileExecutor fe = new FileExecutor(elist);
171            int retval = fe.executeFiles(ExecutableFile.POSTINSTALL, this);
172            if (retval == 0)
173            {
174                idata.setVariable("password", pass);
175                isValid = true;
176            }
177            // else is already showing dialog
178            // {
179            // JOptionPane.showMessageDialog(this, "Cannot execute 'sudo' cmd,
180            // check your password", "Error", JOptionPane.ERROR_MESSAGE);
181            // }
182        }
183        catch (Exception e)
184        {
185            // JOptionPane.showMessageDialog(this, "Cannot execute 'sudo' cmd,
186            // check your password", "Error", JOptionPane.ERROR_MESSAGE);
187            e.printStackTrace();
188            isValid = false;
189        }
190        try
191        {
192            if (file != null && file.exists()) file.delete();// you don't
193            // want the file
194            // with password
195            // tobe arround,
196            // in case of
197            // error
198        }
199        catch (Exception e)
200        {
201            // ignore
202        }
203    }
204
205    /**
206     * Indicates wether the panel has been validated or not.
207     * 
208     * @return Always true.
209     */
210    public boolean isValidated()
211    {
212        if (!isValid)
213        {
214            doSudoCmd();
215        }
216        if (!isValid)
217        {
218            JOptionPane.showInternalMessageDialog(this, "Password", "Password is not valid",
219                    JOptionPane.ERROR_MESSAGE);
220        }
221        return isValid;
222    }
223}