pappl-client(3)

NAME
pappl-client - pappl client functions

LIBRARY
Printer Application Framework (libpappl, "pkg-config --cflags --libs pappl")

SYNOPSIS
#include <pappl/pappl.h>

typedef struct _pappl_client_s pappl_client_t;

char *
papplClientGetCSRFToken(pappl_client_t *client, char *buffer, size_t bufsize);

char *
papplClientGetCookie(pappl_client_t *client, const char *name, char *buffer, size_t bufsize);

int
papplClientGetForm(pappl_client_t *client, cups_option_t **form);

const char *
papplClientGetHostName(pappl_client_t *client);

int
papplClientGetHostPort(pappl_client_t *client);

http_t *
papplClientGetHTTP(pappl_client_t *client);

pappl_job_t *
papplClientGetJob(pappl_client_t *client);

http_state_t
papplClientGetMethod(pappl_client_t *client);

ipp_op_t
papplClientGetOperation(pappl_client_t *client);

const char *
papplClientGetOptions(pappl_client_t *client);

pappl_printer_t *
papplClientGetPrinter(pappl_client_t *client);

ipp_t *
papplClientGetRequest(pappl_client_t *client);

ipp_t *
papplClientGetResponse(pappl_client_t *client);

pappl_system_t *
papplClientGetSystem(pappl_client_t *client);

const char *
papplClientGetURI(pappl_client_t *client);

const char *
papplClientGetUsername(pappl_client_t *client);

bool
papplClientHTMLAuthorize(pappl_client_t *client);

void
papplClientHTMLEscape(pappl_client_t *client, const char *s, size_t slen);

void
papplClientHTMLFooter(pappl_client_t *client);

void
papplClientHTMLHeader(pappl_client_t *client, const char *title, int refresh);

void
papplClientHTMLPrintf(pappl_client_t *client, const char *format, ...);

void
papplClientHTMLPuts(pappl_client_t *client, const char *s);

void
papplClientHTMLStartForm(pappl_client_t *client, const char *action, bool multipart);

http_status_t
papplClientIsAuthorized(pappl_client_t *client);

bool
papplClientRespond(pappl_client_t *client, http_status_t code, const char *content_coding, const char *type, time_t last_modified, size_t length);

ipp_t *
papplClientRespondIPP(pappl_client_t *client, ipp_status_t status, const char *message, ...);

bool
papplClientRespondRedirect(pappl_client_t *client, http_status_t code, const char *path);

void
papplClientSetCookie(pappl_client_t *client, const char * name, const char *value, int expires);

bool
papplClientValidateForm(pappl_client_t *client, int num_form, cups_option_t *form);

DESCRIPTION
The PAPPL client functions provide access to client connections. Client connections and the life cycle of the pappl_client_t objects are managed automatically by the system object for the printer application.

The papplClientGet functions get the current values for various client-supplied request data.

RESPONDING TO CLIENT REQUESTS
The papplClientRespond function starts a HTTP response to a client request. The papplClientHTMLHeader and papplClientHTMLFooter functions send standard HTML headers and footers for the printer application's configured web interface while the papplClientHTMLEscape, papplClientHTMLPrintf, papplClientHTMLPuts, and papplClientHTMLStartForm functions send HTML messages or strings. Use the papplClientGetHTTP and (CUPS) httpWrite2 functions to send arbitrary data in a client response. Cookies can be included in web browser requests using the papplClientSetCookie function.

The papplClientRespondIPP function starts an IPP response. Use the various CUPS ippAdd functions to add attributes to the response message.

The papplClientRespondRedirect function sends a redirection response to the client.

HTML FORMS
PAPPL provides the papplClientGetCSRFToken, papplClientGetForm, papplClientHTMLStartForm and papplClientValidateForm functions to securely manage HTML forms.

The papplClientHTMLStartForm function starts a HTML form and inserts a hidden variable containing a CSRF token that was generated by PAPPL from a secure session key that is periodically updated. Upon receipt of a follow-up form submission request, the papplClientGetForm and papplClientValidateForm functions can be used to securely read the form data (including any file attachments) and validate the hidden CSRF token.

AUTHENTICATION AND AUTHORIZATION
PAPPL supports both user-based authentication using PAM modules and a simple cookie-based password authentication mechanism that is used to limit administrative access through the web interface.

The papplHTMLAuthorize function authorizes access to the web interface and handles displaying an authentication form on the client's web browser. The return value indicates whether the client is authorized to access the web page.

The papplIsAuthorized function can be used to determine whether the current client is authorized to perform administrative operations and is normally only used for IPP clients. Local users are always authorized while remote users must provide credentials (typically a username and password) for access. This function will return an HTTP status code that can be provided to the httpClientSendResponse function. The value HTTP_STATUS_CONTINUE indicates that authorization is granted and the request should continue. The papplGetUsername function can be used to obtain the authenticated user identity.

FUNCTIONS

  papplClientGetCSRFToken
Get a unique Cross-Site Request Forgery token string.

char * papplClientGetCSRFToken (
    pappl_client_t *client,
    char *buffer,
    size_t bufsize
);

This function generates and returns a unique Cross-Site Request Forgery token string to be used as the value of a hidden variable in all HTML forms sent in the response and then compared when validating the form data in the subsequent request.

The value is based on the current system session key and client address in order to make replay attacks infeasible.

5   Note: The papplClientHTMLStartForm function automatically adds the

5   hidden CSRF variable, and the papplClientIsValidForm function

5   validates the value.

  papplClientGetCookie
Get a cookie from the client.

char * papplClientGetCookie (
    pappl_client_t *client,
    const char *name,
    char *buffer,
    size_t bufsize
);

This function gets a HTTP "cookie" value from the client request. NULL is returned if no cookie has been set by a prior request, or if the user has disabled or removed the cookie.

Use the papplClientSetCookie function to set a cookie in a response to a request.

5   Note: Cookies set with papplClientSetCookie will not be available to

5   this function until the following request.

  papplClientGetForm
Get form data from the web client.

int  papplClientGetForm (
    pappl_client_t *client,
    cups_option_t **form
);

For HTTP GET requests, the form data is collected from the request URI. For HTTP POST requests, the form data is read from the client.

The returned form values must be freed using the cupsFreeOptions function.

5   Note: Because the form data is read from the client connection, this

5   function can only be called once per request.

  papplClientGetHTTP
Get the HTTP connection associated with a client object.

http_t * papplClientGetHTTP (
    pappl_client_t *client
);

This function returns the HTTP connection associated with the client and is used when sending response data directly to the client using the CUPS httpXxx functions.

  papplClientGetHostName
Get the hostname from the client-supplied Host: field.

const char * papplClientGetHostName (
    pappl_client_t *client
);

This function returns the hostname that was used in the request and should be used in any URLs or URIs that you generate.

  papplClientGetHostPort
Get the port from the client-supplied Host: field.

int  papplClientGetHostPort (
    pappl_client_t *client
);

This function returns the port number that was used in the request and should be used in any URLs or URIs that you generate.

  papplClientGetJob
Get the target job for an IPP request.

pappl_job_t * papplClientGetJob (
    pappl_client_t *client
);

This function returns the job associated with the current IPP request. NULL is returned if the request does not target a job.

  papplClientGetMethod
Get the HTTP request method.

http_state_t  papplClientGetMethod (
    pappl_client_t *client
);

This function returns the HTTP request method that was used, for example HTTP_STATE_GET for a GET request or HTTP_STATE_POST for a POST request.

  papplClientGetOperation
Get the IPP operation code.

ipp_op_t  papplClientGetOperation (
    pappl_client_t *client
);

This function returns the IPP operation code associated with the current IPP request.

  papplClientGetOptions
Get the options from the request URI.

const char * papplClientGetOptions (
    pappl_client_t *client
);

This function returns any options that were passed in the HTTP request URI. The options are the characters after the "?" character, for example a request URI of "/mypage?name=value" will have an options string of "name=value".

NULL is returned if the request URI did not contain any options.

5   Note: HTTP GET form variables are normally accessed using the

5   papplClientGetForm function. This function should only be used when

5   getting non-form data.

  papplClientGetPrinter
Get the target printer for an IPP request.

pappl_printer_t * papplClientGetPrinter (
    pappl_client_t *client
);

This function returns the printer associated with the current IPP request. NULL is returned if the request does not target a printer.

  papplClientGetRequest
Get the IPP request message.

ipp_t * papplClientGetRequest (
    pappl_client_t *client
);

This function returns the attributes in the current IPP request, for use with the CUPS ippFindAttribute, ippFindNextAttribute, ippFirstAttribute, and ippNextAttribute functions.

  papplClientGetResponse
Get the IPP response message.

ipp_t * papplClientGetResponse (
    pappl_client_t *client
);

This function returns the attributes in the current IPP response, for use with the CUPS ippAddXxx and ippSetXxx functions. Use the papplClientRespondIPP function to set the status code and message, if any.

  papplClientGetSystem
Get the containing system for the client.

pappl_system_t * papplClientGetSystem (
    pappl_client_t *client
);

This function returns the system object that contains the client.

  papplClientGetURI
Get the HTTP request URI.

const char * papplClientGetURI (
    pappl_client_t *client
);

This function returns the URI that was sent in the current HTTP request.

5   Note: Any options in the URI are removed and can be accessed separately

5   using the papplClientGetOptions function.

  papplClientGetUsername
Get the authenticated username, if any.

const char * papplClientGetUsername (
    pappl_client_t *client
);

This function returns the current authenticated username, if any.

  papplClientHTMLAuthorize
Handle authorization for the web interface.

bool  papplClientHTMLAuthorize (
    pappl_client_t *client
);

The web interface supports both authentication against user accounts and authentication using a single administrative access password. This function handles the details of authentication for the web interface based on the system authentication service configuration (the "auth_service" argument to papplSystemCreate).

5   Note: IPP operation callbacks needing to perform authorization should use

5   the papplClientIsAuthorized function instead.

  papplClientHTMLEscape
Send a string to a web browser client.

void papplClientHTMLEscape (
    pappl_client_t *client,
    const char *s,
    size_t slen
);

This function sends the specified string to the web browser client and escapes special characters as HTML entities as needed, for example "&" is sent as &amp;.

  papplClientHTMLFooter
Show the web interface footer.

void papplClientHTMLFooter (
    pappl_client_t *client
);

This function sends the standard web interface footer followed by a trailing 0-length chunk to finish the current HTTP response. Use the papplSystemSetFooterHTML function to add any custom HTML needed in the footer.

  papplClientHTMLHeader
Show the web interface header and title.

void papplClientHTMLHeader (
    pappl_client_t *client,
    const char *title,
    int refresh
);

This function sends the standard web interface header and title. If the "refresh" argument is greater than zero, the page will automatically reload after that many seconds.

Use the papplSystemAddLink function to add system-wide navigation links to the header. Similarly, use papplPrinterAddLink to add printer-specific links, which will appear in the web interface printer if the system is not configured to support multiple printers (the PAPPL_SOPTIONS_MULTI_QUEUE option to papplSystemCreate).

  papplClientHTMLPrinterFooter
Show the web interface footer for printers.

void papplClientHTMLPrinterFooter (
    pappl_client_t *client
);

This function sends the standard web interface footer for a printer followed by a trailing 0-length chunk to finish the current HTTP response. Use the papplSystemSetFooterHTML function to add any custom HTML needed in the footer.

  papplClientHTMLPrinterHeader
Show the web interface header and title for printers.

void papplClientHTMLPrinterHeader (
    pappl_client_t *client,
    pappl_printer_t *printer,
    const char *title,
    int refresh,
    const char *label,
    const char *path_or_url
);

This function sends the standard web interface header and title for a printer. If the "refresh" argument is greater than zero, the page will automatically reload after that many seconds.

If "label" and "path_or_url" are non-NULL strings, an additional navigation link is included with the title header - this is typically used for an action button ("Change").

Use the papplSystemAddLink function to add system-wide navigation links to the header. Similarly, use papplPrinterAddLink to add printer-specific links, which will appear in the web interface printer if the system is not configured to support multiple printers (the PAPPL_SOPTIONS_MULTI_QUEUE option to papplSystemCreate).

  papplClientHTMLPrintf
Send formatted text to the web browser client, escaping as needed.

void papplClientHTMLPrintf (
    pappl_client_t *client,
    const char *format,
    ...
);

This function sends formatted text to the web browser client using printf-style formatting codes. The format string itself is not escaped to allow for embedded HTML, however strings inserted using the '%c' or %s codes are escaped properly for HTML - "&" is sent as &amp;, etc.

  papplClientHTMLPuts
Send a HTML string to the web browser client.

void papplClientHTMLPuts (
    pappl_client_t *client,
    const char *s
);

This function sends a HTML string to the client without performing any escaping of special characters.

  papplClientHTMLStartForm
Start a HTML form.

void papplClientHTMLStartForm (
    pappl_client_t *client,
    const char *action,
    bool multipart
);

