Guest User

gtkcupsutils.c

a guest
Dec 23rd, 2014
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.78 KB | None | 0 0
  1. --- gtkcupsutils-orig.c 2011-08-16 04:30:52.000000000 +0200
  2. +++ gtkcupsutils-new.c  2014-12-23 17:04:11.000000000 +0100
  3. @@ -83,6 +83,20 @@
  4.    _get_read_data
  5.  };
  6.  
  7. +/* Very ugly hack: cups has a stupid synchronous password callback
  8. + * that doesn't even take the request or user data parameters, so
  9. + * we have to use a static variable to pass the password to it.
  10. + * Not threadsafe !
  11. + * The callback sets cups_password to NULL to signal that the
  12. + * password has been used.
  13. + */
  14. +static char *cups_username = NULL;
  15. +static char *cups_password = NULL;
  16. +static char *cups_password_backup = NULL;
  17. +static int cups_password_bad_count = 0;
  18. +#define GTK2_CUPS_STRINGS_LENGTH 255
  19. +
  20. +
  21.  static void
  22.  gtk_cups_result_set_error (GtkCupsResult    *result,
  23.                             GtkCupsErrorType  error_type,
  24. @@ -911,25 +925,138 @@
  25.      }
  26.  }
  27.  
  28. -/* Very ugly hack: cups has a stupid synchronous password callback
  29. - * that doesn't even take the request or user data parameters, so
  30. - * we have to use a static variable to pass the password to it.
  31. - * Not threadsafe !
  32. - * The callback sets cups_password to NULL to signal that the
  33. - * password has been used.
  34. - */
  35. -static char *cups_password;
  36. -static char *cups_username;
  37.  
  38.  static const char *
  39. -passwordCB (const char *prompt)
  40. +return_cups_password (const char *prompt)
  41.  {
  42. -  char *pwd = cups_password;
  43. -  cups_password = NULL;
  44. -
  45. -  cupsSetUser (cups_username);
  46. +   return cups_password;
  47. +}
  48.  
  49. -  return pwd;
  50. +static const char *
  51. +passwordCB (const char *prompt)
  52. +{
  53. +   char *pwd = NULL;
  54. +   char *env;
  55. +   char *str1;
  56. +   char *str2;
  57. +
  58. +   int pipe_in[2];
  59. +   int pipe_ex[2];
  60. +   FILE *pipe_in_1;
  61. +   FILE *pipe_ex_0;
  62. +   pid_t pid;
  63. +   int status;
  64. +  
  65. +   if(cups_password == NULL)
  66. +   {
  67. +       cups_password = malloc(GTK2_CUPS_STRINGS_LENGTH);
  68. +   }
  69. +   /* Give back a saved (probably right) password */
  70. +   if(cups_password_backup != NULL)
  71. +   {
  72. +       strcpy(cups_password, cups_password_backup);
  73. +       pwd = cups_password;
  74. +   }
  75. +   else
  76. +   {
  77. +       env = getenv("CUPS_ASKPASS");
  78. +       if(env != NULL)
  79. +       {
  80. +           pipe(pipe_in);
  81. +           pipe(pipe_ex);
  82. +           pid = fork();
  83. +           if(pid == 0)
  84. +           {
  85. +               char *args[3] = {NULL, "stdin", NULL};
  86. +               args[0] = env;
  87. +               close(pipe_in[1]);
  88. +               dup2(pipe_in[0], STDIN_FILENO);
  89. +               close(pipe_ex[0]);
  90. +               dup2(pipe_ex[1], STDOUT_FILENO);
  91. +               exit(execvp(env, args));
  92. +           }
  93. +           else if(pid > 0)
  94. +           {
  95. +               str1 = malloc(GTK2_CUPS_STRINGS_LENGTH);
  96. +               str2 = malloc(GTK2_CUPS_STRINGS_LENGTH);
  97. +  
  98. +               close(pipe_in[0]);
  99. +               close(pipe_ex[1]);
  100. +               pipe_in_1 = fdopen(pipe_in[1], "w");
  101. +               pipe_ex_0 = fdopen(pipe_ex[0], "r");
  102. +  
  103. +               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());
  104. +               fflush(pipe_in_1);
  105. +               close(pipe_in[1]);
  106. +              
  107. +               if(fgets(str1, GTK2_CUPS_STRINGS_LENGTH, pipe_ex_0) == NULL)
  108. +               {
  109. +                   str1 = NULL;
  110. +               }
  111. +               else if(str1[strlen(str1)-1] == '\n')
  112. +               {
  113. +                   str1[strlen(str1)-1] = '\0';
  114. +               }
  115. +               if(fgets(str2, GTK2_CUPS_STRINGS_LENGTH, pipe_ex_0) == NULL)
  116. +               {
  117. +                   str2 = NULL;
  118. +               }
  119. +               else if(str2[strlen(str2)-1] == '\n')
  120. +               {
  121. +                   str2[strlen(str2)-1] = '\0';
  122. +               }
  123. +               close(pipe_ex[0]);
  124. +              
  125. +               if(waitpid(pid, &status, 0) != -1)
  126. +               {
  127. +                   if(WEXITSTATUS(status) == 0)
  128. +                   {
  129. +                       if(str1 != NULL && str1[0] != '\0')
  130. +                       {
  131. +                           if(cups_username == NULL)
  132. +                           {
  133. +                               cups_username = malloc(GTK2_CUPS_STRINGS_LENGTH);
  134. +                           }
  135. +                           strncpy(cups_username, str1, GTK2_CUPS_STRINGS_LENGTH);
  136. +                           cupsSetUser(cups_username);
  137. +                       }
  138. +                       strncpy(cups_password, str2, GTK2_CUPS_STRINGS_LENGTH);
  139. +                       pwd = cups_password;
  140. +                   }
  141. +                   else
  142. +                   {
  143. +                       warnx("%s: %s: exited %d", __FILE__, env, WEXITSTATUS(status));
  144. +                   }
  145. +               }
  146. +               else
  147. +               {
  148. +                   warn("%s: waitpid", __FILE__);
  149. +               }
  150. +              
  151. +               free(str1);
  152. +               free(str2);
  153. +           }
  154. +           else
  155. +           {
  156. +               close(pipe_in[0]);
  157. +               close(pipe_in[1]);
  158. +               close(pipe_ex[0]);
  159. +               close(pipe_ex[1]);
  160. +               warn("%s: fork", __FILE__);
  161. +           }
  162. +       }
  163. +       else
  164. +       {
  165. +           warnx("%s: No CUPS_ASKPASS environment is set.", __FILE__);
  166. +       }
  167. +   }
  168. +  
  169. +   if(pwd == NULL)
  170. +   {
  171. +       free(cups_password);
  172. +       cups_password = NULL;
  173. +   }
  174. +   return pwd;
  175.  }
  176.  
  177.  static void
  178. @@ -946,6 +1073,10 @@
  179.  
  180.    if (http_status == HTTP_CONTINUE)
  181.      {
  182. +      if(cups_password_backup != NULL && cups_password != NULL)
  183. +      {
  184. +       strcpy(cups_password, cups_password_backup);
  185. +      }
  186.        goto again;
  187.      }
  188.    else if (http_status == HTTP_UNAUTHORIZED)
  189. @@ -953,15 +1084,25 @@
  190.        int auth_result = -1;
  191.        httpFlush (request->http);
  192.  
  193.        if (request->password_state == GTK_CUPS_PASSWORD_APPLIED)
  194.          {
  195.            request->password_state = GTK_CUPS_PASSWORD_NOT_VALID;
  196.            request->state = GTK_CUPS_POST_AUTH;
  197.            request->need_password = TRUE;
  198.  
  199.            return;
  200.          }
  201.  
  202. +     cups_password_bad_count++;
  203. +     if((cups_password_bad_count % 2) == 0)
  204. +     {
  205. +       g_free(cups_password_backup);
  206. +       cups_password_backup = NULL;
  207. +     }
  208. +    
  209.        /* Negotiate */
  210.        if (strncmp (httpGetField (request->http, HTTP_FIELD_WWW_AUTHENTICATE), "Negotiate", 9) == 0)
  211.          {
  212. @@ -972,8 +1113,6 @@
  213.          {
  214.            if (request->password_state == GTK_CUPS_PASSWORD_NONE)
  215.              {
  216. -              cups_password = g_strdup ("");
  217. -              cups_username = request->username;
  218.                cupsSetPasswordCB (passwordCB);
  219.  
  220.                /* This call success for PeerCred authentication */
  221. @@ -981,6 +1120,9 @@
  222.  
  223.                if (auth_result != 0)
  224.                  {
  225. +                  /* Cancel login */
  226. +                  return;
  227. +                  
  228.                    /* move to AUTH state to let the backend
  229.                     * ask for a password
  230.                     */
  231. @@ -992,8 +1134,11 @@
  232.              }
  233.            else
  234.              {
  235. -              cups_password = request->password;
  236. -              cups_username = request->username;
  237. +              if(cups_password == NULL) cups_password = malloc(GTK2_CUPS_STRINGS_LENGTH);
  238. +              if(cups_username == NULL) cups_username = malloc(GTK2_CUPS_STRINGS_LENGTH);
  239. +              strcpy(cups_password, request->password);
  240. +              strcpy(cups_username, request->username);
  241. +              cupsSetPasswordCB(return_cups_password);
  242.  
  243.                auth_result = cupsDoAuthentication (request->http, "POST", request->resource);
  244.  
  245. @@ -1103,7 +1248,7 @@
  246.          }
  247.  
  248.        request->poll_state = GTK_CUPS_HTTP_IDLE;
  249. -      
  250. +      
  251.        httpFlush (request->http);
  252.        
  253.        request->last_status = HTTP_CONTINUE;
  254. @@ -1113,6 +1258,13 @@
  255.      }
  256.    else
  257.      {
  258. +     // Save probably right cups_password
  259. +     if(cups_password_backup != NULL)
  260. +     {
  261. +       g_free(cups_password_backup);
  262. +     }
  263. +     cups_password_backup = g_strdup(cups_password);
  264. +     cups_password_bad_count = 0;
  265.        request->state = GTK_CUPS_POST_READ_RESPONSE;
  266.        return;
  267.      }
Advertisement
Add Comment
Please, Sign In to add comment