1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * IPP data file parsing functions.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "ipp-private.h"
17*5e7646d2SAndroid Build Coastguard Worker #include "string-private.h"
18*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker
21*5e7646d2SAndroid Build Coastguard Worker /*
22*5e7646d2SAndroid Build Coastguard Worker * '_ippVarsDeinit()' - Free all memory associated with the IPP variables.
23*5e7646d2SAndroid Build Coastguard Worker */
24*5e7646d2SAndroid Build Coastguard Worker
25*5e7646d2SAndroid Build Coastguard Worker void
_ippVarsDeinit(_ipp_vars_t * v)26*5e7646d2SAndroid Build Coastguard Worker _ippVarsDeinit(_ipp_vars_t *v) /* I - IPP variables */
27*5e7646d2SAndroid Build Coastguard Worker {
28*5e7646d2SAndroid Build Coastguard Worker if (v->uri)
29*5e7646d2SAndroid Build Coastguard Worker {
30*5e7646d2SAndroid Build Coastguard Worker free(v->uri);
31*5e7646d2SAndroid Build Coastguard Worker v->uri = NULL;
32*5e7646d2SAndroid Build Coastguard Worker }
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(v->num_vars, v->vars);
35*5e7646d2SAndroid Build Coastguard Worker v->num_vars = 0;
36*5e7646d2SAndroid Build Coastguard Worker v->vars = NULL;
37*5e7646d2SAndroid Build Coastguard Worker }
38*5e7646d2SAndroid Build Coastguard Worker
39*5e7646d2SAndroid Build Coastguard Worker
40*5e7646d2SAndroid Build Coastguard Worker /*
41*5e7646d2SAndroid Build Coastguard Worker * '_ippVarsExpand()' - Expand variables in the source string.
42*5e7646d2SAndroid Build Coastguard Worker */
43*5e7646d2SAndroid Build Coastguard Worker
44*5e7646d2SAndroid Build Coastguard Worker void
_ippVarsExpand(_ipp_vars_t * v,char * dst,const char * src,size_t dstsize)45*5e7646d2SAndroid Build Coastguard Worker _ippVarsExpand(_ipp_vars_t *v, /* I - IPP variables */
46*5e7646d2SAndroid Build Coastguard Worker char *dst, /* I - Destination buffer */
47*5e7646d2SAndroid Build Coastguard Worker const char *src, /* I - Source string */
48*5e7646d2SAndroid Build Coastguard Worker size_t dstsize) /* I - Destination buffer size */
49*5e7646d2SAndroid Build Coastguard Worker {
50*5e7646d2SAndroid Build Coastguard Worker char *dstptr, /* Pointer into destination */
51*5e7646d2SAndroid Build Coastguard Worker *dstend, /* End of destination */
52*5e7646d2SAndroid Build Coastguard Worker temp[256], /* Temporary string */
53*5e7646d2SAndroid Build Coastguard Worker *tempptr; /* Pointer into temporary string */
54*5e7646d2SAndroid Build Coastguard Worker const char *value; /* Value to substitute */
55*5e7646d2SAndroid Build Coastguard Worker
56*5e7646d2SAndroid Build Coastguard Worker
57*5e7646d2SAndroid Build Coastguard Worker dstptr = dst;
58*5e7646d2SAndroid Build Coastguard Worker dstend = dst + dstsize - 1;
59*5e7646d2SAndroid Build Coastguard Worker
60*5e7646d2SAndroid Build Coastguard Worker while (*src && dstptr < dstend)
61*5e7646d2SAndroid Build Coastguard Worker {
62*5e7646d2SAndroid Build Coastguard Worker if (*src == '$')
63*5e7646d2SAndroid Build Coastguard Worker {
64*5e7646d2SAndroid Build Coastguard Worker /*
65*5e7646d2SAndroid Build Coastguard Worker * Substitute a string/number...
66*5e7646d2SAndroid Build Coastguard Worker */
67*5e7646d2SAndroid Build Coastguard Worker
68*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(src, "$$", 2))
69*5e7646d2SAndroid Build Coastguard Worker {
70*5e7646d2SAndroid Build Coastguard Worker value = "$";
71*5e7646d2SAndroid Build Coastguard Worker src += 2;
72*5e7646d2SAndroid Build Coastguard Worker }
73*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(src, "$ENV[", 5))
74*5e7646d2SAndroid Build Coastguard Worker {
75*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp, src + 5, sizeof(temp));
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker for (tempptr = temp; *tempptr; tempptr ++)
78*5e7646d2SAndroid Build Coastguard Worker if (*tempptr == ']')
79*5e7646d2SAndroid Build Coastguard Worker break;
80*5e7646d2SAndroid Build Coastguard Worker
81*5e7646d2SAndroid Build Coastguard Worker if (*tempptr)
82*5e7646d2SAndroid Build Coastguard Worker *tempptr++ = '\0';
83*5e7646d2SAndroid Build Coastguard Worker
84*5e7646d2SAndroid Build Coastguard Worker value = getenv(temp);
85*5e7646d2SAndroid Build Coastguard Worker src += tempptr - temp + 5;
86*5e7646d2SAndroid Build Coastguard Worker }
87*5e7646d2SAndroid Build Coastguard Worker else
88*5e7646d2SAndroid Build Coastguard Worker {
89*5e7646d2SAndroid Build Coastguard Worker if (src[1] == '{')
90*5e7646d2SAndroid Build Coastguard Worker {
91*5e7646d2SAndroid Build Coastguard Worker src += 2;
92*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp, src, sizeof(temp));
93*5e7646d2SAndroid Build Coastguard Worker if ((tempptr = strchr(temp, '}')) != NULL)
94*5e7646d2SAndroid Build Coastguard Worker *tempptr = '\0';
95*5e7646d2SAndroid Build Coastguard Worker else
96*5e7646d2SAndroid Build Coastguard Worker tempptr = temp + strlen(temp);
97*5e7646d2SAndroid Build Coastguard Worker }
98*5e7646d2SAndroid Build Coastguard Worker else
99*5e7646d2SAndroid Build Coastguard Worker {
100*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp, src + 1, sizeof(temp));
101*5e7646d2SAndroid Build Coastguard Worker
102*5e7646d2SAndroid Build Coastguard Worker for (tempptr = temp; *tempptr; tempptr ++)
103*5e7646d2SAndroid Build Coastguard Worker if (!isalnum(*tempptr & 255) && *tempptr != '-' && *tempptr != '_')
104*5e7646d2SAndroid Build Coastguard Worker break;
105*5e7646d2SAndroid Build Coastguard Worker
106*5e7646d2SAndroid Build Coastguard Worker if (*tempptr)
107*5e7646d2SAndroid Build Coastguard Worker *tempptr = '\0';
108*5e7646d2SAndroid Build Coastguard Worker }
109*5e7646d2SAndroid Build Coastguard Worker
110*5e7646d2SAndroid Build Coastguard Worker value = _ippVarsGet(v, temp);
111*5e7646d2SAndroid Build Coastguard Worker
112*5e7646d2SAndroid Build Coastguard Worker src += tempptr - temp + 1;
113*5e7646d2SAndroid Build Coastguard Worker }
114*5e7646d2SAndroid Build Coastguard Worker
115*5e7646d2SAndroid Build Coastguard Worker if (value)
116*5e7646d2SAndroid Build Coastguard Worker {
117*5e7646d2SAndroid Build Coastguard Worker strlcpy(dstptr, value, (size_t)(dstend - dstptr + 1));
118*5e7646d2SAndroid Build Coastguard Worker dstptr += strlen(dstptr);
119*5e7646d2SAndroid Build Coastguard Worker }
120*5e7646d2SAndroid Build Coastguard Worker }
121*5e7646d2SAndroid Build Coastguard Worker else
122*5e7646d2SAndroid Build Coastguard Worker *dstptr++ = *src++;
123*5e7646d2SAndroid Build Coastguard Worker }
124*5e7646d2SAndroid Build Coastguard Worker
125*5e7646d2SAndroid Build Coastguard Worker *dstptr = '\0';
126*5e7646d2SAndroid Build Coastguard Worker }
127*5e7646d2SAndroid Build Coastguard Worker
128*5e7646d2SAndroid Build Coastguard Worker
129*5e7646d2SAndroid Build Coastguard Worker /*
130*5e7646d2SAndroid Build Coastguard Worker * '_ippVarsGet()' - Get a variable string.
131*5e7646d2SAndroid Build Coastguard Worker */
132*5e7646d2SAndroid Build Coastguard Worker
133*5e7646d2SAndroid Build Coastguard Worker const char * /* O - Value or @code NULL@ if not set */
_ippVarsGet(_ipp_vars_t * v,const char * name)134*5e7646d2SAndroid Build Coastguard Worker _ippVarsGet(_ipp_vars_t *v, /* I - IPP variables */
135*5e7646d2SAndroid Build Coastguard Worker const char *name) /* I - Variable name */
136*5e7646d2SAndroid Build Coastguard Worker {
137*5e7646d2SAndroid Build Coastguard Worker if (!v)
138*5e7646d2SAndroid Build Coastguard Worker return (NULL);
139*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(name, "uri"))
140*5e7646d2SAndroid Build Coastguard Worker return (v->uri);
141*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(name, "uriuser") || !strcmp(name, "username"))
142*5e7646d2SAndroid Build Coastguard Worker return (v->username[0] ? v->username : NULL);
143*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(name, "scheme") || !strcmp(name, "method"))
144*5e7646d2SAndroid Build Coastguard Worker return (v->scheme);
145*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(name, "hostname"))
146*5e7646d2SAndroid Build Coastguard Worker return (v->host);
147*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(name, "port"))
148*5e7646d2SAndroid Build Coastguard Worker return (v->portstr);
149*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(name, "resource"))
150*5e7646d2SAndroid Build Coastguard Worker return (v->resource);
151*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(name, "user"))
152*5e7646d2SAndroid Build Coastguard Worker return (cupsUser());
153*5e7646d2SAndroid Build Coastguard Worker else
154*5e7646d2SAndroid Build Coastguard Worker return (cupsGetOption(name, v->num_vars, v->vars));
155*5e7646d2SAndroid Build Coastguard Worker }
156*5e7646d2SAndroid Build Coastguard Worker
157*5e7646d2SAndroid Build Coastguard Worker
158*5e7646d2SAndroid Build Coastguard Worker /*
159*5e7646d2SAndroid Build Coastguard Worker * '_ippVarsInit()' - Initialize .
160*5e7646d2SAndroid Build Coastguard Worker */
161*5e7646d2SAndroid Build Coastguard Worker
162*5e7646d2SAndroid Build Coastguard Worker void
_ippVarsInit(_ipp_vars_t * v,_ipp_fattr_cb_t attrcb,_ipp_ferror_cb_t errorcb,_ipp_ftoken_cb_t tokencb)163*5e7646d2SAndroid Build Coastguard Worker _ippVarsInit(_ipp_vars_t *v, /* I - IPP variables */
164*5e7646d2SAndroid Build Coastguard Worker _ipp_fattr_cb_t attrcb, /* I - Attribute (filter) callback */
165*5e7646d2SAndroid Build Coastguard Worker _ipp_ferror_cb_t errorcb, /* I - Error callback */
166*5e7646d2SAndroid Build Coastguard Worker _ipp_ftoken_cb_t tokencb) /* I - Token callback */
167*5e7646d2SAndroid Build Coastguard Worker {
168*5e7646d2SAndroid Build Coastguard Worker memset(v, 0, sizeof(_ipp_vars_t));
169*5e7646d2SAndroid Build Coastguard Worker
170*5e7646d2SAndroid Build Coastguard Worker v->attrcb = attrcb;
171*5e7646d2SAndroid Build Coastguard Worker v->errorcb = errorcb;
172*5e7646d2SAndroid Build Coastguard Worker v->tokencb = tokencb;
173*5e7646d2SAndroid Build Coastguard Worker }
174*5e7646d2SAndroid Build Coastguard Worker
175*5e7646d2SAndroid Build Coastguard Worker
176*5e7646d2SAndroid Build Coastguard Worker /*
177*5e7646d2SAndroid Build Coastguard Worker * '_ippVarsPasswordCB()' - Password callback using the IPP variables.
178*5e7646d2SAndroid Build Coastguard Worker */
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker const char * /* O - Password string or @code NULL@ */
_ippVarsPasswordCB(const char * prompt,http_t * http,const char * method,const char * resource,void * user_data)181*5e7646d2SAndroid Build Coastguard Worker _ippVarsPasswordCB(
182*5e7646d2SAndroid Build Coastguard Worker const char *prompt, /* I - Prompt string (not used) */
183*5e7646d2SAndroid Build Coastguard Worker http_t *http, /* I - HTTP connection (not used) */
184*5e7646d2SAndroid Build Coastguard Worker const char *method, /* I - HTTP method (not used) */
185*5e7646d2SAndroid Build Coastguard Worker const char *resource, /* I - Resource path (not used) */
186*5e7646d2SAndroid Build Coastguard Worker void *user_data) /* I - IPP variables */
187*5e7646d2SAndroid Build Coastguard Worker {
188*5e7646d2SAndroid Build Coastguard Worker _ipp_vars_t *v = (_ipp_vars_t *)user_data;
189*5e7646d2SAndroid Build Coastguard Worker /* I - IPP variables */
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker
192*5e7646d2SAndroid Build Coastguard Worker (void)prompt;
193*5e7646d2SAndroid Build Coastguard Worker (void)http;
194*5e7646d2SAndroid Build Coastguard Worker (void)method;
195*5e7646d2SAndroid Build Coastguard Worker (void)resource;
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker if (v->username[0] && v->password && v->password_tries < 3)
198*5e7646d2SAndroid Build Coastguard Worker {
199*5e7646d2SAndroid Build Coastguard Worker v->password_tries ++;
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker cupsSetUser(v->username);
202*5e7646d2SAndroid Build Coastguard Worker
203*5e7646d2SAndroid Build Coastguard Worker return (v->password);
204*5e7646d2SAndroid Build Coastguard Worker }
205*5e7646d2SAndroid Build Coastguard Worker else
206*5e7646d2SAndroid Build Coastguard Worker {
207*5e7646d2SAndroid Build Coastguard Worker return (NULL);
208*5e7646d2SAndroid Build Coastguard Worker }
209*5e7646d2SAndroid Build Coastguard Worker }
210*5e7646d2SAndroid Build Coastguard Worker
211*5e7646d2SAndroid Build Coastguard Worker
212*5e7646d2SAndroid Build Coastguard Worker /*
213*5e7646d2SAndroid Build Coastguard Worker * '_ippVarsSet()' - Set an IPP variable.
214*5e7646d2SAndroid Build Coastguard Worker */
215*5e7646d2SAndroid Build Coastguard Worker
216*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
_ippVarsSet(_ipp_vars_t * v,const char * name,const char * value)217*5e7646d2SAndroid Build Coastguard Worker _ippVarsSet(_ipp_vars_t *v, /* I - IPP variables */
218*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Variable name */
219*5e7646d2SAndroid Build Coastguard Worker const char *value) /* I - Variable value */
220*5e7646d2SAndroid Build Coastguard Worker {
221*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(name, "uri"))
222*5e7646d2SAndroid Build Coastguard Worker {
223*5e7646d2SAndroid Build Coastguard Worker char uri[1024]; /* New printer URI */
224*5e7646d2SAndroid Build Coastguard Worker char resolved[1024]; /* Resolved mDNS URI */
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker if (strstr(value, "._tcp"))
227*5e7646d2SAndroid Build Coastguard Worker {
228*5e7646d2SAndroid Build Coastguard Worker /*
229*5e7646d2SAndroid Build Coastguard Worker * Resolve URI...
230*5e7646d2SAndroid Build Coastguard Worker */
231*5e7646d2SAndroid Build Coastguard Worker
232*5e7646d2SAndroid Build Coastguard Worker if (!_httpResolveURI(value, resolved, sizeof(resolved), _HTTP_RESOLVE_DEFAULT, NULL, NULL))
233*5e7646d2SAndroid Build Coastguard Worker return (0);
234*5e7646d2SAndroid Build Coastguard Worker
235*5e7646d2SAndroid Build Coastguard Worker value = resolved;
236*5e7646d2SAndroid Build Coastguard Worker }
237*5e7646d2SAndroid Build Coastguard Worker
238*5e7646d2SAndroid Build Coastguard Worker if (httpSeparateURI(HTTP_URI_CODING_ALL, value, v->scheme, sizeof(v->scheme), v->username, sizeof(v->username), v->host, sizeof(v->host), &(v->port), v->resource, sizeof(v->resource)) < HTTP_URI_STATUS_OK)
239*5e7646d2SAndroid Build Coastguard Worker return (0);
240*5e7646d2SAndroid Build Coastguard Worker
241*5e7646d2SAndroid Build Coastguard Worker if (v->username[0])
242*5e7646d2SAndroid Build Coastguard Worker {
243*5e7646d2SAndroid Build Coastguard Worker if ((v->password = strchr(v->username, ':')) != NULL)
244*5e7646d2SAndroid Build Coastguard Worker *(v->password)++ = '\0';
245*5e7646d2SAndroid Build Coastguard Worker }
246*5e7646d2SAndroid Build Coastguard Worker
247*5e7646d2SAndroid Build Coastguard Worker snprintf(v->portstr, sizeof(v->portstr), "%d", v->port);
248*5e7646d2SAndroid Build Coastguard Worker
249*5e7646d2SAndroid Build Coastguard Worker if (v->uri)
250*5e7646d2SAndroid Build Coastguard Worker free(v->uri);
251*5e7646d2SAndroid Build Coastguard Worker
252*5e7646d2SAndroid Build Coastguard Worker httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), v->scheme, NULL, v->host, v->port, v->resource);
253*5e7646d2SAndroid Build Coastguard Worker v->uri = strdup(uri);
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker return (v->uri != NULL);
256*5e7646d2SAndroid Build Coastguard Worker }
257*5e7646d2SAndroid Build Coastguard Worker else
258*5e7646d2SAndroid Build Coastguard Worker {
259*5e7646d2SAndroid Build Coastguard Worker v->num_vars = cupsAddOption(name, value, v->num_vars, &v->vars);
260*5e7646d2SAndroid Build Coastguard Worker return (1);
261*5e7646d2SAndroid Build Coastguard Worker }
262*5e7646d2SAndroid Build Coastguard Worker }
263