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