]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
This commit was manufactured by cvs2svn to create branch 'branch-1.2'.
author(no author) <(no author)@7a7537e8-13f0-0310-91df-b6672ffda945>
Sun, 31 Aug 2003 11:25:35 +0000 (11:25 +0000)
committer(no author) <(no author)@7a7537e8-13f0-0310-91df-b6672ffda945>
Sun, 31 Aug 2003 11:25:35 +0000 (11:25 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/branches/branch-1.2@3895 7a7537e8-13f0-0310-91df-b6672ffda945

cups/auth.c [new file with mode: 0644]
cups/getputfile.c [new file with mode: 0644]

diff --git a/cups/auth.c b/cups/auth.c
new file mode 100644 (file)
index 0000000..e41ba94
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * "$Id: auth.c,v 1.1 2003/08/29 21:26:40 mike Exp $"
+ *
+ *   Authentication functions for the Common UNIX Printing System (CUPS).
+ *
+ *   Copyright 1997-2003 by Easy Software Products.
+ *
+ *   These coded instructions, statements, and computer programs are the
+ *   property of Easy Software Products and are protected by Federal
+ *   copyright law.  Distribution and use rights are outlined in the file
+ *   "LICENSE.txt" which should have been included with this file.  If this
+ *   file is missing or damaged please contact Easy Software Products
+ *   at:
+ *
+ *       Attn: CUPS Licensing Information
+ *       Easy Software Products
+ *       44141 Airport View Drive, Suite 204
+ *       Hollywood, Maryland 20636-3111 USA
+ *
+ *       Voice: (301) 373-9603
+ *       EMail: cups-info@cups.org
+ *         WWW: http://www.cups.org
+ *
+ *   This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ *   cupsDoAuthentication() - Authenticate a request...
+ *   cups_local_auth()      - Get the local authorization certificate if
+ *                            available/applicable...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include "ipp.h"
+#include "language.h"
+#include "string.h"
+#include "debug.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#if defined(WIN32) || defined(__EMX__)
+#  include <io.h>
+#else
+#  include <unistd.h>
+#endif /* WIN32 || __EMX__ */
+
+
+/*
+ * Local functions...
+ */
+
+static int     cups_local_auth(http_t *http);
+
+
+/*
+ * 'cupsDoAuthentication()' - Authenticate a request...
+ */
+
+int                                    /* O - 0 on success, -1 on error */
+cupsDoAuthentication(http_t     *http, /* I - HTTP connection to server */
+                     const char *method,/* I - Request method (GET, POST, PUT) */
+                    const char *resource)
+                                       /* I - Resource path */
+{
+  const char   *password;              /* Password string */
+  char         prompt[1024],           /* Prompt for user */
+               realm[HTTP_MAX_VALUE],  /* realm="xyz" string */
+               nonce[HTTP_MAX_VALUE],  /* nonce="xyz" string */
+               encode[512];            /* Encoded username:password */
+
+
+ /*
+  * Clear the current authentication string...
+  */
+
+  http->authstring[0] = '\0';
+
+ /*
+  * See if we can do local authentication...
+  */
+
+  if (!cups_local_auth(http))
+    return (0);
+
+ /*
+  * Nope, see if we should retry the current digest password...
+  */
+
+  if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0 ||
+      http->digest_tries > 1 || !http->userpass[0])
+  {
+   /*
+    * Nope - get a new password from the user...
+    */
+
+    snprintf(prompt, sizeof(prompt), "Password for %s on %s? ", cupsUser(),
+             http->hostname);
+
+    http->digest_tries  = 0;
+    http->userpass[0]   = '\0';
+
+    if ((password = cupsGetPassword(prompt)) == NULL)
+      return (-1);
+
+    if (!password[0])
+      return (-1);
+
+    snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(),
+             password);
+  }
+  else
+    http->digest_tries ++;
+
+ /*
+  * Got a password; encode it for the server...
+  */
+
+  if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0)
+  {
+   /*
+    * Basic authentication...
+    */
+
+    httpEncode64(encode, http->userpass);
+    snprintf(http->authstring, sizeof(http->authstring), "Basic %s", encode);
+  }
+  else
+  {
+   /*
+    * Digest authentication...
+    */
+
+    httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
+    httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce);
+
+    httpMD5(cupsUser(), realm, strchr(http->userpass, ':') + 1, encode);
+    httpMD5Final(nonce, "POST", resource, encode);
+    snprintf(http->authstring, sizeof(http->authstring),
+            "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", "
+            "response=\"%s\"", cupsUser(), realm, nonce, encode);
+  }
+
+  return (0);
+}
+
+
+/*
+ * 'cups_local_auth()' - Get the local authorization certificate if
+ *                       available/applicable...
+ */
+
+static int                             /* O - 0 if available, -1 if not */
+cups_local_auth(http_t *http)          /* I - HTTP connection to server */
+{
+#if defined(WIN32) || defined(__EMX__)
+ /*
+  * Currently WIN32 and OS-2 do not support the CUPS server...
+  */
+
+  return (-1);
+#else
+  int          pid;                    /* Current process ID */
+  FILE         *fp;                    /* Certificate file */
+  char         filename[1024],         /* Certificate filename */
+               certificate[33];        /* Certificate string */
+  const char   *root;                  /* Server root directory */
+
+
+  DEBUG_printf(("cups_local_auth(http=%p) hostaddr=%08x, hostname=\"%s\"\n",
+                http, ntohl(http->hostaddr.sin_addr.s_addr), http->hostname));
+
+ /*
+  * See if we are accessing localhost...
+  */
+
+  if (ntohl(http->hostaddr.sin_addr.s_addr) != 0x7f000001 &&
+      strcasecmp(http->hostname, "localhost") != 0)
+  {
+    DEBUG_puts("cups_local_auth: Not a local connection!");
+    return (-1);
+  }
+
+ /*
+  * Try opening a certificate file for this PID.  If that fails,
+  * try the root certificate...
+  */
+
+  if ((root = getenv("CUPS_SERVERROOT")) == NULL)
+    root = CUPS_SERVERROOT;
+
+  pid = getpid();
+  snprintf(filename, sizeof(filename), "%s/certs/%d", root, pid);
+  if ((fp = fopen(filename, "r")) == NULL && pid > 0)
+  {
+    DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
+                  filename, strerror(errno)));
+
+    snprintf(filename, sizeof(filename), "%s/certs/0", root);
+    fp = fopen(filename, "r");
+  }
+
+  if (fp == NULL)
+  {
+    DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
+                  filename, strerror(errno)));
+    return (-1);
+  }
+
+ /*
+  * Read the certificate from the file...
+  */
+
+  fgets(certificate, sizeof(certificate), fp);
+  fclose(fp);
+
+ /*
+  * Set the authorization string and return...
+  */
+
+  snprintf(http->authstring, sizeof(http->authstring), "Local %s", certificate);
+
+  DEBUG_printf(("cups_local_auth: Returning authstring = \"%s\"\n",
+                authstring));
+
+  return (0);
+#endif /* WIN32 || __EMX__ */
+}
+
+
+/*
+ * End of "$Id: auth.c,v 1.1 2003/08/29 21:26:40 mike Exp $".
+ */
diff --git a/cups/getputfile.c b/cups/getputfile.c
new file mode 100644 (file)
index 0000000..bb38244
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * "$Id: getputfile.c,v 1.1 2003/08/29 21:26:41 mike Exp $"
+ *
+ *   Get/put file functions for the Common UNIX Printing System (CUPS).
+ *
+ *   Copyright 1997-2003 by Easy Software Products.
+ *
+ *   These coded instructions, statements, and computer programs are the
+ *   property of Easy Software Products and are protected by Federal
+ *   copyright law.  Distribution and use rights are outlined in the file
+ *   "LICENSE.txt" which should have been included with this file.  If this
+ *   file is missing or damaged please contact Easy Software Products
+ *   at:
+ *
+ *       Attn: CUPS Licensing Information
+ *       Easy Software Products
+ *       44141 Airport View Drive, Suite 204
+ *       Hollywood, Maryland 20636-3111 USA
+ *
+ *       Voice: (301) 373-9603
+ *       EMail: cups-info@cups.org
+ *         WWW: http://www.cups.org
+ *
+ *   This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ *   cupsGetFd()   - Get a file from the server.
+ *   cupsGetFile() - Get a file from the server.
+ *   cupsPutFd()   - Put a file on the server.
+ *   cupsPutFile() - Put a file on the server.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include "ipp.h"
+#include "language.h"
+#include "string.h"
+#include "debug.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#if defined(WIN32) || defined(__EMX__)
+#  include <io.h>
+#else
+#  include <unistd.h>
+#endif /* WIN32 || __EMX__ */
+
+
+/*
+ * 'cupsGetFd()' - Get a file from the server.
+ */
+
+http_status_t                          /* O - Status */
+cupsGetFd(http_t     *http,            /* I - HTTP connection to server */
+         const char *resource,         /* I - Resource name */
+         int        fd)                /* I - File descriptor */
+{
+  int          bytes;                  /* Number of bytes read */
+  char         buffer[8192];           /* Buffer for file */
+  http_status_t        status;                 /* HTTP status from server */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!http || !resource || fd < 0)
+  {
+    if (http)
+      http->error = EINVAL;
+
+    return (HTTP_ERROR);
+  }
+
+ /*
+  * Then send GET requests to the HTTP server...
+  */
+
+  do
+  {
+    httpClearFields(http);
+    httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
+
+    if (httpGet(http, resource))
+    {
+      if (httpReconnect(http))
+      {
+        status = HTTP_ERROR;
+       break;
+      }
+      else
+      {
+        status = HTTP_UNAUTHORIZED;
+        continue;
+      }
+    }
+
+    while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+
+    if (status == HTTP_UNAUTHORIZED)
+    {
+     /*
+      * Flush any error message...
+      */
+
+      httpFlush(http);
+
+     /*
+      * See if we can do authentication...
+      */
+
+      if (cupsDoAuthentication(http, "GET", resource))
+        break;
+
+      httpReconnect(http);
+
+      continue;
+    }
+    else if (status == HTTP_ERROR)
+    {
+#ifdef WIN32
+      if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH)
+#else
+      if (http->error != ENETDOWN && http->error != ENETUNREACH)
+#endif /* WIN32 */
+        continue;
+      else
+        break;
+    }
+#ifdef HAVE_LIBSSL
+    else if (status == HTTP_UPGRADE_REQUIRED)
+    {
+     /*
+      * Flush any error message...
+      */
+
+      httpFlush(http);
+
+     /*
+      * Upgrade with encryption...
+      */
+
+      httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+
+     /*
+      * Try again, this time with encryption enabled...
+      */
+
+      continue;
+    }
+#endif /* HAVE_LIBSSL */
+  }
+  while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED ||
+         status == HTTP_ERROR);
+
+ /*
+  * See if we actually got the file or an error...
+  */
+
+  if (status == HTTP_OK)
+  {
+   /*
+    * Yes, copy the file...
+    */
+
+    while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
+      write(fd, buffer, bytes);
+  }
+  else
+    httpFlush(http);
+
+ /*
+  * Return the request status...
+  */
+
+  return (status);
+}
+
+
+/*
+ * 'cupsGetFile()' - Get a file from the server.
+ */
+
+http_status_t                          /* O - Status */
+cupsGetFile(http_t     *http,          /* I - HTTP connection to server */
+           const char *resource,       /* I - Resource name */
+           const char *filename)       /* I - Filename */
+{
+  int          fd;                     /* File descriptor */
+  http_status_t        status;                 /* Status */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!http || !resource || !filename)
+  {
+    if (http)
+      http->error = EINVAL;
+
+    return (HTTP_ERROR);
+  }
+
+ /*
+  * Create the file...
+  */
+
+  if ((fd = open(filename, O_WRONLY | O_EXCL | O_TRUNC)) < 0)
+  {
+   /*
+    * Couldn't open the file!
+    */
+
+    http->error = errno;
+
+    return (HTTP_ERROR);
+  }
+
+ /*
+  * Get the file...
+  */
+
+  status = cupsGetFd(http, resource, fd);
+
+ /*
+  * If the file couldn't be gotten, then remove the file...
+  */
+
+  close(fd);
+
+  if (status != HTTP_OK)
+    unlink(filename);
+
+ /*
+  * Return the HTTP status code...
+  */
+
+  return (status);
+}
+
+
+/*
+ * 'cupsPutFd()' - Put a file on the server.
+ */
+
+http_status_t                          /* O - Status */
+cupsPutFd(http_t     *http,            /* I - HTTP connection to server */
+          const char *resource,                /* I - Resource name */
+         int        fd)                /* I - File descriptor */
+{
+  int          bytes;                  /* Number of bytes read */
+  char         buffer[8192];           /* Buffer for file */
+  http_status_t        status;                 /* HTTP status from server */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!http || !resource || fd < 0)
+  {
+    if (http)
+      http->error = EINVAL;
+
+    return (HTTP_ERROR);
+  }
+
+ /*
+  * Then send PUT requests to the HTTP server...
+  */
+
+  do
+  {
+    httpClearFields(http);
+    httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
+    httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked");
+
+    if (httpPut(http, resource))
+    {
+      if (httpReconnect(http))
+      {
+        status = HTTP_ERROR;
+       break;
+      }
+      else
+      {
+        status = HTTP_UNAUTHORIZED;
+        continue;
+      }
+    }
+
+   /*
+    * Copy the file...
+    */
+
+    lseek(fd, 0, SEEK_SET);
+
+    status = HTTP_CONTINUE;
+
+    while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
+      if (httpCheck(http))
+      {
+        if ((status = httpUpdate(http)) != HTTP_CONTINUE)
+          break;
+      }
+      else
+        httpWrite(http, buffer, bytes);
+
+    if (status == HTTP_CONTINUE)
+    {
+      httpWrite(http, buffer, 0);
+
+      while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+    }
+
+    if (status == HTTP_UNAUTHORIZED)
+    {
+     /*
+      * Flush any error message...
+      */
+
+      httpFlush(http);
+
+     /*
+      * See if we can do authentication...
+      */
+
+      if (cupsDoAuthentication(http, "PUT", resource))
+        break;
+
+      httpReconnect(http);
+
+      continue;
+    }
+    else if (status == HTTP_ERROR)
+    {
+#ifdef WIN32
+      if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH)
+#else
+      if (http->error != ENETDOWN && http->error != ENETUNREACH)
+#endif /* WIN32 */
+        continue;
+      else
+        break;
+    }
+#ifdef HAVE_LIBSSL
+    else if (status == HTTP_UPGRADE_REQUIRED)
+    {
+      /* Flush any error message... */
+      httpFlush(http);
+
+      /* Upgrade with encryption... */
+      httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+
+      /* Try again, this time with encryption enabled... */
+      continue;
+    }
+#endif /* HAVE_LIBSSL */
+  }
+  while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED ||
+         status == HTTP_ERROR);
+
+ /*
+  * See if we actually put the file or an error...
+  */
+
+  if (status != HTTP_CREATED)
+    httpFlush(http);
+
+  return (status);
+}
+
+
+/*
+ * 'cupsPutFile()' - Put a file on the server.
+ */
+
+http_status_t                          /* O - Status */
+cupsPutFile(http_t     *http,          /* I - HTTP connection to server */
+            const char *resource,      /* I - Resource name */
+           const char *filename)       /* I - Filename */
+{
+  int          fd;                     /* File descriptor */
+  http_status_t        status;                 /* Status */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!http || !resource || !filename)
+  {
+    if (http)
+      http->error = EINVAL;
+
+    return (HTTP_ERROR);
+  }
+
+ /*
+  * Open the local file...
+  */
+
+  if ((fd = open(filename, O_RDONLY)) < 0)
+  {
+   /*
+    * Couldn't open the file!
+    */
+
+    http->error = errno;
+
+    return (HTTP_ERROR);
+  }
+
+ /*
+  * Put the file...
+  */
+
+  status = cupsPutFd(http, resource, fd);
+
+  close(fd);
+
+  return (status);
+}
+
+
+/*
+ * End of "$Id: getputfile.c,v 1.1 2003/08/29 21:26:41 mike Exp $".
+ */