[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    kdesu/libkdesu patches
From:       Geert Jansen <g.t.jansen () stud ! tue ! nl>
Date:       2000-09-14 17:26:54
[Download RAW message or body]

Hi!

The attached patches fix bug #8850, it makes kdesu work when you don't need 
to enter a password. It makes some return values a little more consistent 
and makes kdessh work again.

Please review.

Greetings,
Geert
["kdesu-diff" (text/x-c)]

Index: kdesu.cpp
===================================================================
RCS file: /home/kde/kdebase/kdesu/kdesu/kdesu.cpp,v
retrieving revision 1.20
diff -u -r1.20 kdesu.cpp
--- kdesu.cpp	2000/08/31 02:40:19	1.20
+++ kdesu.cpp	2000/09/14 17:05:32
@@ -30,6 +30,7 @@
 #include <klocale.h>
 #include <kaboutdata.h>
 #include <kcmdlineargs.h>
+#include <kmessagebox.h>
 
 #include <kdesu/defaults.h>
 #include <kdesu/su.h>
@@ -219,25 +220,45 @@
     config->setGroup("Passwords");
     int timeout = config->readNumEntry("Timeout", defTimeout);
 
-     // Start the dialog
-    KDEsuDialog *dlg = new KDEsuDialog(user, auth_user, keep && !terminal);
-    dlg->addLine(i18n("Command:"), command);
-    if ((priority != 50) || (scheduler != SuProcess::SchedNormal)) 
-    {
-	QString prio;
-	if (scheduler == SuProcess::SchedRealtime)
-	    prio += i18n("realtime: ");
-	prio += QString("%1/100").arg(priority);
-	dlg->addLine(i18n("Priority:"), prio);
-    }
-    int ret = dlg->exec();
-    if (ret == KDEsuDialog::Rejected)
-	exit(0);
-    if (ret == KDEsuDialog::AsUser)
-	change_uid = false;
-    QCString password = dlg->password();
-    int k = dlg->keep();
-    delete dlg;
+    // Check if we need a password
+    SuProcess proc;
+    proc.setUser(auth_user);
+    int needpw = proc.checkNeedPassword();
+    if (needpw < 0)
+    {
+	QString err = i18n("Su returned with an error!\n");
+	KMessageBox::error(0L, err);
+	exit(1);
+    }
+    if (needpw == 0)
+    {
+	keep = 0;
+	kdDebug() << "Don't need password!!\n";
+    }
+
+    // Start the dialog
+    QCString password;
+    if (needpw)
+    {
+	KDEsuDialog *dlg = new KDEsuDialog(user, auth_user, keep && !terminal);
+	dlg->addLine(i18n("Command:"), command);
+	if ((priority != 50) || (scheduler != SuProcess::SchedNormal)) 
+	{
+	    QString prio;
+	    if (scheduler == SuProcess::SchedRealtime)
+		prio += i18n("realtime: ");
+	    prio += QString("%1/100").arg(priority);
+	    dlg->addLine(i18n("Priority:"), prio);
+	}
+	int ret = dlg->exec();
+	if (ret == KDEsuDialog::Rejected)
+	    exit(0);
+	if (ret == KDEsuDialog::AsUser)
+	    change_uid = false;
+	password = dlg->password();
+	keep = dlg->keep();
+	delete dlg;
+    }
 
     // Some events may need to be handled (like a button animation)
     app->processEvents();
@@ -247,7 +268,7 @@
 
     // Run command
 
-    if (k && have_daemon) 
+    if (keep && have_daemon) 
     {
 	client.setPass(password, timeout);
 	client.setPriority(priority);
Index: sudlg.cpp
===================================================================
RCS file: /home/kde/kdebase/kdesu/kdesu/sudlg.cpp,v
retrieving revision 1.5
diff -u -r1.5 sudlg.cpp
--- sudlg.cpp	2000/07/05 14:16:14	1.5
+++ sudlg.cpp	2000/09/14 17:05:32
@@ -46,14 +46,21 @@
     int status = proc.checkInstall(password);
     switch (status)
     {
+    case -1:
+	KMessageBox::sorry(this, i18n("Conversation with su failed."));
+	done(Rejected);
+	return false;
+
     case 0:
 	return true;
+
     case SuProcess::SuNotFound:
         KMessageBox::sorry(this, 
 		i18n("The program `su' is not found!\n\n"
 		     "Make sure your PATH is set correctly."));
 	done(Rejected);
 	return false;
+
     case SuProcess::SuNotAllowed:
         KMessageBox::sorry(this, 
 		i18n("You are not allowed to use `su'!\n\n"
@@ -61,9 +68,11 @@
 		     "group (often: wheel) to use this program."));
 	done(Rejected);
 	return false;
+
     case SuProcess::SuIncorrectPassword:
         KMessageBox::sorry(this, i18n("Incorrect password! Please try again."));
 	return false;
+
     default:
         KMessageBox::error(this, i18n("Internal error: Illegal return from "
 		"SuProcess::checkInstall()"));

["libkdesu-diff" (text/english)]

===================================================================
RCS file: /home/kde/kdelibs/kdesu/process.cpp,v
retrieving revision 1.22
diff -u -r1.22 process.cpp
--- process.cpp	2000/07/30 13:16:09	1.22
+++ process.cpp	2000/09/14 17:04:40
@@ -159,12 +159,22 @@
     return ret;
 }
 
+
 void PtyProcess::writeLine(QCString line, bool addnl)
 {
     if (!line.isEmpty())
 	write(m_Fd, line, line.length());
     if (addnl)
 	write(m_Fd, "\n", 1);
+}
+
+
+void PtyProcess::unreadLine(QCString line, bool addnl)
+{
+    if (addnl)
+	line += '\n';
+    if (!line.isEmpty())
+	m_Inbuf.prepend(line);
 }
 
 /*
Index: process.h
===================================================================
RCS file: /home/kde/kdelibs/kdesu/process.h,v
retrieving revision 1.18
diff -u -r1.18 process.h
--- process.h	2000/07/02 11:48:37	1.18
+++ process.h	2000/09/14 17:04:40
@@ -60,6 +60,13 @@
     void writeLine(QCString line, bool addNewline=true);
 
     /**
+     * Put back a line of input.
+     * @param line The line to put back.
+     * @param addNewline Adds a '\n' to the line.
+     */
+    void unreadLine(QCString line, bool addNewline=true);
+
+    /**
      * Set exit string. If a line of program output matches this,
      * @ref #waitForChild() will terminate the program and return.
      */
Index: ssh.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdesu/ssh.cpp,v
retrieving revision 1.14
diff -u -r1.14 ssh.cpp
--- ssh.cpp	2000/07/06 12:03:49	1.14
+++ ssh.cpp	2000/09/14 17:04:41
@@ -62,15 +62,16 @@
     d->m_Stub = stub;
 }
 
-int SshProcess::checkNeedPassword()
+
+int SshProcess::checkInstall(const char *password)
 {
-    return exec(0L, 2);
+    return exec(password, 1);
 }
 
 
-int SshProcess::checkInstall(const char *password)
+int SshProcess::checkNeedPassword()
 {
-    return exec(password, 1);
+    return exec(0L, 2);
 }
 
 
@@ -80,17 +81,6 @@
 	setTerminal(true);
 
     QCStringList args;
-    if (!m_bXOnly) 
-    {
-	// Install DCOP forward
-	QCString fwd = dcopForward();
-	if (fwd.isEmpty()) 
-	{
-	    kdError(900) << k_lineinfo << "Could not get DCOP forward\n";
-	    return -1;
-	}
-	args += "-R"; args += fwd;
-    }
     args += "-l"; args += m_User;
     args += "-o"; args += "StrictHostKeyChecking no";
     args += m_Host; args += d->m_Stub;
@@ -103,12 +93,13 @@
     int ret = ConverseSsh(password, check);
     if (ret < 0)
     {
-	kdError(900) << k_lineinfo << "Conversation with ssh failed\n";
+	if (!check)
+	    kdError(900) << k_lineinfo << "Conversation with ssh failed\n";
 	return ret;
     }
     if (check == 2)
     {
-	if (ret == SshNeedsPassword)
+	if (ret == 1)
 	{
 	    kill(m_Pid, SIGTERM);
 	    waitForChild();
@@ -126,19 +117,17 @@
     ret = ConverseStub(check);
     if (ret < 0)
     {
-	kdError(900) << k_lineinfo << "Converstation with kdesu_stub failed\n";
+	if (!check)
+	    kdError(900) << k_lineinfo << "Converstation with kdesu_stub failed\n";
 	return ret;
-    }
-    if (ret == StubUnknownRequest)
+    } else if (ret == 1)
     {
 	kill(m_Pid, SIGTERM);
 	waitForChild();
-	return ret;
+	ret = SshIncorrectPassword;
     }
-
-    if (check)
+    if (check == 1)
     {
-	// All checks are ok.
 	waitForChild();
 	return 0;
     }
@@ -157,6 +146,8 @@
  * random number between 10k and 50k. This is not ok, of course, but I see
  * no other way. There is, afaik, no security issue involved here. If the port 
  * happens to be occupied, ssh will refuse to start.
+ *
+ * 14/SEP/2000: DCOP forwarding is not used anymore.
  */
 
 QCString SshProcess::dcopForward()
@@ -221,15 +212,8 @@
 	    // Check for "kdesu_stub" header.
 	    if (line == "kdesu_stub") 
 	    {
-		// This makes parsing a lot easier. Normally, 
-		// StubProcess::ConverseStub will do this.
-		enableLocalEcho(false);
-		if (check > 0)
-		    write(m_Fd, "stop\n", 5);
-		else
-		    write(m_Fd, "ok\n", 3);
-		state += 2;
-		break;
+		unreadLine(line);
+		return 0;
 	    }
 
 	    // Match "Password: " with the regex ^[^:]+:[\w]*$.
Index: stub.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdesu/stub.cpp,v
retrieving revision 1.9
diff -u -r1.9 stub.cpp
--- stub.cpp	2000/09/09 15:05:44	1.9
+++ stub.cpp	2000/09/14 17:04:41
@@ -73,9 +73,10 @@
 /*
  * Conversation with kdesu_stub. This is how we pass the authentication
  * tokens (X11, DCOP) and other stuff to kdesu_stub.
+ * return values: -1 = error, 0 = ok, 1 = kill me
  */
 
-int StubProcess::ConverseStub(bool check_only)
+int StubProcess::ConverseStub(int check)
 {
     QCString line, tmp;
     while (1) 
@@ -88,7 +89,7 @@
 	{
 	    // This makes parsing a lot easier.
 	    enableLocalEcho(false);
-	    if (check_only) writeLine("stop");
+	    if (check) writeLine("stop");
 	    else writeLine("ok");
 	} else if (line == "display") {
 	    writeLine(display());
@@ -99,7 +100,7 @@
 	} else if (line == "dcop_auth") {
 	    writeLine("no");
 	} else if (line == "ice_auth") {
-	    writeLine(commaSeparatedList(iceAuth()));
+	    writeLine("no");
 	} else if (line == "command") {
 	    writeLine(m_Command);
 	} else if (line == "path") {
@@ -124,7 +125,7 @@
 	{
 	    kdWarning(900) << k_lineinfo << "Unknown request: -->" << line 
 		           << "<--\n";
-	    return StubUnknownRequest;
+	    return 1;
 	}
     }
 
Index: stub.h
===================================================================
RCS file: /home/kde/kdelibs/kdesu/stub.h,v
retrieving revision 1.6
diff -u -r1.6 stub.h
--- stub.h	2000/07/05 14:15:05	1.6
+++ stub.h	2000/09/14 17:04:41
@@ -33,8 +33,6 @@
     StubProcess();
     ~StubProcess();
 
-    enum Errors { StubUnknownRequest=1 };
-
     /** Set the command. */
     void setCommand(QCString command) { m_Command = command; }
 
@@ -68,7 +66,7 @@
 protected:
 
     /** Exchange all parameters with kdesu_stub. */
-    int ConverseStub(bool check_only);
+    int ConverseStub(int check);
 
     /** Notify the taskbar that a new application has been started. */
     void notifyTaskbar(QString suffix);
Index: su.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdesu/su.cpp,v
retrieving revision 1.15
diff -u -r1.15 su.cpp
--- su.cpp	2000/07/06 11:54:47	1.15
+++ su.cpp	2000/09/14 17:04:41
@@ -60,6 +60,11 @@
     return exec(password, 1);
 }
 
+int SuProcess::checkNeedPassword()
+{
+    return exec(0L, 2);
+}
+
 /*
  * Execute a command with su(1).
  */
@@ -83,12 +88,18 @@
     }
     
     int ret = ConverseSU(password);
-    if (ret != 0) 
+    if (ret < 0) 
     {
 	if (!check)
-	{
 	    kdError(900) << k_lineinfo << "Conversation with su failed\n";
-	    ret = -1;
+	return ret;
+    } 
+    if (check == 2)
+    {
+	if (ret == 1)
+	{
+	    kill(m_Pid, SIGTERM);
+	    waitForChild();
 	}
 	return ret;
     }
@@ -101,22 +112,19 @@
     }
 
     ret = ConverseStub(check);
-    if (ret != 0)
+    if (ret < 0)
     {
-	if (ret < 0)
+	if (!check)
 	    kdError(900) << k_lineinfo << "Converstation with kdesu_stub failed\n";
-	if (ret == StubUnknownRequest)
-	{
-	    kill(m_Pid, SIGTERM);
-	    waitForChild();
-	    ret = SuIncorrectPassword;
-	}
 	return ret;
+    } else if (ret == 1)
+    {
+	kill(m_Pid, SIGTERM);
+	waitForChild();
+	ret = SuIncorrectPassword;
     }
-
-    if (check)
+    if (check == 1)
     {
-	// All checks are ok
 	waitForChild();
 	return 0;
     }
@@ -130,7 +138,7 @@
 
 /*
  * Conversation with su: feed the password.
- * Return values: -1 = parse error, 0 = ok or >0 an error code.
+ * Return values: -1 = error, 0 = ok, 1 = kill me
  */
 
 int SuProcess::ConverseSU(const char *password)
@@ -143,15 +151,18 @@
     {
 	line = readLine(); 
 	if (line.isNull())
-	{
-	    if (state == 0)
-		return SuNotAllowed;
 	    return -1;
-	}
-
+	
 	switch (state) 
 	{
 	case 0:
+	    // In case no password is needed.
+	    if (line == "kdesu_stub")
+	    {
+		unreadLine(line);
+		return 0;
+	    }
+
 	    // Match "Password: " with the regex ^[^:]+:[\w]*$.
 	    for (i=0,j=0,colon=0; i<line.length(); i++) 
 	    {
@@ -165,6 +176,8 @@
 	    }
 	    if ((colon == 1) && (line[j] == ':')) 
 	    {
+		if (password == 0L)
+		    return 1;
 		WaitSlave();
 		write(m_Fd, password, strlen(password));
 		write(m_Fd, "\n", 1);
Index: su.h
===================================================================
RCS file: /home/kde/kdelibs/kdesu/su.h,v
retrieving revision 1.9
diff -u -r1.9 su.h
--- su.h	2000/07/05 14:15:05	1.9
+++ su.h	2000/09/14 17:04:41
@@ -38,6 +38,11 @@
      */
     int checkInstall(const char *password);
 
+    /**
+     * Checks if a password is needed.
+     */
+    int checkNeedPassword();
+
 protected:
     virtual QCStringList dcopServer();
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic