~ubuntu-branches/ubuntu/quantal/libgksu1.2/quantal

« back to all changes in this revision

Viewing changes to libgksu/gksu-context.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2005-11-10 22:41:26 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051110224126-qas4smtk4w5gcgfr
Tags: 1.3.6-1ubuntu1
merged with debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include <glib.h>
35
35
#include <locale.h>
36
36
 
37
 
#ifdef ENABLE_GNOME_KEYRING
38
 
#include <gnome-keyring.h>
39
 
#endif
40
 
 
41
37
#include "defines.h"
42
38
#include "../config.h"
43
39
 
44
40
#include "gksu-context.h"
45
41
 
46
 
#ifdef ENABLE_GNOME_KEYRING
47
 
gboolean keyring_used = FALSE;
48
 
#endif
49
 
 
50
42
/* local function declarations */
51
43
static void
52
44
gksu_context_init (GTypeInstance *instance, gpointer g_class);
173
165
void
174
166
gksu_context_set_password (GksuContext *context, gchar *password)
175
167
{
176
 
  g_assert (password != NULL);
177
 
 
178
168
  if (context->password)
179
169
    {
180
 
       g_free (context->password);
181
 
       context->password = NULL;
 
170
      g_free (context->password);
 
171
      context->password = NULL;
182
172
    }
183
173
 
184
174
  if (password && strcmp ("", password) && strcmp ("\n", password))
185
175
    {
186
176
      if (password[strlen(password) - 1] == '\n')
187
 
       context->password = g_strdup (password);
 
177
        context->password = g_strdup (password);
188
178
      else
189
 
       context->password = g_strdup_printf ("%s\n", password);
 
179
        context->password = g_strdup_printf ("%s\n", password);
190
180
    }
191
181
}
192
182
 
423
413
  return etype;
424
414
}
425
415
 
 
416
static gchar *
 
417
get_process_name (pid_t pid)
 
418
{
 
419
#ifdef linux
 
420
  FILE *f;
 
421
  char *cmdline = malloc (sizeof(gchar*)*256);
 
422
  char *cmdfile = g_strdup_printf("/proc/%i/status",pid);
 
423
 
 
424
  cmdline[255] = '\0';
 
425
 
 
426
  f = fopen(cmdfile, "r");
 
427
  g_free (cmdfile);
 
428
  if(f != NULL) 
 
429
    {
 
430
      fgets(cmdline, 255, f);
 
431
      cmdline[255] = '\0';
 
432
      fclose(f);
 
433
    }
 
434
  return cmdline;
 
435
#else
 
436
  return NULL;
 
437
#endif
 
438
}
 
439
 
426
440
/**
427
441
 * prepare_xauth:
428
442
 *
518
532
    {
519
533
      if (errno == EEXIST)
520
534
        fprintf (stderr,
521
 
                   _("The X authority file i am trying to create for"
522
 
                     " the target user already exists! This is highly"
523
 
                     " suspicous!"));
 
535
                 _("Impossible to create the .Xauthority file: a file "
 
536
                   "already exists. This might be a security issue; "
 
537
                   "please investigate or warn your system administrator."));
524
538
      else
525
539
        fprintf (stderr,
526
540
                   _("Error copying '%s' to '%s': %s"),
607
621
  g_free (xauth);
608
622
}
609
623
 
610
 
#ifdef ENABLE_GNOME_KEYRING
611
 
gboolean
612
 
try_gnome_keyring_password (GksuContext *context)
613
 
{
614
 
  GnomeKeyringAttributeList *attributes;
615
 
  GnomeKeyringAttribute attribute;
616
 
  GnomeKeyringResult result;
617
 
  GList *list;
618
 
  GError *error = NULL;
619
 
  gboolean keyring_has_password;
620
 
  gchar *keyring_password;
621
 
  gchar *keyring_command;
622
 
 
623
 
  keyring_used = TRUE;
624
 
 
625
 
  attributes = gnome_keyring_attribute_list_new ();
626
 
 
627
 
  attribute.name = g_strdup ("user");
628
 
  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
629
 
  attribute.value.string = g_strdup (gksu_context_get_user (context));
630
 
  g_array_append_val (attributes, attribute);
631
 
 
632
 
  attribute.name = g_strdup ("type");
633
 
  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
634
 
  attribute.value.string = g_strdup ("local");
635
 
  g_array_append_val (attributes, attribute);
636
 
 
637
 
  attribute.name = g_strdup ("creator");
638
 
  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
639
 
  attribute.value.string = g_strdup ("gksu");
640
 
  g_array_append_val (attributes, attribute);
641
 
      
642
 
  list = g_list_alloc();
643
 
  keyring_has_password = FALSE;
644
 
 
645
 
  result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
646
 
                                          attributes,
647
 
                                          &list);
648
 
  gnome_keyring_attribute_list_free (attributes);
649
 
  if (
650
 
      (result == GNOME_KEYRING_RESULT_OK) &&
651
 
      (g_list_length(list) == 1)
652
 
      )
653
 
    {
654
 
      GnomeKeyringFound *found = list->data;
655
 
      keyring_password = g_strdup(found->secret);
656
 
 
657
 
      keyring_command = g_strdup (gksu_context_get_command (context));
658
 
      gksu_context_set_command (context, "/bin/echo test > /dev/null");
659
 
      gksu_context_set_password (context, keyring_password);
660
 
      gksu_context_run (context, &error);
661
 
 
662
 
      if (!error)
663
 
        keyring_has_password = TRUE;
664
 
      gksu_context_set_command (context, keyring_command);
665
 
    }
666
 
 
667
 
  if (keyring_has_password) 
668
 
    {
669
 
      gchar *password;
670
 
 
671
 
      password = g_locale_from_utf8 (keyring_password, 
672
 
                                     strlen (keyring_password), 
673
 
                                     NULL, NULL, NULL);
674
 
      gksu_context_set_password (context, password);
675
 
      return FALSE; /* we do not need a password */
676
 
    }
677
 
 
678
 
  return TRUE;
679
 
}
680
 
#endif
681
 
 
682
624
gboolean
683
625
try_su_run (GksuContext *context)
684
626
{
733
675
      fd_set rfds;
734
676
 
735
677
      struct timeval tv;
 
678
      struct termios tio;
736
679
 
737
680
      gchar buf[256];
738
681
      gint status;
750
693
      if (context->debug)
751
694
        fprintf (stderr, "try_su_run: buf: -%s-\n", buf);
752
695
 
753
 
      if (!strncmp (buf, "Password: ", 10))
754
 
        {
755
 
          write (fdpty, "\n", 1);
756
 
          close (fdpty);
757
 
        }
758
 
      else
 
696
      usleep (100);
 
697
 
 
698
      tcgetattr (fdpty, &tio);
 
699
      
 
700
      if ((tio.c_lflag & ECHO))
759
701
        need_pass = FALSE;
760
702
 
 
703
      kill (pid, SIGKILL);
761
704
      waitpid (pid, &status, 0);
762
705
    }
763
706
 
770
713
 *
771
714
 * Checks if we need to ask for a password or if we have ways of
772
715
 * getting the password for ourselves or we simply don't need it.
 
716
 * Since 1.3.0.
773
717
 *
774
718
 * Returns: TRUE if requesting a password is needed, FALSE otherwise.
775
719
 *
782
726
  if (try_su_run (context) == FALSE)
783
727
    return FALSE;
784
728
 
785
 
#ifdef ENABLE_GNOME_KEYRING
786
 
  if (try_gnome_keyring_password (context) == FALSE)
787
 
    return FALSE;
788
 
#endif
789
 
 
790
729
  return TRUE;
791
730
}
792
731
 
793
732
/**
794
 
 * gksu_context_run:
 
733
 * gksu_context_run_full:
795
734
 * @context: a #GksuContext
 
735
 * @ask_pass: a #GksuAskPasswordFunc
 
736
 * @user_data: a #gpointer with user data to be passed to the
 
737
 * #GksuAskPasswordFunc
 
738
 * @pass_not_needed: a #GksuPasswordNotNeededFunc
 
739
 * @pnn_user_data: a #gpointer with the user data to be passed to the
 
740
 * #GksuPasswordNotNeededFunc
796
741
 * @error: a #GError object to be filled with the error code or NULL
797
742
 *
798
743
 * This could be considered one of the main functions in GKSu.
799
 
 * it is responsible for doing the 'user changing' magic.
 
744
 * it is responsible for doing the 'user changing' magic calling
 
745
 * the #GksuAskPasswordFunc function to request a password if needed.
 
746
 * and the #GksuPasswordNotNeededFunc function if a password won't be
 
747
 * needed, so the application has the oportunity of warning the user
 
748
 * what it's doing.
 
749
 * Since 1.3.3.
800
750
 *
801
751
 * Returns: the child's error status, 0 if all went fine, -1 if failed
802
752
 */
