Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- gtkcupsutils-orig.c 2011-08-16 04:30:52.000000000 +0200
- +++ gtkcupsutils-new.c 2014-12-23 17:04:11.000000000 +0100
- @@ -83,6 +83,20 @@
- _get_read_data
- };
- +/* Very ugly hack: cups has a stupid synchronous password callback
- + * that doesn't even take the request or user data parameters, so
- + * we have to use a static variable to pass the password to it.
- + * Not threadsafe !
- + * The callback sets cups_password to NULL to signal that the
- + * password has been used.
- + */
- +static char *cups_username = NULL;
- +static char *cups_password = NULL;
- +static char *cups_password_backup = NULL;
- +static int cups_password_bad_count = 0;
- +#define GTK2_CUPS_STRINGS_LENGTH 255
- +
- +
- static void
- gtk_cups_result_set_error (GtkCupsResult *result,
- GtkCupsErrorType error_type,
- @@ -911,25 +925,138 @@
- }
- }
- -/* Very ugly hack: cups has a stupid synchronous password callback
- - * that doesn't even take the request or user data parameters, so
- - * we have to use a static variable to pass the password to it.
- - * Not threadsafe !
- - * The callback sets cups_password to NULL to signal that the
- - * password has been used.
- - */
- -static char *cups_password;
- -static char *cups_username;
- static const char *
- -passwordCB (const char *prompt)
- +return_cups_password (const char *prompt)
- {
- - char *pwd = cups_password;
- - cups_password = NULL;
- -
- - cupsSetUser (cups_username);
- + return cups_password;
- +}
- - return pwd;
- +static const char *
- +passwordCB (const char *prompt)
- +{
- + char *pwd = NULL;
- + char *env;
- + char *str1;
- + char *str2;
- +
- + int pipe_in[2];
- + int pipe_ex[2];
- + FILE *pipe_in_1;
- + FILE *pipe_ex_0;
- + pid_t pid;
- + int status;
- +
- + if(cups_password == NULL)
- + {
- + cups_password = malloc(GTK2_CUPS_STRINGS_LENGTH);
- + }
- + /* Give back a saved (probably right) password */
- + if(cups_password_backup != NULL)
- + {
- + strcpy(cups_password, cups_password_backup);
- + pwd = cups_password;
- + }
- + else
- + {
- + env = getenv("CUPS_ASKPASS");
- + if(env != NULL)
- + {
- + pipe(pipe_in);
- + pipe(pipe_ex);
- + pid = fork();
- + if(pid == 0)
- + {
- + char *args[3] = {NULL, "stdin", NULL};
- + args[0] = env;
- + close(pipe_in[1]);
- + dup2(pipe_in[0], STDIN_FILENO);
- + close(pipe_ex[0]);
- + dup2(pipe_ex[1], STDOUT_FILENO);
- + exit(execvp(env, args));
- + }
- + else if(pid > 0)
- + {
- + str1 = malloc(GTK2_CUPS_STRINGS_LENGTH);
- + str2 = malloc(GTK2_CUPS_STRINGS_LENGTH);
- +
- + close(pipe_in[0]);
- + close(pipe_ex[1]);
- + pipe_in_1 = fdopen(pipe_in[1], "w");
- + pipe_ex_0 = fdopen(pipe_ex[0], "r");
- +
- + fprintf(pipe_in_1, "service=cups\nprompt=%s\nusername=%s\nservername=%s\nanswer=username,password\n", prompt, cups_username == NULL ? cupsUser() == NULL ? "" : cupsUser() : cups_username, cupsServer());
- + fflush(pipe_in_1);
- + close(pipe_in[1]);
- +
- + if(fgets(str1, GTK2_CUPS_STRINGS_LENGTH, pipe_ex_0) == NULL)
- + {
- + str1 = NULL;
- + }
- + else if(str1[strlen(str1)-1] == '\n')
- + {
- + str1[strlen(str1)-1] = '\0';
- + }
- + if(fgets(str2, GTK2_CUPS_STRINGS_LENGTH, pipe_ex_0) == NULL)
- + {
- + str2 = NULL;
- + }
- + else if(str2[strlen(str2)-1] == '\n')
- + {
- + str2[strlen(str2)-1] = '\0';
- + }
- + close(pipe_ex[0]);
- +
- + if(waitpid(pid, &status, 0) != -1)
- + {
- + if(WEXITSTATUS(status) == 0)
- + {
- + if(str1 != NULL && str1[0] != '\0')
- + {
- + if(cups_username == NULL)
- + {
- + cups_username = malloc(GTK2_CUPS_STRINGS_LENGTH);
- + }
- + strncpy(cups_username, str1, GTK2_CUPS_STRINGS_LENGTH);
- + cupsSetUser(cups_username);
- + }
- + strncpy(cups_password, str2, GTK2_CUPS_STRINGS_LENGTH);
- + pwd = cups_password;
- + }
- + else
- + {
- + warnx("%s: %s: exited %d", __FILE__, env, WEXITSTATUS(status));
- + }
- + }
- + else
- + {
- + warn("%s: waitpid", __FILE__);
- + }
- +
- + free(str1);
- + free(str2);
- + }
- + else
- + {
- + close(pipe_in[0]);
- + close(pipe_in[1]);
- + close(pipe_ex[0]);
- + close(pipe_ex[1]);
- + warn("%s: fork", __FILE__);
- + }
- + }
- + else
- + {
- + warnx("%s: No CUPS_ASKPASS environment is set.", __FILE__);
- + }
- + }
- +
- + if(pwd == NULL)
- + {
- + free(cups_password);
- + cups_password = NULL;
- + }
- + return pwd;
- }
- static void
- @@ -946,6 +1073,10 @@
- if (http_status == HTTP_CONTINUE)
- {
- + if(cups_password_backup != NULL && cups_password != NULL)
- + {
- + strcpy(cups_password, cups_password_backup);
- + }
- goto again;
- }
- else if (http_status == HTTP_UNAUTHORIZED)
- @@ -953,15 +1084,25 @@
- int auth_result = -1;
- httpFlush (request->http);
- if (request->password_state == GTK_CUPS_PASSWORD_APPLIED)
- {
- request->password_state = GTK_CUPS_PASSWORD_NOT_VALID;
- request->state = GTK_CUPS_POST_AUTH;
- request->need_password = TRUE;
- return;
- }
- + cups_password_bad_count++;
- + if((cups_password_bad_count % 2) == 0)
- + {
- + g_free(cups_password_backup);
- + cups_password_backup = NULL;
- + }
- +
- /* Negotiate */
- if (strncmp (httpGetField (request->http, HTTP_FIELD_WWW_AUTHENTICATE), "Negotiate", 9) == 0)
- {
- @@ -972,8 +1113,6 @@
- {
- if (request->password_state == GTK_CUPS_PASSWORD_NONE)
- {
- - cups_password = g_strdup ("");
- - cups_username = request->username;
- cupsSetPasswordCB (passwordCB);
- /* This call success for PeerCred authentication */
- @@ -981,6 +1120,9 @@
- if (auth_result != 0)
- {
- + /* Cancel login */
- + return;
- +
- /* move to AUTH state to let the backend
- * ask for a password
- */
- @@ -992,8 +1134,11 @@
- }
- else
- {
- - cups_password = request->password;
- - cups_username = request->username;
- + if(cups_password == NULL) cups_password = malloc(GTK2_CUPS_STRINGS_LENGTH);
- + if(cups_username == NULL) cups_username = malloc(GTK2_CUPS_STRINGS_LENGTH);
- + strcpy(cups_password, request->password);
- + strcpy(cups_username, request->username);
- + cupsSetPasswordCB(return_cups_password);
- auth_result = cupsDoAuthentication (request->http, "POST", request->resource);
- @@ -1103,7 +1248,7 @@
- }
- request->poll_state = GTK_CUPS_HTTP_IDLE;
- -
- +
- httpFlush (request->http);
- request->last_status = HTTP_CONTINUE;
- @@ -1113,6 +1258,13 @@
- }
- else
- {
- + // Save probably right cups_password
- + if(cups_password_backup != NULL)
- + {
- + g_free(cups_password_backup);
- + }
- + cups_password_backup = g_strdup(cups_password);
- + cups_password_bad_count = 0;
- request->state = GTK_CUPS_POST_READ_RESPONSE;
- return;
- }
Advertisement
Add Comment
Please, Sign In to add comment