#include #include #include #include #include #ifdef HAVE_CONFIG_H # include #endif #include #include "gkdial.h" #include "defines.h" #include "peers_list.h" #include "connedit.h" #include "defines.h" gboolean parse_peer_files (GkDial * gkdial) { GkConnection *connection = gkdial->connection; FILE *file; gchar *file_name; gchar *buf = g_malloc (sizeof (gchar) * 256); gchar *tmp = NULL; if (!strcmp (connection->name, "")) { g_free (buf); return FALSE; } #ifdef DEBUG fprintf (stderr, "Reading /etc/ppp/peers/%s\n", connection->name); #endif /* * parses the /etc/ppp/peers/peer to get the user name, modem device, * etc */ file_name = g_strdup_printf ("/etc/ppp/peers/%s", connection->name); file = fopen (file_name, "r"); g_free (file_name); if (file) { gint parseoptions = 0; while (!feof (file)) { fgets (buf, 255, file); /* * gets the user name */ if (!strncmp ("user ", buf, 5)) { gchar *tmp; g_strstrip (buf); tmp = strstr (buf, " "); gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_user), tmp + 1); } if (parseoptions) { g_strstrip (buf); if (parseoptions == 1) gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_option1), buf); if (parseoptions == 2) gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_option2), buf); parseoptions++; } if (!strncmp ("remotename ", buf, 11)) { memset(buf, 0, 255); parseoptions++; } } fclose (file); } #ifdef DEBUG fprintf (stderr, "Reading /etc/chatscripts/%s\n", connection->name); #endif /* * parses /etc/chatscripts/peer, to get phone number and other * information */ file_name = g_strdup_printf ("/etc/chatscripts/%s", connection->name); file = fopen (file_name, "r"); g_free (file_name); if (file) { while (!feof (file)) { fgets (buf, 255, file); if (!strncmp ("# ispauth", buf, 9)) { /* gets the auth style */ g_strstrip (buf); tmp = strstr (buf, "auth"); gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_auth), tmp + 5); tmp = NULL; } else if (!strncmp ("# modeminit", buf, 11)) { /* gets the modem init string */ fgets (buf, 255, file); g_strstrip (buf); tmp = strstr (buf, "''"); if (!strstr(tmp + 2,"'ATZ'")) /* get value, remove "'" */ { gchar *t = strstr(tmp + 4, "'"); if (t) t[0] = 0; gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_modeminit), tmp + 4); } tmp = NULL; } else if (!strncmp ("# ispnumber", buf, 11)) { /* gets the phone * number */ fgets (buf, 255, file); g_strstrip (buf); tmp = strstr (buf, "ATD"); gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_phone), tmp + 4); tmp = NULL; } } fclose (file); } /* * parses /etc/ppp/${auth_type}-secrets, to get password */ { gchar *secrets_name; if (!connection->auth_type) { connection->auth_type = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_auth), 0, -1); } if (!strcmp (connection->auth_type, "PAP")) secrets_name = g_strdup ("pap"); else if (!strcmp (connection->auth_type, "CHAP")) secrets_name = g_strdup ("chap"); file_name = g_strdup_printf ("/etc/ppp/%s-secrets", secrets_name); g_free (secrets_name); } #ifdef DEBUG fprintf (stderr, "Reading %s\n", file_name); #endif file = fopen (file_name, "r"); g_free (file_name); if (file) { gchar *search_for; if (connection->user) search_for = g_strdup_printf ("%s %s ", connection->user, connection->name); else search_for = g_strdup_printf (" %s ", connection->name); while (!feof (file)) { fgets (buf, 255, file); g_strstrip (buf); if (tmp = strstr (buf, search_for)) { gchar *final_str = g_malloc0 (sizeof (gchar) * 2); gchar *end = NULL; gint count; tmp = tmp + strlen (search_for); end = strstr (tmp, " "); if (end) { for (count = 2; tmp != end; count++) { final_str = g_realloc (final_str, count); final_str[count - 2] = *tmp; final_str[count - 1] = '\0'; tmp += 1; } } else final_str = g_strdup (tmp); gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_password), final_str); g_free (final_str); break; } } fclose (file); } g_free (buf); return TRUE; } void gkconnection_clear (GkConnection * connection) { g_free (connection->name); connection->name = NULL; g_free (connection->phone); connection->phone = NULL; g_free (connection->user); connection->user = NULL; g_free (connection->password); connection->password = NULL; g_free (connection->auth_type); connection->auth_type = NULL; g_free (connection->modeminit); connection->modeminit = NULL; g_free (connection->option1); connection->option1 = NULL; g_free (connection->option2); connection->option2 = NULL; } void gkconnection_copy (GkConnection * source, GkConnection * destination) { gkconnection_clear (destination); destination->name = g_strdup (source->name); destination->phone = g_strdup (source->phone); destination->user = g_strdup (source->user); destination->password = g_strdup (source->password); destination->auth_type = g_strdup (source->auth_type); destination->modeminit = g_strdup (source->modeminit); destination->option1 = g_strdup (source->option1); destination->option2 = g_strdup (source->option2); } void connedit_window_clear (GkDial * gkdial) { GkConnection *connection = gkdial->connection; gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_conn_name), ""); gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_phone), ""); gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_user), ""); gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_password), ""); gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_modeminit), ""); gkconnection_clear (connection); } gboolean connedit_window_populate (GkDial * gkdial) { GkConnection *connection = gkdial->connection; if (!peers_list_get_selected (gkdial)) return FALSE; /* * if the user is not root, re run gkdial using gksu asking for root * password */ if (geteuid ()) { gchar *command; command = g_strdup_printf ("%s/bin/gkdial -e %s", PREFIX, connection->name); gkdial_fork_new (gkdial, _("You need root permissions to edit " "a connection.\n\n" "Please type you root password:"), command); g_free (command); return FALSE; } gtk_entry_set_text (GTK_ENTRY (gkdial->cp_entry_conn_name), connection->name); #ifdef DEBUG printf ("(connedit_window_populate): connection->name: %s\n", connection->name); #endif if (!parse_peer_files (gkdial)) return FALSE; return TRUE; } void gkdial_connedit_show (GtkWidget * w, gpointer data) { GkDial *gkdial = (GkDial *) data; GkConnection *connection = gkdial->connection; GkConnection *backup = gkdial->connection_backup; gkdial_prefs_buttons_set_sensitive (gkdial, FALSE); if (!connedit_window_populate (gkdial)) { gkdial_prefs_buttons_set_sensitive (gkdial, TRUE); return; } /* * save the original information in case connection name or auth_type * change */ gkconnection_copy (connection, backup); gtk_widget_show (gkdial->connedit_window); } /* * uses the same window as 'connedit' */ void gkdial_connadd_show (GtkWidget * w, gpointer data) { GkDial *gkdial = (GkDial *) data; GkConnection *connection = gkdial->connection; gkdial_prefs_buttons_set_sensitive (gkdial, FALSE); /* * if the user is not root, re run gkdial using gksu asking for root * password */ if (geteuid ()) { gchar *command; command = g_strdup_printf ("%s/bin/gkdial -a", PREFIX); gkdial_fork_new (gkdial, _("You need root permissions to add " "a connection.\n\n" "Please type you root password:"), command); g_free (command); return; } gkdial->editing_status = GKCONNECTION_ADDING; gtk_widget_show (gkdial->connedit_window); } void gkdial_connedit_delete (GtkWidget * w, GdkEventAny * event, gpointer data) { gkdial_connedit_close (w, data); } void gkdial_connedit_close (GtkWidget * w, gpointer data) { GkDial *gkdial = (GkDial *) data; GkConnection *connection = gkdial->connection; GkConnection *backup = gkdial->connection_backup; gtk_widget_hide (gkdial->connedit_window); #ifdef DEBUG fprintf (stderr, "name: %s\n" "phone: %s\n" "user: %s\n" "password: %s\n" "auth_type: %s\n", connection->name, connection->phone, connection->user, connection->password, connection->auth_type); #endif connedit_window_clear (gkdial); gkconnection_clear (backup); gkdial->editing_status = GKCONNECTION_NONE; gkdial_prefs_buttons_set_sensitive (gkdial, TRUE); if (gkdial->edit_only || gkdial->add_only) gtk_main_quit (); else peers_list_fill (gkdial, FALSE); } int remove_secret_entry (GkConnection * connection) { FILE *file; gchar *backup; gchar *file_name; gchar *search_for; gchar **buffer; gint i; umask (0117); /* * I cannot check for username or pass, as connection->user and * connection->password contain the new ones, maybe a * gkdial->connection_old would be more secure? */ search_for = g_strdup_printf (" %s ", connection->name); if (!strcmp (connection->auth_type, "PAP")) file_name = g_strdup_printf ("/etc/ppp/pap-secrets"); else if (!strcmp (connection->auth_type, "CHAP")) file_name = g_strdup_printf ("/etc/ppp/chap-secrets"); #ifdef DEBUG fprintf (stderr, "(remove_secret_entry): Trying to clean %s on %s!\n", search_for, file_name); #endif file = fopen (file_name, "r"); if (file == NULL) { gk_dialog (GTK_MESSAGE_WARNING, _("Error trying to clean %s. You will need to\n" "edit it by hand and remove the correct entry\n" "for this connection."), file_name); return -1; } buffer = (gchar **) g_malloc (sizeof (gchar *) * 1); for (i = 1; !feof (file); i++) { buffer = (gchar **) g_realloc (buffer, sizeof (gchar *) * i); buffer[i - 1] = (gchar *) g_malloc0 (sizeof (gchar) * 1024); fgets (buffer[i - 1], 1024, file); if (strstr (buffer[i - 1], search_for)) { free (buffer[i - 1]); i--; } } fclose (file); buffer = (char **) g_realloc (buffer, sizeof (char *) * i); buffer[i - 1] = NULL; backup = g_strdup_printf ("%s~", file_name); rename (file_name, backup); file = fopen (file_name, "w"); for (i = 0; buffer[i] != NULL; i++) { // printf ("i: %d - buffer[i]: %s\n", i, buffer[i]); fprintf (file, "%s", buffer[i]); g_free (buffer[i]); } fclose (file); // unlink (backup); g_free (buffer[i]); g_free (buffer); g_free (search_for); g_free (backup); return 0; } void gkdial_connection_remove_files (GkConnection * connection) { gchar *file_name; file_name = g_strdup_printf ("/etc/ppp/peers/%s", connection->name); unlink (file_name); g_free (file_name); file_name = g_strdup_printf ("/etc/chatscripts/%s", connection->name); unlink (file_name); g_free (file_name); remove_secret_entry (connection); } void gkdial_connection_remove (GtkWidget * w, gpointer data) { GkDial *gkdial = (GkDial *) data; GkConnection *connection = gkdial->connection; if (!peers_list_get_selected (gkdial)) { if (gkdial->remove_only) gtk_main_quit (); else return; } if (!gkdial->remove_only) { GtkWidget *dialog; gint response; dialog = gtk_message_dialog_new (GTK_WINDOW (gkdial->prefs_window), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _ ("Are you sure you want to remove " "the %s connection?"), connection->name); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); switch (response) { case GTK_RESPONSE_NO: case GTK_RESPONSE_NONE: case GTK_RESPONSE_DELETE_EVENT: return; } } gkdial_prefs_buttons_set_sensitive (gkdial, FALSE); /* * if the user is not root, re run gkdial using gksu asking for root * password */ if (geteuid ()) { gchar *command; command = g_strdup_printf ("%s/bin/gkdial -r %s", PREFIX, connection->name); gkdial_fork_new (gkdial, _("You need root permissions to remove " "a connection.\n\n" "Please type you root password:"), command); g_free (command); return; } #ifdef DEBUG fprintf (stderr, "(gkdial_connection_remove: Removing: %s!\n", connection->name); #endif parse_peer_files (gkdial); gkdial_connection_remove_files (connection); gkconnection_clear (connection); if (!gkdial->remove_only) { gkdial_prefs_buttons_set_sensitive (gkdial, TRUE); peers_list_fill (gkdial, FALSE); } } void gkdial_connedit_save (GtkWidget * w, gpointer data) { GkDial *gkdial = (GkDial *) data; GkConnection *connection = gkdial->connection; GkConnection *backup = gkdial->connection_backup; /* * if we're editing the peer (the file exists already) instead of * creating a new, this should be TRUE */ gboolean file_exists = FALSE; /* * TRUE if when editing a connection the user changed its name */ gboolean name_changed = FALSE; FILE *file; gchar *file_name; umask (0117); if (!connection->name || !connection->phone || !connection->user || !connection->password) { gk_dialog (GTK_MESSAGE_WARNING, _("The information you entered is " "not complete, please add the " "missing information.")); return; } if (!connection->auth_type) connection->auth_type = g_strdup ("PAP"); /* * writes /etc/ppp/peers/${peer} */ file_name = g_strdup_printf ("/etc/ppp/peers/%s", connection->name); /* * are we editing an already existant file? */ file_exists = g_file_test (file_name, G_FILE_TEST_EXISTS); if (backup->name && strcmp (connection->name, backup->name)) name_changed = TRUE; /* * checks if a connection with that name already exists when adding * new */ if (file_exists && (gkdial->editing_status == GKCONNECTION_ADDING || name_changed)) { GtkWidget *dialog; gint response; dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("A connection named %s " "already exists.\n\n" "Do you want to overwrite " "it?"), connection->name); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); switch (response) { case GTK_RESPONSE_NO: case GTK_RESPONSE_NONE: case GTK_RESPONSE_DELETE_EVENT: return; } } file = fopen (file_name, "w"); if (!file) { gk_dialog (GTK_MESSAGE_ERROR, _("Fatal error trying to write to: " "%s. Cannot continue. "), file_name); g_free (file_name); return; } /* * FIXME: need to get the modem device from somewhere */ fprintf (file, "# This optionfile was generated by %s %s.\n" "# \n" "#\n" "hide-password \n" "noauth\n" "connect \"/usr/sbin/chat -v -f /etc/chatscripts/%s\"\n" "debug\n" "%s\n" /* modem file */ "115200\n" "defaultroute\n" "noipdefault\n" "user %s\n" /* user name */ "remotename %s\n", /* conn_name */ PACKAGE, VERSION, connection->name, "/dev/modem", connection->user, connection->name); if (connection->option1) fprintf(file, "%s\n", connection->option1); if (connection->option2) fprintf(file, "%s\n", connection->option2); fclose (file); if (chmod (file_name, S_IWUSR | S_IRGRP | S_IRUSR | S_IROTH)) perror("err"); g_free (file_name); /* * writes /etc/chatscripts/${peer} */ file_name = g_strdup_printf ("/etc/chatscripts/%s", connection->name); file = fopen (file_name, "w"); if (!file) { gk_dialog (GTK_MESSAGE_ERROR, _("Fatal error trying to write to: " "%s. Cannot continue. "), file_name); gkdial_connection_remove_files (connection); g_free (file_name); return; } /* * FIXME: need to get the modem device from somewhere */ fprintf (file, "# This chatfile was generated by %s %s.\n" "# Please do not delete any of the comments. " "Pppconfig and GkDial need them.\n" "# \n" "# ispauth %s\n" /* auth */ "# abortstring\n" "ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE'" "ABORT 'NO DIAL TONE' ABORT 'NO ANSWER'\n" "# modeminit\n" "'' '%s'\n" /* FIXME! */ "TIMEOUT 120\n" "# ispnumber\n" "OK-AT-OK ATDT%s\n" /* phone - FIXME! Tone or Pulse */ "# ispconnect\n" "CONNECT \\d\\c\n" "# prelogin\n" "\n" "# ispname\n" "# isppassword\n" "# postlogin\n" "\n" "# end of pppconfig stuff\n", PACKAGE, VERSION, connection->auth_type, connection->modeminit ? connection->modeminit : "ATZ", connection->phone); fclose (file); if (chmod (file_name, S_IWUSR | S_IRGRP | S_IRUSR | S_IROTH)) perror("err"); g_free (file_name); /* * remove the old user/pass entry before adding the new */ if (file_exists) remove_secret_entry (connection); /* * the auth_type may have changed, so we need to check that */ if (backup->auth_type) remove_secret_entry (backup); /* * writes /etc/ppp/${auth}-secrets */ { gchar *secrets_name = NULL; if (!strcmp (connection->auth_type, "PAP")) secrets_name = g_strdup ("pap"); else if (!strcmp (connection->auth_type, "CHAP")) secrets_name = g_strdup ("chap"); file_name = g_strdup_printf ("/etc/ppp/%s-secrets", secrets_name); g_free (secrets_name); } file = fopen (file_name, "a"); if (!file) { gk_dialog (GTK_MESSAGE_ERROR, _("Fatal error trying to write to: " "%s. Cannot continue. "), file_name); gkdial_connection_remove_files (connection); g_free (file_name); return; } g_free (file_name); fprintf (file, "%s %s %s\n", connection->user, connection->name, connection->password); fclose (file); /* * remove the old files */ if (name_changed) { gkdial_connection_remove_files (backup); } gkdial_connedit_close (NULL, gkdial); } void cp_entry_changed_cb (GtkWidget * w, gpointer data) { GkDial *gkdial = (GkDial *) data; GkConnection *connection = gkdial->connection; gchar *entry_name; entry_name = g_object_get_data (G_OBJECT (w), "name"); g_return_if_fail (entry_name != NULL); #ifdef DEBUG fprintf (stderr, "%s changed!!\n", entry_name); #endif if (!strcmp (entry_name, "conn_name")) { gchar *tmp = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_conn_name), 0, -1); if (!strcmp (tmp, "")) g_free (tmp); else { g_free (connection->name); connection->name = g_strdup (tmp); g_free (tmp); #ifdef DEBUG fprintf (stderr, "%s changed to %s!!!\n", entry_name, connection->name); #endif } } else if (!strcmp (entry_name, "phone")) { g_free (connection->phone); connection->phone = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_phone), 0, -1); } else if (!strcmp (entry_name, "user")) { g_free (connection->user); connection->user = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_user), 0, -1); } else if (!strcmp (entry_name, "password")) { g_free (connection->password); connection->password = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_password), 0, -1); } else if (!strcmp (entry_name, "auth")) { g_free (connection->auth_type); connection->auth_type = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_auth), 0, -1); } else if (!strcmp (entry_name, "modeminit")) { g_free (connection->modeminit); connection->modeminit = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_modeminit), 0, -1); } else if (!strcmp (entry_name, "option1")) { g_free (connection->option1); connection->option1 = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_option1), 0, -1); } else if (!strcmp (entry_name, "option2")) { g_free (connection->option2); connection->option2 = gtk_editable_get_chars (GTK_EDITABLE (gkdial->cp_entry_option2), 0, -1); } }