803
753
gboolean
804
 
gksu_context_run (GksuContext *context, GError **error)
 
754
gksu_context_run_full (GksuContext *context, 
 
755
                       GksuAskPasswordFunc ask_pass, gpointer user_data, 
 
756
                       GksuPasswordNotNeededFunc pass_not_needed, 
 
757
                       gpointer pnn_user_data, GError **error)
805
758
{
806
759
  GQuark gksu_quark;
807
760
  int i = 0;
808
 
  gboolean auth_failed = FALSE;
809
761
 
810
762
  gchar auxcommand[] = PREFIX "/lib/" PACKAGE "/gksu-run-helper";
811
763
 
888
840
      gint target_uid = -1;
889
841
      gint my_uid = 0;
890
842
 
891
 
      gchar buf[256];
 
843
      gchar buf[256] = {0};
892
844
      gint status;
893
845
 
894
 
      /* 
895
 
         for controling the conversation with the
896
 
         helper
897
 
      */
898
 
      gboolean first_line_read = FALSE;
899
 
      
 
846
      gchar *cmdline = NULL;
 
847
 
 
848
      gboolean password_needed = FALSE;
 
849
 
900
850
      my_uid = getuid();
901
851
      pwd = getpwnam (context->user);
902
852
      if (pwd)
905
855
      /* no need to ask for password if we're already root */
906
856
      if (my_uid != target_uid && my_uid)
907
857
        {
908
 
          if (context->password)
 
858
          if (context->password || ask_pass)
909
859
            {
 
860
              struct termios tio;
 
861
 
 
862
              usleep (100);
910
863
              read (fdpty, buf, 256);
911
864
              if (context->debug)
912
865
                fprintf (stderr, "gksu_context_run: buf: -%s-\n", buf);
913
 
              sleep (1);
914
 
              write (fdpty, context->password, 
915
 
                     strlen(context->password));
 
866
 
 
867
              usleep (100);
 
868
 
 
869
              tcgetattr (fdpty, &tio);
 
870
 
 
871
              if (!(tio.c_lflag & ECHO))
 
872
                {
 
873
                  if (!context->password)
 
874
                    {
 
875
                      if (ask_pass (context, buf, user_data, error))
 
876
                          return -1;
 
877
 
 
878
                      g_return_val_if_fail (context->password, -1);
 
879
                    }
 
880
 
 
881
                  usleep (100);
 
882
 
 
883
                  password_needed = TRUE;
 
884
                  write (fdpty, context->password, 
 
885
                         strlen(context->password));
 
886
                }
916
887
            }
917
888
        }
 
889
 
 
890
      if (!password_needed)
 
891
        pass_not_needed (context, pnn_user_data);
918
892
      
 
893
      if (context->debug)
 
894
        fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
 
895
      if (strncmp (buf, "gksu", 4) && strncmp (buf, "su", 2))
 
896
        {
 
897
          bzero (buf, 256);
 
898
          /* drop the \n echoed on password entry if su did request
 
899
             a password */
 
900
          if (password_needed)
 
901
            read (fdpty, buf, 256);
 
902
          read (fdpty, buf, 255);
 
903
          if (context->debug)
 
904
            fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
 
905
        }
 
906
 
 
907
      if (!strncmp (buf, "su: Authentication failure", 26))
 
908
        {
 
909
          g_set_error (error, gksu_quark, 
 
910
                       GKSU_CONTEXT_ERROR_WRONGPASS,
 
911
                       _("Wrong password."));
 
912
          if (context->debug)
 
913
            fprintf (stderr, "DEBUG (auth_failed) buf: -%s-\n", buf);
 
914
        }
 
915
      else if (!strncmp (buf, "gksu: waiting", 13))
 
916
        {
 
917
          gchar *line;
 
918
          
 
919
          if (context->debug)
 
920
            fprintf (stderr, "DEBUG (gksu: waiting) buf: -%s-\n", buf);
 
921
 
 
922
          line = g_strdup_printf ("gksu-run: %s\n", context->display);
 
923
          write (fdpty, line, strlen(line));
 
924
          g_free (line);
 
925
          
 
926
          line = g_strdup_printf ("gksu-run: %s\n", context->xauth);
 
927
          write (fdpty, line, strlen(line));
 
928
          g_free (line);
 
929
 
 
930
          tcdrain (fdpty);
 
931
 
 
932
          bzero (buf, 256);
 
933
          read (fdpty, buf, 256);
 
934
        }
 
935
      else
 
936
        {
 
937
          gchar *emsg = g_strdup_printf (_("Failed to communicate with "
 
938
                                           "gksu-run-helper.\n\n"
 
939
                                           "Received:\n"
 
940
                                           " %s\n"
 
941
                                           "While expecting:\n"
 
942
                                           " %s"), buf, "gksu: waiting");
 
943
          g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_HELPER, emsg);
 
944
          g_free (emsg);
 
945
 
 
946
          if (context->debug)
 
947
            fprintf (stderr, "DEBUG (failed!) buf: -%s-\n", buf);
 
948
 
 
949
          return -1;
 
950
        }
 
951
 
919
952
      FD_ZERO(&rfds);
920
953
      FD_SET(fdpty, &rfds);
921
954
 
924
957
 
925
958
      while (!waitpid (pid, &status, WNOHANG))
926
959
        {
 
960
          bzero (buf, 256);
 
961
          usleep (200);
 
962
 
 
963
          if (cmdline)
 
964
            g_free (cmdline);
 
965
          cmdline = get_process_name (pid);
 
966
 
 
967
          usleep(1000);
 
968
 
927
969
          if (select (fdpty+1, &rfds, NULL, NULL, &tv) < 0)
928
970
            {
929
971
              g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_PIPEREAD,
937
979
            {
938
980
              bzero(buf, 256);
939
981
              read (fdpty, buf, 255);
940
 
 
941
 
              if (!first_line_read)
942
 
                {
943
 
                  /* we've already read something important on the
944
 
                     outside of the loop, probably because su gave
945
 
                     no output at all (pam_wheel trust or something)
946
 
                  */
947
 
                  if (strncmp (buf, "gksu", 4))
948
 
                    read (fdpty, buf, 255);
949
 
 
950
 
                  if (!strncmp (buf, "su: Authentication failure", 26))
951
 
                    auth_failed = TRUE;
952
 
                  else if (!strncmp (buf, "gksu: waiting", 13))
953
 
                    {
954
 
                      gchar *line;
955
 
                      
956
 
                      line = g_strdup_printf ("gksu-run: %s\n", context->display);
957
 
                      write (fdpty, line, strlen(line));
958
 
                      g_free (line);
959
 
                      
960
 
                      line = g_strdup_printf ("gksu-run: %s\n", context->xauth);
961
 
                      write (fdpty, line, strlen(line));
962
 
                      g_free (line);
963
 
 
964
 
                      bzero (buf, 255);
965
 
                    }
966
 
 
967
 
#ifdef ENABLE_GNOME_KEYRING
968
 
                  if (keyring_used && context->password)
969
 
                    {
970
 
                      static GMainLoop *keyring_loop = NULL;
971
 
                      GnomeKeyringAttributeList *attributes;
972
 
                      GnomeKeyringAttribute attribute;
973
 
                      
974
 
                      gchar *key_name;
975
 
                      
976
 
                      attributes = gnome_keyring_attribute_list_new ();
977
 
                      
978
 
                      attribute.name = g_strdup ("user");
979
 
                      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
980
 
                      attribute.value.string = g_strdup (gksu_context_get_user (context));
981
 
                      g_array_append_val (attributes, attribute);
982
 
                    
983
 
                      attribute.name = g_strdup ("type");
984
 
                      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
985
 
                      attribute.value.string = g_strdup ("local");
986
 
                      g_array_append_val (attributes, attribute);
987
 
 
988
 
                      attribute.name = g_strdup ("creator");
989
 
                      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
990
 
                      attribute.value.string = g_strdup ("gksu");
991
 
                      g_array_append_val (attributes, attribute);
992
 
      
993
 
                      key_name = g_strdup_printf ("Local password for user %s",
994
 
                                                  gksu_context_get_user (context));
995
 
      
996
 
                      keyring_loop = g_main_loop_new (NULL, FALSE);
997
 
 
998
 
                      void
999
 
                        keyring_create_item_cb (GnomeKeyringResult result,
1000
 
                                                guint32 id, gpointer data)
1001
 
                        {
1002
 
                          g_main_loop_quit (keyring_loop);
1003
 
                        }
1004
 
 
1005
 
                      gnome_keyring_item_create (NULL,
1006
 
                                                 GNOME_KEYRING_ITEM_GENERIC_SECRET,
1007
 
                                                 key_name,
1008
 
                                                 attributes,
1009
 
                                                 gksu_context_get_password (context),
1010
 
                                                 TRUE,
1011
 
                                                 keyring_create_item_cb, NULL, NULL);
1012
 
                      gnome_keyring_attribute_list_free (attributes);
1013
 
                      g_main_loop_run (keyring_loop);
1014
 
                    }
1015
 
#endif
1016
 
 
1017
 
                  first_line_read = TRUE;
1018
 
                }
1019
 
              else if (!strncmp (buf, "gksu-run:", 8))
1020
 
                {
1021
 
                  gchar *tmp = NULL;
1022
 
 
1023
 
                  tmp = g_strrstr (buf, "\n");
1024
 
                  while (!tmp)
1025
 
                    {
1026
 
                      bzero(buf, 256);
1027
 
                      read (fdpty, buf, 255);
1028
 
                      tmp = g_strrstr (tmp, "\n");
1029
 
                    }
1030
 
                  if (tmp)
1031
 
                    fprintf (stderr, "%s", tmp+1);
1032
 
                  bzero (buf, 255);
1033
 
                }
1034
 
              else
1035
 
                fprintf (stderr, "%s", buf);
 
982
              fprintf (stderr, "%s", buf);
1036
983
            }
1037
984
          else
1038
985
            FD_SET(fdpty, &rfds);
1039
 
 
1040
 
          usleep (200);
1041
986
        }
1042
987
 
1043
988
      while (1)
1052
997
        {
1053
998
          if (WEXITSTATUS(status))
1054
999
            {
1055
 
              if (auth_failed)
1056
 
                g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_WRONGPASS,
1057
 
                             _("Wrong password."));
1058
 
              else
1059
 
                g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_CHILDFAILED,
1060
 
                             _("Child terminated with %d status"),
 
1000
              if(cmdline)
 
1001
                {
 
1002
                  /* su already exec()ed something else, don't report
 
1003
                   * exit status errors in that case
 
1004
                   */
 
1005
                  if (!g_str_has_suffix (cmdline, "su\n"))
 
1006
                    {
 
1007
                      g_free (cmdline);
 
1008
                      return TRUE;
 
1009
                    }
 
1010
                  g_free (cmdline);
 
1011
                }
 
1012
 
 
1013
              if (error == NULL)
 
1014
                g_set_error (error, gksu_quark, 
 
1015
                             GKSU_CONTEXT_ERROR_CHILDFAILED,
 
1016
                             _("su terminated with %d status"),
1061
1017
                             WEXITSTATUS(status));
1062
 
              return WEXITSTATUS(status);
1063
1018
            }
1064
1019
        }
1065
1020
    }
1066
1021
 
1067
 
  return 0;
 
1022
  if (error)
 
1023
    return TRUE;
 
1024
 
 
1025
  return FALSE;
 
1026
}
 
1027
 
 
1028
/* DO NOT USE -- Deprecated */
 
1029
gboolean
 
1030
gksu_context_ask_and_run (GksuContext *context, GksuAskPasswordFunc ask_pass, 
 
1031
                          gpointer user_data, GError **error)
 
1032
{
 
1033
  return gksu_context_run_full (context, ask_pass, user_data, NULL, NULL, error);
 
1034
}
 
1035
 
 
1036
/**
 
1037
 * gksu_context_run:
 
1038
 * @context: a #GksuContext
 
1039
 * @error: a #GError object to be filled with the error code or NULL
 
1040
 *
 
1041
 * This could be considered one of the main functions in GKSu.
 
1042
 * it is responsible for doing the 'user changing' magic.
 
1043
 *
 
1044
 * Returns: the child's error status, 0 if all went fine, -1 if failed
 
1045
 */
 
1046
gboolean
 
1047
gksu_context_run (GksuContext *context, GError **error)
 
1048
{
 
1049
  return gksu_context_run_full (context, NULL, NULL, NULL, NULL, error);
1068
1050
}
1069
1051
 
1070
1052
static gboolean
1167
1149
            fprintf (stderr, "We'll need a password...\n");
1168
1150
 
1169
1151
          fprintf (outfile, "\n");
1170
 
          fclose (outfile);
1171
1152
        } 
1172
1153
      else 
1173
1154
        {
1191
1172
 *
1192
1173
 * Checks if we need to ask for a password or if we have ways of
1193
1174
 * getting the password for ourselves or we simply don't need it.
 
1175
 * Since 1.3.1.
1194
1176
 *
1195
1177
 * Returns: TRUE if requesting a password is needed, FALSE otherwise.
1196
1178
 *
1205
1187
}
1206
1188
 