This function starts a HTML form with the specified "action" path and includes the CSRF token as a hidden variable. If the "multipart" argument is true, the form is annotated to support file attachments up to 2MiB in size.

  papplClientIsAuthorized
Determine whether a client is authorized for administrative requests.

http_status_t  papplClientIsAuthorized (
    pappl_client_t *client
);

This function determines whether a client is authorized to submit an administrative request.

The return value is HTTP_STATUS_CONTINUE if access is authorized, HTTP_STATUS_FORBIDDEN if access is not allowed, HTTP_STATUS_UNAUTHORIZED if authorization is required, or HTTP_STATUS_UPGRADE_REQUIRED if the connection needs to be encrypted. All of these values can be passed to the papplClientRespond function.

  papplClientIsValidForm
Validate HTML form variables.

bool  papplClientIsValidForm (
    pappl_client_t *client,
    int num_form,
    cups_option_t *form
);

This function validates the contents of a HTML form using the CSRF token included as a hidden variable. When sending a HTML form you should use the papplClientStartForm function to start the HTML form and insert the CSRF token for later validation.

5   Note: Callers are expected to validate all other form variables.

  papplClientRespond
Send a regular HTTP response.

bool  papplClientRespond (
    pappl_client_t *client,
    http_status_t code,
    const char *content_encoding,
    const char *type,
    time_t last_modified,
    size_t length
);

This function sends all of the required HTTP fields and includes standard messages for errors. The following values for "code" are explicitly supported:

•   HTTP_STATUS_OK: The request is successful.

•   HTTP_STATUS_BAD_REQUEST: The client submitted a bad request.

•   HTTP_STATUS_CONTINUE: An authentication challenge is not needed.

•   HTTP_STATUS_FORBIDDEN: Authenticated but not allowed.

•   HTTP_STATUS_METHOD_NOT_ALLOWED: The HTTP method is not supported for the given URI.

•   HTTP_STATUS_UNAUTHORIZED: Not authenticated.

•   HTTP_STATUS_UPGRADE_REQUIRED: Redirects the client to a secure page.

Use the papplClientRespondRedirect when you need to redirect the client to another page.

  papplClientRespondIPP
Send an IPP response.

ipp_t * papplClientRespondIPP (
    pappl_client_t *client,
    ipp_status_t status,
    const char *message,
    ...
);

This function sets the return status for an IPP request and returns the current IPP response message. The "status" and "message" arguments replace any existing status-code and "status-message" attribute value that may be already present in the response.

5   Note: You should call this function prior to adding any response

5   attributes.

  papplClientRespondIPPUnsupported
Respond with an unsupported IPP attribute.

void papplClientRespondIPPUnsupported (
    pappl_client_t *client,
    ipp_attribute_t *attr
);

This function returns a 'client-error-attributes-or-values-not-supported' status code and adds the specified attribute to the unsupported attributes group in the response.

  papplClientRespondRedirect
Respond with a redirect to another page.

bool  papplClientRespondRedirect (
    pappl_client_t *client,
    http_status_t code,
    const char *path
);

This function sends a HTTP response that redirects the client to another page or URL. The most common "code" value to return is HTTP_STATUS_FOUND.

  papplClientSetCookie
Set a cookie for the web browser client.

void papplClientSetCookie (
    pappl_client_t *client,
    const char *name,
    const char *value,
    int expires
);

This function sets the value of a cookie for the client by updating the Set-Cookie header in the HTTP response that will be sent. The "name" and "value" strings must contain only valid characters for a cookie and its value as documented in RFC 6265, which basically means letters, numbers, "@", "-", ".", and "_".

The "expires" argument specifies how long the cookie will remain active in seconds, for example 3600 seconds is one hour and 86400 seconds is one day. If the value is zero or less, a "session" cookie is created instead which will expire as soon as the web browser is closed.

SEE ALSO
pappl(1), pappl-client(3), pappl-device(3), pappl-job(3), pappl-log(3), pappl-mainline(3), pappl-makeresheader(1), pappl-printer(3), pappl-resource(3), pappl-system(3), https://www.msweet.org/pappl

COPYRIGHT
Copyright © 2019-2020 by Michael R Sweet.

PAPPL is licensed under the Apache License Version 2.0 with an (optional) exception to allow linking against GPL2/LGPL2 software (like older versions of CUPS), so it can be used freely in any project you'd like. See the files "LICENSE" and "NOTICE" in the source distribution for more information.