355b4669e025ff377602b6fc7caaf30dbc218371jacobs * CDDL HEADER START
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * The contents of this file are subject to the terms of the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Common Development and Distribution License (the "License").
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * You may not use this file except in compliance with the License.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * See the License for the specific language governing permissions
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * and limitations under the License.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * When distributing Covered Code, include this CDDL HEADER in each
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * If applicable, add the following below this CDDL HEADER, with the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * fields enclosed by brackets "[]" replaced with your own identifying
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * information: Portions Copyright [yyyy] [name of copyright owner]
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * CDDL HEADER END
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Use is subject to license terms.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/* $Id: ipp-support.c 148 2006-04-25 16:54:17Z njacobs $ */
223f6c28404c8d330c123e98936160b8da9a26b2jacobsstatic void ipp_add_printer_uri(service_t *svc, char *name,
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_initialize_request(service_t *svc, papi_attribute_t ***request,
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_initialize_operational_attributes(service_t *svc, papi_attribute_t ***op,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char *charset = "utf-8"; /* default to UTF-8 encoding */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * All IPP requests must contain the following:
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * attributes-charset (UTF-8)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * attributes-natural-language (our current locale)
223f6c28404c8d330c123e98936160b8da9a26b2jacobs * (object identifier) printer-uri/job-id or job-uri
223f6c28404c8d330c123e98936160b8da9a26b2jacobs * requesting-user-name (process user or none)
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes "attributes-natural-language", language);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * if our euid is 0 "super user", we will allow the system supplied
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * user name to be overridden, if the requestor wants to.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (geteuid() == 0) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifndef OPID_CUPS_GET_DEFAULT /* for servers that will enumerate */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* OPID_CUPS_GET_DEFAULT */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* we must be connected to find the default destination */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_initialize_request(svc, &request, OPID_CUPS_GET_DEFAULT);
223f6c28404c8d330c123e98936160b8da9a26b2jacobs ipp_initialize_operational_attributes(svc, &op, NULL, -1);
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes "requested-attributes", "printer-uri-supported");
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes "operational-attributes-group", op);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiAttributeListGetString(op, NULL, "printer-uri", &tmp);
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_add_printer_uri(service_t *svc, char *name, papi_attribute_t ***op)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (strstr(name, "://") == NULL) { /* not in URI form */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* not the "default" */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(buf, sizeof (buf), "%s/%s", svc->name, name);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiAttributeListAddString(op, PAPI_ATTR_EXCL, "printer-uri", uri);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* save the printer-uri's path to be used by http POST request */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if ((uri_from_string(uri, &tmp) == 0) && (tmp != NULL)) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * don't actually write anything, just add to the total size and return the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * size of what would be written, so we can figure out how big the request
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * is going to be.
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_request_write(void *fd, void *buffer, size_t length)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs printf("ipp_request_write(0x%8.8x, 0x%8.8x, %d)\n", fd, buffer, length);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs httpDumpData(stdout, "ipp_request_write:", buffer, length);
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_request_read(void *fd, void *buffer, size_t length)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs while ((rc = httpRead(svc->connection, p, i)) != i) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs printf("ipp_request_read(0x%8.8x, 0x%8.8x, %d) = %d\n",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs httpDumpData(stdout, "ipp_request_read:", buffer, length);
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_send_initial_request_block(service_t *svc, papi_attribute_t **request,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* calculate the request size */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs (void) ipp_write_message(&size_calculate, &chunk_size, request);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* Fill in the HTTP Header information */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (svc->transfer_encoding == TRANSFER_ENCODING_CHUNKED)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs httpSetField(svc->connection, HTTP_FIELD_TRANSFER_ENCODING,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs sprintf(length, "%lu", (unsigned long)(file_size + chunk_size));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs httpSetField(svc->connection, HTTP_FIELD_CONTENT_LENGTH,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs httpSetField(svc->connection, HTTP_FIELD_CONTENT_TYPE,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs httpSetField(svc->connection, HTTP_FIELD_AUTHORIZATION,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* flush any state information about this connection */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* if we have don't have a POST path, use the service uri path */
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka if ((svc->post == NULL) && (svc->uri->path))
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* send the HTTP POST message for the IPP request */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* if the POST fails, return the error */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* build the request chunk */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs result = ipp_write_message(&build_chunk, &ptr, request);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs printf("request: %d (0x%x) bytes\n", chunk_size, chunk_size);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* send the actual IPP request */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (ipp_request_write(svc, chunk, chunk_size) != chunk_size)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if ((svc == NULL) || (svc->connection == NULL) || (svc->name == NULL))
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (-1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* if the passphrase is not set, use the Authentication Callback */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (((svc->password == NULL) || (svc->password[0] == '\0')) &&
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* if there is still no passphrase, we have to fail */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (-1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE],
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(plain, sizeof (plain), "%s:%s", user, passphrase);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(http->authstring, sizeof (http->authstring),
355b4669e025ff377602b6fc7caaf30dbc218371jacobs } else if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE],
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(line, sizeof (line), "%s:%s:%s", user, realm,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(line, sizeof (line), "%s:%s:%s", urp, mr, nonce);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(http->authstring, sizeof (http->authstring),
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", "
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes "uri=\"%s\", response=\"%s\"", user, realm, nonce, uri,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (0);
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_status_info(service_t *svc, papi_attribute_t **response)
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes "operational-attributes-group", &operational);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes "detailed-status-message", message);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiAttributeListGetInteger(response, NULL, "status-code", &status);
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_send_request_with_file(service_t *svc, papi_attribute_t **request,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs fprintf(stderr, "\nIPP-REQUEST: (%s)", (file ? file : ""));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * if we are sending a file, open it and include it's size in the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * message size.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs detailed_error(svc, "%s: %s", file, strerror(errno));
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes } else if (strcmp("standard input", file) != 0) {
a5669307eaef64af8519feb70d42f0aa0e7ec21aJonathan Cowper-Andrewes gettext("Cannot access file: %s: %s"),
a5669307eaef64af8519feb70d42f0aa0e7ec21aJonathan Cowper-Andrewes return (PAPI_DOCUMENT_ACCESS_ERROR);
95c2d3023b88b9097d9822eb47ace5466e6d1cf4Jonathan Cowper-Andrewes "Zero byte (empty) file: %s", file);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs result = ipp_send_initial_request_block(svc, request, size);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* send the file contents if we have it */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* update our connection info */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * If the transport was built with TLS support, we can
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * try to use it.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs httpEncryption(svc->connection, HTTP_ENCRYPT_REQUIRED);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* read the IPP response */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs result = ipp_read_message(&ipp_request_read, svc, response,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs fprintf(stderr, "\nIPP-RESPONSE: (%s) (%s)", (file ? file : ""),
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_send_request(service_t *svc, papi_attribute_t **request,