1207
1189
/**
1208
 
 * gksu_context_sudo_run:
 
1190
 * gksu_context_sudo_run_full:
1209
1191
 * @context: a #GksuContext
 
1192
 * @ask_pass: a #GksuAskPasswordFunc
 
1193
 * @user_data: a #gpointer with user data to be passed to the
 
1194
 * #GksuAskPasswordFunc
 
1195
 * @pass_not_needed: a #GksuPasswordNotNeededFunc
 
1196
 * @pnn_user_data: a #gpointer with the user data to be passed to the
 
1197
 * #GksuPasswordNotNeededFunc
1210
1198
 * @error: a #GError object to be filled with the error code or NULL
1211
1199
 *
1212
1200
 * This could be considered one of the main functions in GKSu.
1213
 
 * it is responsible for doing the 'user changing' magic by
1214
 
 * calling gksu_ask_password() if it needs the user's password
1215
 
 * it behaves like sudo.
 
1201
 * it is responsible for doing the 'user changing' magic calling
 
1202
 * the #GksuAskPasswordFunc function to request a password if needed.
 
1203
 * and the #GksuPasswordNotNeededFunc function if a password won't be
 
1204
 * needed, so the application has the oportunity of warning the user
 
1205
 * what it's doing.
 
1206
 * Since 1.3.3.
1216
1207
 *
1217
1208
 * Returns: the child's error status, 0 if all went fine, -1 if failed
1218
1209
 */
1219
1210
gboolean
1220
 
gksu_context_sudo_run (GksuContext *context, GError **error)
 
1211
gksu_context_sudo_run_full (GksuContext *context, 
 
1212
                            GksuAskPasswordFunc ask_pass, gpointer user_data, 
 
1213
                            GksuPasswordNotNeededFunc pass_not_needed, 
 
1214
                            gpointer pnn_user_data, GError **error)
1221
1215
{
1222
1216
  char **cmd;
1223
1217
  char buffer[256];
1235
1229
  FILE *infile, *outfile;
1236
1230
  int parent_pipe[2];   /* For talking to the parent */
1237
1231
  int child_pipe[2];    /* For talking to the child */
1238
 
 
 
1232
  
1239
1233
  gksu_quark = g_quark_from_string (PACKAGE);
1240
1234
 
1241
1235
  if (!context->command)
1309
1303
      argcount++;
1310
1304
    }
1311
1305
 
1312
 
  for (i = j = 0; ; i++)
1313
 
    {
1314
 
      if (context->command[i] == ' ' || context->command[i] == '\0')
1315
 
        {
1316
 
          buffer[j] = '\0';
1317
 
          cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
1318
 
          cmd[argcount] = g_strdup (buffer);
1319
 
          bzero (buffer, 256);
1320
 
          argcount = argcount + 1;
1321
 
          j = 0;
1322
 
 
1323
 
          if (context->command[i] == '\0')
1324
 
            break;
1325
 
        }
1326
 
      else
1327
 
        {
1328
 
          if (context->command[i] == '\\')
 
1306
  {
 
1307
    gchar *tmp_arg = g_malloc (sizeof(gchar)*1);
 
1308
    gboolean inside_quotes = FALSE;
 
1309
 
 
1310
    tmp_arg[0] = '\0';
 
1311
 
 
1312
    for (i = j = 0; ; i++)
 
1313
      {
 
1314
        if ((context->command[i] == '\'') && (context->command[i-1] != '\\'))
 
1315
          {
1329
1316
            i = i + 1;
1330
 
          buffer[j] = context->command[i];
1331
 
          j = j + 1;
1332
 
        }
1333
 
    }
 
1317
            inside_quotes = !inside_quotes;
 
1318
          }
 
1319
 
 
1320
        if ((context->command[i] == ' ' && inside_quotes == FALSE) 
 
1321
            || context->command[i] == '\0')
 
1322
          {
 
1323
            tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
 
1324
            tmp_arg[j] = '\0';
 
1325
            cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
 
1326
            cmd[argcount] = g_strdup (tmp_arg);
 
1327
 
 
1328
            g_free (tmp_arg);
 
1329
 
 
1330
            argcount = argcount + 1;
 
1331
            j = 0;
 
1332
 
 
1333
            if (context->command[i] == '\0')
 
1334
              break;
 
1335
 
 
1336
            tmp_arg = g_malloc (sizeof(gchar)*1);
 
1337
            tmp_arg[0] = '\0';
 
1338
          }
 
1339
        else
 
1340
          {
 
1341
            if (context->command[i] == '\\')
 
1342
              i = i + 1;
 
1343
            tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
 
1344
            tmp_arg[j] = context->command[i];
 
1345
            j = j + 1;
 
1346
          }
 
1347
      }
 
1348
  }
