/*
- * "$Id: client.c 5335 2006-03-24 02:56:20Z mike $"
+ * "$Id: client.c 5491 2006-05-04 20:53:35Z mike $"
*
* Client routines for the Common UNIX Printing System (CUPS) scheduler.
*
* is_path_absolute() - Is a path absolute and free of relative elements.
* make_certificate() - Make a self-signed SSL/TLS certificate.
* pipe_command() - Pipe the output of a command to the remote client.
- * send_file() - Send a file via HTTP.
+ * write_file() - Send a file via HTTP.
*/
/*
#endif /* HAVE_GNUTLS */
static int pipe_command(cupsd_client_t *con, int infile, int *outfile,
char *command, char *options, int root);
-static int send_file(cupsd_client_t *con, http_status_t code,
- char *filename, char *type,
- struct stat *filestats);
+static int write_file(cupsd_client_t *con, http_status_t code,
+ char *filename, char *type,
+ struct stat *filestats);
/*
SSL *conn; /* Connection for encryption */
unsigned long error; /* Error code */
#elif defined(HAVE_GNUTLS)
- http_tls_t *conn; /* TLS connection information */
- int error; /* Error code */
+ http_tls_t *conn; /* TLS connection information */
+ int error; /* Error code */
gnutls_certificate_server_credentials *credentials;
/* TLS credentials */
+# elif defined(HAVE_CDSASSL)
+ http_tls_t *conn; /* CDSA connection information */
#endif /* HAVE_LIBSSL */
free(conn);
# elif defined(HAVE_CDSASSL)
- while (SSLClose((SSLContextRef)con->http.tls) == errSSLWouldBlock)
+ conn = (http_tls_t *)(con->http.tls);
+
+ while (SSLClose(conn->session) == errSSLWouldBlock)
usleep(1000);
- SSLDisposeContext((SSLContextRef)con->http.tls);
+ SSLDisposeContext(conn->session);
+
+ if (conn->certsArray)
+ CFRelease(conn->certsArray);
+
+ free(conn);
# endif /* HAVE_LIBSSL */
con->http.tls = NULL;
con->start = time(NULL);
con->operation = con->http.state;
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %s %s HTTP/%d.%d", con->http.fd,
- operation, con->uri,
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %s %s HTTP/%d.%d",
+ con->http.fd, operation, con->uri,
con->http.version / 100, con->http.version % 100);
con->http.status = HTTP_OK;
else
snprintf(locale, sizeof(locale), "%s.%s",
con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE], DefaultCharset);
-
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "cupsdReadClient: %d Browser asked for language \"%s\"...",
+ con->http.fd, locale);
+
con->language = cupsLangGet(locale);
}
else
else
snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
- if (!send_file(con, HTTP_OK, filename, line, &filestats))
+ if (!write_file(con, HTTP_OK, filename, line, &filestats))
return (cupsdCloseClient(con));
}
}
*/
if (!strncasecmp(buf, "Location:", 9))
+ {
cupsdSendHeader(con, HTTP_SEE_OTHER, NULL);
+ if (httpPrintf(HTTP(con), "Content-Length: 0\r\n") < 0)
+ return (0);
+ }
else if (!strncasecmp(buf, "Status:", 7))
cupsdSendError(con, atoi(buf + 7));
else
while (*ptr != '\0' && *ptr != ';')
ptr ++;
}
+ else
+ ptr ++;
}
cupsdLogMessage(CUPSD_LOG_DEBUG2,
* Create the SSL object and perform the SSL handshake...
*/
- conn = (http_tls_t *)malloc(sizeof(gnutls_session));
+ conn = (http_tls_t *)malloc(sizeof(http_tls_t));
if (conn == NULL)
return (0);
return (1);
# elif defined(HAVE_CDSASSL)
- OSStatus error; /* Error info */
- SSLContextRef conn; /* New connection */
- CFArrayRef certificatesArray; /* Array containing certificates */
- int allowExpired; /* Allow expired certificates? */
- int allowAnyRoot; /* Allow any root certificate? */
+ OSStatus error; /* Error code */
+ http_tls_t *conn; /* CDSA connection information */
+ cdsa_conn_ref_t u; /* Connection reference union */
- conn = NULL;
- error = SSLNewContext(true, &conn);
- allowExpired = 1;
- allowAnyRoot = 1;
+ if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL)
+ return (0);
- certificatesArray = get_cdsa_server_certs();
+ error = 0;
+ conn->session = NULL;
+ conn->certsArray = get_cdsa_server_certs();
- if (!certificatesArray)
+ if (!conn->certsArray)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"EncryptClient: Could not find signing key in keychain "
}
if (!error)
- error = SSLSetIOFuncs(conn, _httpReadCDSA, _httpWriteCDSA);
+ error = SSLNewContext(true, &conn->session);
if (!error)
- error = SSLSetProtocolVersion(conn, kSSLProtocol3);
+ error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA);
if (!error)
- error = SSLSetConnection(conn, (SSLConnectionRef)con->http.fd);
+ error = SSLSetProtocolVersion(conn->session, kSSLProtocol3);
if (!error)
- error = SSLSetPeerDomainName(conn, ServerName, strlen(ServerName) + 1);
+ {
+ /*
+ * Use a union to resolve warnings about int/pointer size mismatches...
+ */
- /* have to do these options before setting server certs */
- if (!error && allowExpired)
- error = SSLSetAllowsExpiredCerts(conn, true);
+ u.connection = NULL;
+ u.sock = con->http.fd;
+ error = SSLSetConnection(conn->session, u.connection);
+ }
- if (!error && allowAnyRoot)
- error = SSLSetAllowsAnyRoot(conn, true);
+ if (!error)
+ error = SSLSetAllowsExpiredCerts(conn->session, true);
if (!error)
- error = SSLSetCertificate(conn, certificatesArray);
+ error = SSLSetAllowsAnyRoot(conn->session, true);
- if (certificatesArray)
- {
- CFRelease(certificatesArray);
- certificatesArray = NULL;
- }
+ if (!error)
+ error = SSLSetCertificate(conn->session, conn->certsArray);
if (!error)
{
* Perform SSL/TLS handshake
*/
- while ((error = SSLHandshake(conn)) == errSSLWouldBlock)
+ while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock)
usleep(1000);
}
con->http.error = error;
con->http.status = HTTP_ERROR;
- if (conn != NULL)
- SSLDisposeContext(conn);
+ if (conn->session)
+ SSLDisposeContext(conn->session);
+
+ if (conn->certsArray)
+ CFRelease(conn->certsArray);
+
+ free(conn);
return (0);
}
else
return (NULL);
}
- else if (con->language != NULL)
+ else if (con->language)
snprintf(filename, len, "%s/%s%s", DocumentRoot, con->language->language,
- con->uri);
+ con->uri);
else
snprintf(filename, len, "%s%s", DocumentRoot, con->uri);
* then fallback to the default one...
*/
- if ((status = stat(filename, filestats)) != 0 && con->language != NULL)
+ if ((status = stat(filename, filestats)) != 0 && con->language &&
+ strncmp(con->uri, "/ppd/", 5) &&
+ strncmp(con->uri, "/admin/conf/", 12) &&
+ strncmp(con->uri, "/admin/log/", 11))
{
/*
- * Drop the language prefix and try the current directory...
+ * Drop the country code...
*/
- if (strncmp(con->uri, "/ppd/", 5) &&
- strncmp(con->uri, "/admin/conf/", 12) &&
- strncmp(con->uri, "/admin/log/", 11))
+ char ll[3]; /* Short language name */
+
+
+ strlcpy(ll, con->language->language, sizeof(ll));
+ snprintf(filename, len, "%s/%s%s", DocumentRoot, ll, con->uri);
+
+ if ((ptr = strchr(filename, '?')) != NULL)
+ *ptr = '\0';
+
+ if ((status = stat(filename, filestats)) != 0)
{
+ /*
+ * Drop the language prefix and try the root directory...
+ */
+
snprintf(filename, len, "%s%s", DocumentRoot, con->uri);
if ((ptr = strchr(filename, '?')) != NULL)
* Tell the CGI if we are using encryption...
*/
- if (con->http.encryption == HTTP_ENCRYPT_ALWAYS)
+ if (con->http.tls)
envp[envc ++] = "HTTPS=ON";
/*
/*
- * 'send_file()' - Send a file via HTTP.
+ * 'write_file()' - Send a file via HTTP.
*/
static int /* O - 0 on failure, 1 on success */
-send_file(cupsd_client_t *con, /* I - Client connection */
- http_status_t code, /* I - HTTP status */
- char *filename, /* I - Filename */
- char *type, /* I - File type */
- struct stat *filestats) /* O - File information */
+write_file(cupsd_client_t *con, /* I - Client connection */
+ http_status_t code, /* I - HTTP status */
+ char *filename, /* I - Filename */
+ char *type, /* I - File type */
+ struct stat *filestats) /* O - File information */
{
con->file = open(filename, O_RDONLY);
- cupsdLogMessage(CUPSD_LOG_DEBUG, "send_file: %d file=%d", con->http.fd,
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "write_file: %d file=%d", con->http.fd,
con->file);
if (con->file < 0)
con->http._data_remaining = INT_MAX;
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_file: Adding fd %d to OutputSet...", con->http.fd);
+ "write_file: Adding fd %d to OutputSet...", con->http.fd);
FD_SET(con->http.fd, OutputSet);
/*
- * End of "$Id: client.c 5335 2006-03-24 02:56:20Z mike $".
+ * End of "$Id: client.c 5491 2006-05-04 20:53:35Z mike $".
*/