Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

runtests.cpp

Go to the documentation of this file.
00001 /*
00002  *            kPPP: A pppd front end for the KDE project
00003  *
00004  * $Id: runtests.cpp,v 1.2 2003/08/09 17:14:56 kergoth Exp $
00005  *
00006  *            Copyright (C) 1997 Bernd Johannes Wuebben
00007  *                   wuebben@math.cornell.edu
00008  *
00009  * This file was contributed by Mario Weilguni <mweilguni@sime.com>
00010  * Thanks Mario !
00011  *
00012  * This program is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Library General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2 of the License, or (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Library General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Library General Public
00023  * License along with this program; if not, write to the Free
00024  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025  */
00026 
00027 #include <qdir.h>
00028 #include "runtests.h"
00029 #include <ctype.h>
00030 #include <unistd.h>
00031 #include <qmessagebox.h>
00032 #include <sys/stat.h>
00033 #include <stdlib.h>
00034 #include <sys/types.h>
00035 #include <pwd.h>
00036 #include <netinet/in.h>
00037 
00038 #ifdef HAVE_RESOLV_H
00039 #include <arpa/nameser.h>
00040 #include <resolv.h>
00041 #endif
00042 
00043 #ifndef _PATH_RESCONF
00044 #define _PATH_RESCONF "/etc/resolv.conf"
00045 #endif
00046 
00047 #include "pppdata.h"
00048 
00049 // initial effective uid (main.cpp)
00050 extern uid_t euid;
00051 
00052 // secure pppd location (opener.cpp)
00053 extern const char* pppdPath();
00054 
00055 // shamelessly stolen from pppd-2.3.5
00056 /********************************************************************
00057  *
00058  * Internal routine to decode the version.modification.patch level
00059  */
00060 
00061 static void decode_version (const char *_buf, int *version,
00062                             int *modification, int *patch)
00063   {
00064     char *buffer = qstrdup(_buf);
00065     char *buf = buffer;
00066     *version      = (int) strtoul (buf, &buf, 10);
00067     *modification = 0;
00068     *patch        = 0;
00069 
00070     if (*buf == '.')
00071       {
00072         ++buf;
00073         *modification = (int) strtoul (buf, &buf, 10);
00074         if (*buf == '.')
00075           {
00076             ++buf;
00077             *patch = (int) strtoul (buf, &buf, 10);
00078           }
00079       }
00080 
00081     if (*buf != '\0')
00082       {
00083         *version      =
00084         *modification =
00085         *patch        = 0;
00086       }
00087 
00088     delete [] buffer;
00089   }
00090 
00091 
00092 void pppdVersion(int *version, int *modification, int *patch) {
00093   char buffer[30];
00094   const char *pppd;
00095   char *query;
00096 
00097   *version = *modification = *patch = 0;
00098 
00099   // locate pppd
00100   if(!(pppd = pppdPath()))
00101     return;
00102 
00103   // call pppd with --version option
00104   if(!(query = new char[strlen(pppd)+25]))
00105     return;
00106   strcpy(query, pppd);
00107   // had to add a dummy device to prevent a "no device specified
00108   // and stdin is not a tty" error from newer pppd versions.
00109   strcat(query, " --version /dev/tty 2>&1");
00110   fflush(0L);
00111   FILE *output = popen(query, "r");
00112   delete [] query;
00113   if(!output)
00114     return;
00115 
00116   // read output
00117   int size = fread(buffer, sizeof(char), 29, output);
00118 
00119   if(ferror(output)) {
00120     pclose(output);
00121     return;
00122   }
00123   pclose(output);
00124   buffer[size] = '\0';
00125 
00126   // find position of version number x.y.z
00127   char *p = buffer;
00128   while(*p && !isdigit(*p))
00129     p++;
00130   if (*p == 0)
00131     return;
00132   char *p2 = p;
00133   while(*p2 == '.' || isdigit(*p2))
00134     p2++;
00135   *p2 = '\0';
00136 
00137   decode_version(p, version, modification, patch);
00138 }
00139 
00140 
00141 int uidFromName(const char *uname) {
00142   struct passwd *pw;
00143 
00144   setpwent();
00145   while((pw = getpwent()) != NULL) {
00146     if(strcmp(uname, pw->pw_name) == 0) {
00147       int uid = pw->pw_uid;
00148       endpwent();
00149       return uid;
00150     }
00151   }
00152 
00153   endpwent();
00154   return -1;
00155 }
00156 
00157 
00158 const char *homedirFromUid(uid_t uid) {
00159   struct passwd *pw;
00160   char *d = 0;
00161 
00162   setpwent();
00163   while((pw = getpwent()) != NULL) {
00164     if(pw->pw_uid == uid) {
00165       d = strdup(pw->pw_dir);
00166       endpwent();
00167       return d;
00168     }
00169   }
00170 
00171   endpwent();
00172   return d;
00173 }
00174 
00175 
00176 const char* getHomeDir() {
00177   static const char *hd = 0;
00178   static bool ranTest = false;
00179   if(!ranTest) {
00180     hd = homedirFromUid(getuid());
00181     ranTest = true;
00182   }
00183 
00184   return hd;
00185 }
00186 
00187 
00188 int runTests() {
00189   int warning = 0;
00190 
00191   // Test pre-1: check if the user is allowed to dial-out
00192   if(access("/etc/kppp.allow", R_OK) == 0 && getuid() != 0) {
00193     bool access = FALSE;
00194     FILE *f;
00195     if((f = fopen("/etc/kppp.allow", "r")) != NULL) {
00196       char buf[2048]; // safe
00197       while(f != NULL && !feof(f)) {
00198         if(fgets(buf, sizeof(buf), f) != NULL) {
00199           QString s(buf);
00200 
00201           s = s.stripWhiteSpace();
00202           if(s[0] == '#' || s.length() == 0)
00203             continue;
00204 
00205           if((uid_t)uidFromName(QFile::encodeName(s)) == getuid()) {
00206             access = TRUE;
00207             fclose(f);
00208             f = NULL;
00209           }
00210         }
00211       }
00212       if(f)
00213         fclose(f);
00214     }
00215 
00216     if(!access) {
00217         QMessageBox::warning(0,"error",
00218                  QObject::tr("You're not allowed to dial out with "
00219                       "kppp.\nContact your system administrator."));
00220       return TEST_CRITICAL;
00221     }
00222   }
00223 
00224   // Test 1: search the pppd binary
00225   const char *f = pppdPath();
00226 
00227   if(!f) {
00228       QMessageBox::warning(0,"error",
00229                  QObject::tr("Cannot find the PPP daemon!\n"
00230                       "Make sure that pppd is installed."));
00231     warning++;
00232   }
00233 
00234   // Test 2: check access to the pppd binary
00235   if(f) {
00236 #if 0
00237     if(access(f, X_OK) != 0 /* && geteuid() != 0 */) {
00238       KMessageBox::warning(0,
00239                    QObject::tr("You do not have the permission "
00240                         "to start pppd!\n"
00241                         "Contact your system administrator "
00242                         "and ask to get access to pppd."));
00243       return TEST_CRITICAL;
00244     }
00245 #endif
00246 
00247     if(geteuid() != 0) {
00248       struct stat st;
00249       stat(f, &st);
00250       if(st.st_uid != 0 || (st.st_mode & S_ISUID) == 0) {
00251           QMessageBox::warning(0,"error",
00252                      QObject::tr("You don't have sufficient permission to run\n"
00253                           "%1\n"
00254                           "Please make sure that kppp is owned by root "
00255                           "and has the SUID bit set.").arg(f));
00256         warning++;
00257       }
00258     }
00259   }
00260 
00261   // Test 5: check for existence of /etc/resolv.conf
00262   if (access(_PATH_RESCONF, R_OK) != 0) {
00263     QString file = _PATH_RESCONF" ";
00264     QString msgstr = QObject::tr("%1 is missing or can't be read!\n"
00265                    "Ask your system administrator to create "
00266                    "this file (can be empty) with appropriate "
00267                    "read and write permissions.").arg(file);
00268     QMessageBox::warning(0, "errror", msgstr);
00269     warning ++;
00270   }
00271 
00272   if(warning == 0)
00273     return TEST_OK;
00274   else
00275     return TEST_WARNING;
00276 }
00277 

Generated on Sat Nov 5 16:17:51 2005 for OPIE by  doxygen 1.4.2