1334
1349
  cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
1335
1350
  cmd[argcount] = NULL;
1336
1351
 
1385
1400
    } 
1386
1401
  else 
1387
1402
    {
1388
 
      gboolean auth_failed = FALSE;
 
1403
      gchar *cmdline = NULL;
1389
1404
 
1390
1405
      // Parent
1391
1406
      close(parent_pipe[1]);
1425
1440
          if (context->debug)
1426
1441
            fprintf (stderr, "Yeah, we're in...\n");
1427
1442
 
1428
 
          if (context->password == NULL || (!strcmp (context->password, "")))
 
1443
          if ((context->password == NULL || (!strcmp (context->password, "")))
 
1444
              && ask_pass == NULL)
1429
1445
            {
1430
1446
              g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_NOPASSWORD,
1431
1447
                           _("No password was supplied and sudo needs it."));
1434
1450
              return -1;
1435
1451
            }
1436
1452
 
 
1453
          if (!context->password)
 
1454
            {
 
1455
              if (ask_pass (context, _("Password: "), user_data, error))
 
1456
                return -1;
 
1457
              
 
1458
              g_return_val_if_fail (context->password, -1);
 
1459
            }
 
1460
          
 
1461
          usleep (100);
 
1462
 
1437
1463
          fprintf (outfile, "%s", context->password);
1438
1464
          fclose (outfile);
1439
1465
 
1442
1468
          */
1443
1469
          fgets (buffer, 255, infile);
1444
1470
          fgets (buffer, 255, infile);
1445
 
          if (!strcmp (buffer, "Sorry, try again.\n"))
1446
 
            auth_failed = TRUE;
1447
 
          else if (!strncmp (buffer, "Sorry, user ", 12))
1448
 
             g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_NOT_ALLOWED,
1449
 
                          _("The underlying authorization mechanism (sudo) "
1450
 
                            "does not allow you to run this program. Contact "
1451
 
                            "the system administrator."));
1452
 
          else
1453
 
            {
1454
 
              gchar *haystack = buffer;
1455
 
              gchar *needle;
1456
 
 
1457
 
              needle = g_strstr_len (haystack, strlen (haystack), " ");
1458
 
              if (needle && (needle + 1))
1459
 
                {
1460
 
                   needle += 1;
1461
 
                   if (!strncmp (needle, "is not in", 9))
1462
 
                      g_set_error (error, gksu_quark, 
1463
 
                                   GKSU_CONTEXT_ERROR_NOT_ALLOWED,
1464
 
                                   _("The underlying authorization mechanism (sudo) "
1465
 
                                     "does not allow you to run this program. Contact "
1466
 
                                     "the system administrator."));
1467
 
                }
1468
 
            }
1469
1471
        } 
1470
1472
      else 
1471
1473
        {
1472
1474
          if (context->debug)
1473
1475
            fprintf (stderr, "Oops... what's up?\n");
1474
1476
 
 
1477
          pass_not_needed (context, pnn_user_data);
 
1478
 
1475
1479
          fprintf (stderr, "%s", buffer);
1476
1480
        }
1477
1481
 
1478
 
 
1479
 
      // check if we are still dealing with sudo 
1480
 
      FILE *f;
1481
 
      char cmdline[255];
1482
 
      char *cmdfile = g_strdup_printf("/proc/%i/status",pid);
1483
 
 
1484
 
      f = fopen(cmdfile, "r");
1485
 
      if(f != NULL) 
1486
 
        {
1487
 
          fgets(cmdline, sizeof(cmdline), f);
1488
 
          fclose(f);
 
1482
      if (!strcmp (buffer, "Sorry, try again.\n"))
 
1483
        g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_WRONGPASS,
 
1484
                     _("Wrong password."));
 
1485
      else if (!strncmp (buffer, "Sorry, user ", 12))
 
1486
        g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_NOT_ALLOWED,
 
1487
                     _("The underlying authorization mechanism (sudo) "
 
1488
                       "does not allow you to run this program. Contact "
 
1489
                       "the system administrator."));
 
1490
      else
 
1491
        {
 
1492
          gchar *haystack = buffer;
 
1493
          gchar *needle;
 
1494
 
 
1495
          needle = g_strstr_len (haystack, strlen (haystack), " ");
 
1496
          if (needle && (needle + 1))
 
1497
            {
 
1498
              needle += 1;
 
1499
              if (!strncmp (needle, "is not in", 9))
 
1500
                g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_NOT_ALLOWED,
 
1501
                             _("The underlying authorization mechanism (sudo) "
 
1502
                               "does not allow you to run this program. Contact "
 
1503
                               "the system administrator."));
 
1504
            }
1489
1505
        }
1490
1506
 
1491
1507
      while (!waitpid (pid, &status, WNOHANG))
1492
1508
        {
1493
 
           f = fopen(cmdfile, "r");
1494
 
           if (f != NULL) 
1495
 
             {
1496
 
                 fgets(cmdline, sizeof(cmdline), f);
1497
 
                 fclose(f);
1498
 
                 usleep(1000);
1499
 
             }
 
1509
          if (cmdline)
 
1510
            g_free (cmdline);
 
1511
          cmdline = get_process_name (pid);
 
1512
 
 
1513
          usleep(1000);
1500
1514
 
1501
1515
          bzero(buffer, 256);
1502
1516
          if(!fgets (buffer, 255, infile))
1503
1517
            break;
1504
1518
          fprintf (stderr, "%s", buffer);
1505
1519
        }
1506
 
      g_free(cmdfile);
1507
1520
 
1508
1521
      /* make sure we did read everything */
1509
1522
      while (1)
1521
1534
        {
1522
1535
          if (WEXITSTATUS(status))
1523
1536
            {
1524
 
              // sudo already exec()ed something else, don't report
1525
 
              // exit status errors in that case
1526
 
               if(!g_str_has_suffix(cmdline,"sudo\n"))
1527
 
                 return TRUE;
 
1537
              if(cmdline)
 
1538
                {
 
1539
                  /* sudo already exec()ed something else, don't report
 
1540
                   * exit status errors in that case
 
1541
                   */
 
1542
                  if (!g_str_has_suffix (cmdline, "sudo\n"))
 
1543
                    {
 
1544
                      g_free (cmdline);
 
1545
                      return TRUE;
 
1546
                    }
 
1547
                  g_free (cmdline);
 
1548
                }
1528
1549
 
1529
 
              if (auth_failed)
1530
 
                g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_WRONGPASS,
1531
 
                             _("Wrong password."));
1532
 
              else
1533
 
                g_set_error (error, gksu_quark, GKSU_CONTEXT_ERROR_CHILDFAILED,
1534
 
                             _("Child terminated with %d status"),
 
1550
              if (error == NULL)
 
1551
                g_set_error (error, gksu_quark, 
 
1552
                             GKSU_CONTEXT_ERROR_CHILDFAILED,
 
1553
                             _("sudo terminated with %d status"),
1535
1554
                             WEXITSTATUS(status));
1536
 
 
1537
 
              return TRUE;
1538
1555
            }
1539
1556
        }
1540
1557
    }
1541
1558
  
 
1559
  /* if error is set we have found an error condition */
 
1560
  if (error)
 
1561
    return TRUE;
 
1562
 
1542
1563
  return FALSE;
1543
1564
}
1544
1565
 
 
1566
/* DO NOT USE -- Deprecated */
 
1567
gboolean
 
1568
gksu_context_sudo_ask_and_run (GksuContext *context, GksuAskPasswordFunc ask_pass, 
 
1569
                               gpointer user_data, GError **error)
 
1570
{
 
1571
  return gksu_context_sudo_run_full (context, ask_pass, user_data, NULL, NULL, error);
 
1572
}
 
1573
 
 
1574
/**
 
1575
 * gksu_context_sudo_run:
 
1576
 * @context: a #GksuContext
 
1577
 * @error: a #GError object to be filled with the error code or NULL
 
1578
 *
 
1579
 * This could be considered one of the main functions in GKSu.
 
1580
 * it is responsible for doing the 'user changing' magic by
 
1581
 * calling gksu_ask_password() if it needs the user's password
 
1582
 * it behaves like sudo.
 
1583
 *
 
1584
 * Returns: the child's error status, 0 if all went fine, -1 if failed
 
1585
 */
 
1586
gboolean
 
1587
gksu_context_sudo_run (GksuContext *context, GError **error)
 
1588
{
 
1589
  return gksu_context_sudo_run_full (context, NULL, NULL, NULL, NULL, error);
 
1590
}