]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/usersys.c
Clean up some build issues on certain platforms.
[thirdparty/cups.git] / cups / usersys.c
CommitLineData
ef416fc2 1/*
83bc2aac
MS
2 * User, system, and password routines for CUPS.
3 *
3c2cb822 4 * Copyright 2007-2019 by Apple Inc.
83bc2aac
MS
5 * Copyright 1997-2006 by Easy Software Products.
6 *
3c2cb822
MS
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
8 * information.
ef416fc2 9 */
10
11/*
12 * Include necessary headers...
13 */
14
71e16022 15#include "cups-private.h"
fb863569 16#include "debug-internal.h"
ef416fc2 17#include <stdlib.h>
e00b005a 18#include <sys/stat.h>
19dc16f7 19#ifdef _WIN32
ef416fc2 20# include <windows.h>
5a6b583a
MS
21#else
22# include <pwd.h>
dcb445bc 23# include <termios.h>
db8b865d 24# include <sys/utsname.h>
19dc16f7 25#endif /* _WIN32 */
588c2205
MS
26#ifdef __APPLE__
27# include <sys/sysctl.h>
28#endif /* __APPLE__ */
ef416fc2 29
30
dcb445bc
MS
31/*
32 * Local constants...
33 */
34
08d56b1f 35#ifdef __APPLE__
3c2cb822 36# if TARGET_OS_OSX
588c2205
MS
37# define kCUPSPrintingPrefs CFSTR("org.cups.PrintingPrefs")
38# define kPREFIX ""
3c2cb822
MS
39# else
40# define kCUPSPrintingPrefs CFSTR(".GlobalPreferences")
41# define kPREFIX "AirPrint"
42# endif /* TARGET_OS_OSX */
588c2205
MS
43# define kAllowAnyRootKey CFSTR(kPREFIX "AllowAnyRoot")
44# define kAllowExpiredCertsKey CFSTR(kPREFIX "AllowExpiredCerts")
45# define kEncryptionKey CFSTR(kPREFIX "Encryption")
46# define kGSSServiceNameKey CFSTR(kPREFIX "GSSServiceName")
47# define kSSLOptionsKey CFSTR(kPREFIX "SSLOptions")
48# define kTrustOnFirstUseKey CFSTR(kPREFIX "TrustOnFirstUse")
49# define kValidateCertsKey CFSTR(kPREFIX "ValidateCerts")
50/* Deprecated */
51# define kAllowRC4 CFSTR(kPREFIX "AllowRC4")
52# define kAllowSSL3 CFSTR(kPREFIX "AllowSSL3")
53# define kAllowDH CFSTR(kPREFIX "AllowDH")
08d56b1f
MS
54#endif /* __APPLE__ */
55
dcb445bc
MS
56#define _CUPS_PASSCHAR '*' /* Character that is echoed for password */
57
58
3abb875b
MS
59/*
60 * Local types...
61 */
62
63typedef struct _cups_client_conf_s /**** client.conf config data ****/
64{
65#ifdef HAVE_SSL
8f1fbdec
MS
66 int ssl_options, /* SSLOptions values */
67 ssl_min_version,/* Minimum SSL/TLS version */
68 ssl_max_version;/* Maximum SSL/TLS version */
3abb875b 69#endif /* HAVE_SSL */
08d56b1f
MS
70 int trust_first, /* Trust on first use? */
71 any_root, /* Allow any (e.g., self-signed) root */
3abb875b
MS
72 expired_certs, /* Allow expired certs */
73 validate_certs; /* Validate certificates */
74 http_encryption_t encryption; /* Encryption setting */
75 char user[65], /* User name */
76 server_name[256];
77 /* Server hostname */
78#ifdef HAVE_GSSAPI
79 char gss_service_name[32];
80 /* Kerberos service name */
81#endif /* HAVE_GSSAPI */
82} _cups_client_conf_t;
83
84
b423cd4c 85/*
86 * Local functions...
87 */
88
08d56b1f
MS
89#ifdef __APPLE__
90static int cups_apple_get_boolean(CFStringRef key, int *value);
91static int cups_apple_get_string(CFStringRef key, char *value, size_t valsize);
92#endif /* __APPLE__ */
93static int cups_boolean_value(const char *value);
3abb875b
MS
94static void cups_finalize_client_conf(_cups_client_conf_t *cc);
95static void cups_init_client_conf(_cups_client_conf_t *cc);
96static void cups_read_client_conf(cups_file_t *fp, _cups_client_conf_t *cc);
4b9daaf4 97static void cups_set_default_ipp_port(_cups_globals_t *cg);
3abb875b 98static void cups_set_encryption(_cups_client_conf_t *cc, const char *value);
07ed0e9a 99#ifdef HAVE_GSSAPI
3abb875b 100static void cups_set_gss_service_name(_cups_client_conf_t *cc, const char *value);
07ed0e9a 101#endif /* HAVE_GSSAPI */
3abb875b
MS
102static void cups_set_server_name(_cups_client_conf_t *cc, const char *value);
103#ifdef HAVE_SSL
104static void cups_set_ssl_options(_cups_client_conf_t *cc, const char *value);
105#endif /* HAVE_SSL */
106static void cups_set_user(_cups_client_conf_t *cc, const char *value);
b423cd4c 107
108
ef416fc2 109/*
5a6b583a 110 * 'cupsEncryption()' - Get the current encryption settings.
ef416fc2 111 *
112 * The default encryption setting comes from the CUPS_ENCRYPTION
568fa3fa 113 * environment variable, then the ~/.cups/client.conf file, and finally the
ef416fc2 114 * /etc/cups/client.conf file. If not set, the default is
cb7f98ee 115 * @code HTTP_ENCRYPTION_IF_REQUESTED@.
5a6b583a
MS
116 *
117 * Note: The current encryption setting is tracked separately for each thread
118 * in a program. Multi-threaded programs that override the setting via the
119 * @link cupsSetEncryption@ function need to do so in each thread for the same
120 * setting to be used.
ef416fc2 121 */
122
123http_encryption_t /* O - Encryption settings */
124cupsEncryption(void)
125{
ef416fc2 126 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
127
128
ef416fc2 129 if (cg->encryption == (http_encryption_t)-1)
e07d4801 130 _cupsSetDefaults();
ef416fc2 131
132 return (cg->encryption);
133}
134
135
136/*
137 * 'cupsGetPassword()' - Get a password from the user.
138 *
5a738aea 139 * Uses the current password callback function. Returns @code NULL@ if the
ecdc0628 140 * user does not provide a password.
5a6b583a
MS
141 *
142 * Note: The current password callback function is tracked separately for each
143 * thread in a program. Multi-threaded programs that override the setting via
144 * the @link cupsSetPasswordCB@ or @link cupsSetPasswordCB2@ functions need to
145 * do so in each thread for the same function to be used.
53af7f21
MS
146 *
147 * @exclude all@
ef416fc2 148 */
149
150const char * /* O - Password */
151cupsGetPassword(const char *prompt) /* I - Prompt string */
152{
f11a948a
MS
153 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
154
155
156 return ((cg->password_cb)(prompt, NULL, NULL, NULL, cg->password_data));
157}
158
159
160/*
98d88c8d 161 * 'cupsGetPassword2()' - Get a password from the user using the current
5a6b583a 162 * password callback.
f11a948a
MS
163 *
164 * Uses the current password callback function. Returns @code NULL@ if the
165 * user does not provide a password.
166 *
5a6b583a
MS
167 * Note: The current password callback function is tracked separately for each
168 * thread in a program. Multi-threaded programs that override the setting via
98d88c8d
MS
169 * the @link cupsSetPasswordCB2@ function need to do so in each thread for the
170 * same function to be used.
5a6b583a 171 *
8072030b 172 * @since CUPS 1.4/macOS 10.6@
f11a948a
MS
173 */
174
175const char * /* O - Password */
176cupsGetPassword2(const char *prompt, /* I - Prompt string */
177 http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
178 const char *method, /* I - Request method ("GET", "POST", "PUT") */
179 const char *resource) /* I - Resource path */
180{
181 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
182
183
184 if (!http)
185 http = _cupsConnect();
186
187 return ((cg->password_cb)(prompt, http, method, resource, cg->password_data));
ef416fc2 188}
189
190
ef416fc2 191/*
5a6b583a
MS
192 * 'cupsServer()' - Return the hostname/address of the current server.
193 *
194 * The default server comes from the CUPS_SERVER environment variable, then the
195 * ~/.cups/client.conf file, and finally the /etc/cups/client.conf file. If not
196 * set, the default is the local system - either "localhost" or a domain socket
197 * path.
ef416fc2 198 *
5a6b583a
MS
199 * The returned value can be a fully-qualified hostname, a numeric IPv4 or IPv6
200 * address, or a domain socket pathname.
201 *
202 * Note: The current server is tracked separately for each thread in a program.
203 * Multi-threaded programs that override the server via the
204 * @link cupsSetServer@ function need to do so in each thread for the same
205 * server to be used.
ef416fc2 206 */
207
208const char * /* O - Server name */
209cupsServer(void)
210{
ef416fc2 211 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
212
213
ef416fc2 214 if (!cg->server[0])
e07d4801 215 _cupsSetDefaults();
ef416fc2 216
e07d4801
MS
217 return (cg->server);
218}
ef416fc2 219
d09495fa 220
7cf5915e
MS
221/*
222 * 'cupsSetClientCertCB()' - Set the client certificate callback.
223 *
224 * Pass @code NULL@ to restore the default callback.
225 *
226 * Note: The current certificate callback is tracked separately for each thread
227 * in a program. Multi-threaded programs that override the callback need to do
228 * so in each thread for the same callback to be used.
229 *
8072030b 230 * @since CUPS 1.5/macOS 10.7@
7cf5915e
MS
231 */
232
233void
234cupsSetClientCertCB(
235 cups_client_cert_cb_t cb, /* I - Callback function */
236 void *user_data) /* I - User data pointer */
237{
238 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
239
240
241 cg->client_cert_cb = cb;
242 cg->client_cert_data = user_data;
243}
244
245
246/*
247 * 'cupsSetCredentials()' - Set the default credentials to be used for SSL/TLS
248 * connections.
249 *
250 * Note: The default credentials are tracked separately for each thread in a
251 * program. Multi-threaded programs that override the setting need to do so in
252 * each thread for the same setting to be used.
253 *
8072030b 254 * @since CUPS 1.5/macOS 10.7@
7cf5915e
MS
255 */
256
257int /* O - Status of call (0 = success) */
258cupsSetCredentials(
259 cups_array_t *credentials) /* I - Array of credentials */
260{
261 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
262
263
264 if (cupsArrayCount(credentials) < 1)
265 return (-1);
266
7d5824d6 267#ifdef HAVE_SSL
7cf5915e 268 _httpFreeCredentials(cg->tls_credentials);
85dda01c 269 cg->tls_credentials = _httpCreateCredentials(credentials);
7d5824d6 270#endif /* HAVE_SSL */
7cf5915e
MS
271
272 return (cg->tls_credentials ? 0 : -1);
273}
274
275
e07d4801
MS
276/*
277 * 'cupsSetEncryption()' - Set the encryption preference.
5a6b583a
MS
278 *
279 * The default encryption setting comes from the CUPS_ENCRYPTION
280 * environment variable, then the ~/.cups/client.conf file, and finally the
281 * /etc/cups/client.conf file. If not set, the default is
cb7f98ee 282 * @code HTTP_ENCRYPTION_IF_REQUESTED@.
5a6b583a
MS
283 *
284 * Note: The current encryption setting is tracked separately for each thread
285 * in a program. Multi-threaded programs that override the setting need to do
286 * so in each thread for the same setting to be used.
e07d4801 287 */
ef416fc2 288
e07d4801
MS
289void
290cupsSetEncryption(http_encryption_t e) /* I - New encryption preference */
291{
292 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
ef416fc2 293
ef416fc2 294
e07d4801 295 cg->encryption = e;
ef416fc2 296
e07d4801
MS
297 if (cg->http)
298 httpEncryption(cg->http, e);
ef416fc2 299}
300
301
302/*
303 * 'cupsSetPasswordCB()' - Set the password callback for CUPS.
304 *
5a6b583a
MS
305 * Pass @code NULL@ to restore the default (console) password callback, which
306 * reads the password from the console. Programs should call either this
307 * function or @link cupsSetPasswordCB2@, as only one callback can be registered
308 * by a program per thread.
309 *
310 * Note: The current password callback is tracked separately for each thread
311 * in a program. Multi-threaded programs that override the callback need to do
312 * so in each thread for the same callback to be used.
53af7f21
MS
313 *
314 * @exclude all@
ef416fc2 315 */
316
317void
318cupsSetPasswordCB(cups_password_cb_t cb)/* I - Callback function */
319{
320 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
321
322
f11a948a
MS
323 if (cb == (cups_password_cb_t)0)
324 cg->password_cb = (cups_password_cb2_t)_cupsGetPassword;
325 else
326 cg->password_cb = (cups_password_cb2_t)cb;
327
328 cg->password_data = NULL;
329}
330
331
332/*
333 * 'cupsSetPasswordCB2()' - Set the advanced password callback for CUPS.
334 *
5a6b583a
MS
335 * Pass @code NULL@ to restore the default (console) password callback, which
336 * reads the password from the console. Programs should call either this
337 * function or @link cupsSetPasswordCB2@, as only one callback can be registered
338 * by a program per thread.
339 *
340 * Note: The current password callback is tracked separately for each thread
341 * in a program. Multi-threaded programs that override the callback need to do
342 * so in each thread for the same callback to be used.
f11a948a 343 *
8072030b 344 * @since CUPS 1.4/macOS 10.6@
f11a948a
MS
345 */
346
347void
348cupsSetPasswordCB2(
349 cups_password_cb2_t cb, /* I - Callback function */
350 void *user_data) /* I - User data pointer */
351{
352 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
353
354
355 if (cb == (cups_password_cb2_t)0)
356 cg->password_cb = (cups_password_cb2_t)_cupsGetPassword;
ef416fc2 357 else
358 cg->password_cb = cb;
f11a948a
MS
359
360 cg->password_data = user_data;
ef416fc2 361}
362
363
364/*
5a6b583a 365 * 'cupsSetServer()' - Set the default server name and port.
ef416fc2 366 *
367 * The "server" string can be a fully-qualified hostname, a numeric
5a6b583a
MS
368 * IPv4 or IPv6 address, or a domain socket pathname. Hostnames and numeric IP
369 * addresses can be optionally followed by a colon and port number to override
370 * the default port 631, e.g. "hostname:8631". Pass @code NULL@ to restore the
371 * default server name and port.
372 *
373 * Note: The current server is tracked separately for each thread in a program.
374 * Multi-threaded programs that override the server need to do so in each
375 * thread for the same server to be used.
ef416fc2 376 */
377
378void
379cupsSetServer(const char *server) /* I - Server name */
380{
0cb67df3
MS
381 char *options, /* Options */
382 *port; /* Pointer to port */
ef416fc2 383 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
384
385
386 if (server)
387 {
388 strlcpy(cg->server, server, sizeof(cg->server));
389
0cb67df3
MS
390 if (cg->server[0] != '/' && (options = strrchr(cg->server, '/')) != NULL)
391 {
392 *options++ = '\0';
393
394 if (!strcmp(options, "version=1.0"))
395 cg->server_version = 10;
396 else if (!strcmp(options, "version=1.1"))
397 cg->server_version = 11;
398 else if (!strcmp(options, "version=2.0"))
399 cg->server_version = 20;
400 else if (!strcmp(options, "version=2.1"))
401 cg->server_version = 21;
402 else if (!strcmp(options, "version=2.2"))
403 cg->server_version = 22;
404 }
567f49cb
MS
405 else
406 cg->server_version = 20;
0cb67df3 407
ef416fc2 408 if (cg->server[0] != '/' && (port = strrchr(cg->server, ':')) != NULL &&
409 !strchr(port, ']') && isdigit(port[1] & 255))
410 {
411 *port++ = '\0';
412
e07d4801 413 cg->ipp_port = atoi(port);
ef416fc2 414 }
415
4b9daaf4
MS
416 if (!cg->ipp_port)
417 cups_set_default_ipp_port(cg);
418
ef416fc2 419 if (cg->server[0] == '/')
5a9febac 420 strlcpy(cg->servername, "localhost", sizeof(cg->servername));
ef416fc2 421 else
422 strlcpy(cg->servername, cg->server, sizeof(cg->servername));
423 }
424 else
425 {
0cb67df3
MS
426 cg->server[0] = '\0';
427 cg->servername[0] = '\0';
428 cg->server_version = 20;
4b9daaf4 429 cg->ipp_port = 0;
ef416fc2 430 }
5a738aea
MS
431
432 if (cg->http)
433 {
434 httpClose(cg->http);
435 cg->http = NULL;
436 }
ef416fc2 437}
438
439
7cf5915e
MS
440/*
441 * 'cupsSetServerCertCB()' - Set the server certificate callback.
442 *
443 * Pass @code NULL@ to restore the default callback.
444 *
445 * Note: The current credentials callback is tracked separately for each thread
446 * in a program. Multi-threaded programs that override the callback need to do
447 * so in each thread for the same callback to be used.
448 *
8072030b 449 * @since CUPS 1.5/macOS 10.7@
7cf5915e
MS
450 */
451
452void
453cupsSetServerCertCB(
454 cups_server_cert_cb_t cb, /* I - Callback function */
455 void *user_data) /* I - User data pointer */
456{
457 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
458
459
460 cg->server_cert_cb = cb;
461 cg->server_cert_data = user_data;
462}
463
464
ef416fc2 465/*
466 * 'cupsSetUser()' - Set the default user name.
467 *
5a738aea 468 * Pass @code NULL@ to restore the default user name.
5a6b583a
MS
469 *
470 * Note: The current user name is tracked separately for each thread in a
471 * program. Multi-threaded programs that override the user name need to do so
472 * in each thread for the same user name to be used.
ef416fc2 473 */
474
475void
476cupsSetUser(const char *user) /* I - User name */
477{
478 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
479
480
481 if (user)
482 strlcpy(cg->user, user, sizeof(cg->user));
483 else
484 cg->user[0] = '\0';
485}
486
487
db8b865d
MS
488/*
489 * 'cupsSetUserAgent()' - Set the default HTTP User-Agent string.
490 *
491 * Setting the string to NULL forces the default value containing the CUPS
492 * version, IPP version, and operating system version and architecture.
493 *
8072030b 494 * @since CUPS 1.7/macOS 10.9@
db8b865d
MS
495 */
496
497void
498cupsSetUserAgent(const char *user_agent)/* I - User-Agent string or @code NULL@ */
499{
500 _cups_globals_t *cg = _cupsGlobals();
501 /* Thread globals */
19dc16f7 502#ifdef _WIN32
db8b865d 503 SYSTEM_INFO sysinfo; /* System information */
104c5283 504 OSVERSIONINFOA version; /* OS version info */
588c2205
MS
505 const char *machine; /* Hardware/machine name */
506#elif defined(__APPLE__)
507 struct utsname name; /* uname info */
508 char version[256]; /* macOS/iOS version */
509 size_t len; /* Length of value */
db8b865d
MS
510#else
511 struct utsname name; /* uname info */
19dc16f7 512#endif /* _WIN32 */
db8b865d
MS
513
514
515 if (user_agent)
516 {
517 strlcpy(cg->user_agent, user_agent, sizeof(cg->user_agent));
518 return;
519 }
520
19dc16f7 521#ifdef _WIN32
588c2205
MS
522 /*
523 * Gather Windows version information for the User-Agent string...
524 */
525
db8b865d 526 version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
86206ccf 527 GetVersionExA(&version);
db8b865d
MS
528 GetNativeSystemInfo(&sysinfo);
529
588c2205
MS
530 switch (sysinfo.wProcessorArchitecture)
531 {
532 case PROCESSOR_ARCHITECTURE_AMD64 :
533 machine = "amd64";
534 break;
535
536 case PROCESSOR_ARCHITECTURE_ARM :
537 machine = "arm";
538 break;
539
540 case PROCESSOR_ARCHITECTURE_IA64 :
541 machine = "ia64";
542 break;
543
544 case PROCESSOR_ARCHITECTURE_INTEL :
545 machine = "intel";
546 break;
547
548 default :
549 machine = "unknown";
550 break;
551 }
552
553 snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (Windows %d.%d; %s) IPP/2.0", version.dwMajorVersion, version.dwMinorVersion, machine);
554
555#elif defined(__APPLE__)
556 /*
557 * Gather macOS/iOS version information for the User-Agent string...
558 */
559
560 uname(&name);
561
562 len = sizeof(version) - 1;
563 if (!sysctlbyname("kern.osproductversion", version, &len, NULL, 0))
564 version[len] = '\0';
565 else
566 strlcpy(version, "unknown", sizeof(version));
567
3c2cb822 568# if TARGET_OS_OSX
588c2205 569 snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (macOS %s; %s) IPP/2.0", version, name.machine);
3c2cb822
MS
570# else
571 snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (iOS %s; %s) IPP/2.0", version, name.machine);
572# endif /* TARGET_OS_OSX */
db8b865d
MS
573
574#else
588c2205
MS
575 /*
576 * Gather generic UNIX version information for the User-Agent string...
577 */
578
db8b865d
MS
579 uname(&name);
580
588c2205 581 snprintf(cg->user_agent, sizeof(cg->user_agent), CUPS_MINIMAL " (%s %s; %s) IPP/2.0", name.sysname, name.release, name.machine);
19dc16f7 582#endif /* _WIN32 */
db8b865d
MS
583}
584
585
ef416fc2 586/*
587 * 'cupsUser()' - Return the current user's name.
5a6b583a
MS
588 *
589 * Note: The current user name is tracked separately for each thread in a
590 * program. Multi-threaded programs that override the user name with the
591 * @link cupsSetUser@ function need to do so in each thread for the same user
592 * name to be used.
ef416fc2 593 */
594
595const char * /* O - User name */
596cupsUser(void)
597{
598 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
599
600
601 if (!cg->user[0])
3e7fe0ca 602 _cupsSetDefaults();
ef416fc2 603
604 return (cg->user);
605}
606
607
db8b865d
MS
608/*
609 * 'cupsUserAgent()' - Return the default HTTP User-Agent string.
610 *
8072030b 611 * @since CUPS 1.7/macOS 10.9@
db8b865d
MS
612 */
613
614const char * /* O - User-Agent string */
615cupsUserAgent(void)
616{
617 _cups_globals_t *cg = _cupsGlobals(); /* Thread globals */
618
619
620 if (!cg->user_agent[0])
621 cupsSetUserAgent(NULL);
622
623 return (cg->user_agent);
624}
625
626
ef416fc2 627/*
628 * '_cupsGetPassword()' - Get a password from the user.
629 */
630
dcb445bc 631const char * /* O - Password or @code NULL@ if none */
ef416fc2 632_cupsGetPassword(const char *prompt) /* I - Prompt string */
633{
19dc16f7 634#ifdef _WIN32
dcb445bc
MS
635 HANDLE tty; /* Console handle */
636 DWORD mode; /* Console mode */
637 char passch, /* Current key press */
638 *passptr, /* Pointer into password string */
639 *passend; /* End of password string */
12f89d24 640 DWORD passbytes; /* Bytes read */
dcb445bc
MS
641 _cups_globals_t *cg = _cupsGlobals();
642 /* Thread globals */
643
644
5a6b583a 645 /*
dcb445bc 646 * Disable input echo and set raw input...
5a6b583a
MS
647 */
648
dcb445bc
MS
649 if ((tty = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)
650 return (NULL);
651
652 if (!GetConsoleMode(tty, &mode))
653 return (NULL);
654
655 if (!SetConsoleMode(tty, 0))
656 return (NULL);
657
658 /*
659 * Display the prompt...
660 */
661
662 printf("%s ", prompt);
663 fflush(stdout);
664
665 /*
666 * Read the password string from /dev/tty until we get interrupted or get a
667 * carriage return or newline...
668 */
669
670 passptr = cg->password;
671 passend = cg->password + sizeof(cg->password) - 1;
672
12f89d24 673 while (ReadFile(tty, &passch, 1, &passbytes, NULL))
dcb445bc
MS
674 {
675 if (passch == 0x0A || passch == 0x0D)
676 {
677 /*
678 * Enter/return...
679 */
680
681 break;
682 }
683 else if (passch == 0x08 || passch == 0x7F)
684 {
685 /*
686 * Backspace/delete (erase character)...
687 */
688
689 if (passptr > cg->password)
690 {
691 passptr --;
692 fputs("\010 \010", stdout);
693 }
694 else
695 putchar(0x07);
696 }
697 else if (passch == 0x15)
698 {
699 /*
700 * CTRL+U (erase line)
701 */
702
703 if (passptr > cg->password)
704 {
705 while (passptr > cg->password)
706 {
707 passptr --;
708 fputs("\010 \010", stdout);
709 }
710 }
711 else
712 putchar(0x07);
713 }
714 else if (passch == 0x03)
715 {
716 /*
717 * CTRL+C...
718 */
719
720 passptr = cg->password;
721 break;
722 }
723 else if ((passch & 255) < 0x20 || passptr >= passend)
724 putchar(0x07);
725 else
726 {
727 *passptr++ = passch;
728 putchar(_CUPS_PASSCHAR);
729 }
730
731 fflush(stdout);
732 }
733
734 putchar('\n');
735 fflush(stdout);
736
737 /*
738 * Cleanup...
739 */
740
741 SetConsoleMode(tty, mode);
742
743 /*
744 * Return the proper value...
745 */
746
747 if (passbytes == 1 && passptr > cg->password)
748 {
749 *passptr = '\0';
750 return (cg->password);
751 }
752 else
753 {
754 memset(cg->password, 0, sizeof(cg->password));
755 return (NULL);
756 }
5a6b583a
MS
757
758#else
dcb445bc
MS
759 int tty; /* /dev/tty - never read from stdin */
760 struct termios original, /* Original input mode */
761 noecho; /* No echo input mode */
762 char passch, /* Current key press */
763 *passptr, /* Pointer into password string */
764 *passend; /* End of password string */
765 ssize_t passbytes; /* Bytes read */
766 _cups_globals_t *cg = _cupsGlobals();
767 /* Thread globals */
768
769
5a6b583a 770 /*
dcb445bc 771 * Disable input echo and set raw input...
5a6b583a
MS
772 */
773
dcb445bc
MS
774 if ((tty = open("/dev/tty", O_RDONLY)) < 0)
775 return (NULL);
776
777 if (tcgetattr(tty, &original))
778 {
779 close(tty);
780 return (NULL);
781 }
782
783 noecho = original;
7e86f2f6 784 noecho.c_lflag &= (tcflag_t)~(ICANON | ECHO | ECHOE | ISIG);
a8db9df8
MS
785 noecho.c_cc[VMIN] = 1;
786 noecho.c_cc[VTIME] = 0;
7cf5915e 787
dcb445bc
MS
788 if (tcsetattr(tty, TCSAFLUSH, &noecho))
789 {
790 close(tty);
7cf5915e 791 return (NULL);
dcb445bc
MS
792 }
793
794 /*
795 * Display the prompt...
796 */
797
798 printf("%s ", prompt);
799 fflush(stdout);
800
801 /*
802 * Read the password string from /dev/tty until we get interrupted or get a
803 * carriage return or newline...
804 */
805
806 passptr = cg->password;
807 passend = cg->password + sizeof(cg->password) - 1;
808
809 while ((passbytes = read(tty, &passch, 1)) == 1)
810 {
8dd318e5
MS
811 if (passch == noecho.c_cc[VEOL] ||
812# ifdef VEOL2
813 passch == noecho.c_cc[VEOL2] ||
814# endif /* VEOL2 */
dcb445bc
MS
815 passch == 0x0A || passch == 0x0D)
816 {
817 /*
818 * Enter/return...
819 */
820
821 break;
822 }
823 else if (passch == noecho.c_cc[VERASE] ||
824 passch == 0x08 || passch == 0x7F)
825 {
826 /*
827 * Backspace/delete (erase character)...
828 */
829
830 if (passptr > cg->password)
831 {
832 passptr --;
833 fputs("\010 \010", stdout);
834 }
835 else
836 putchar(0x07);
837 }
838 else if (passch == noecho.c_cc[VKILL])
839 {
840 /*
841 * CTRL+U (erase line)
842 */
843
844 if (passptr > cg->password)
845 {
846 while (passptr > cg->password)
847 {
848 passptr --;
849 fputs("\010 \010", stdout);
850 }
851 }
852 else
853 putchar(0x07);
854 }
855 else if (passch == noecho.c_cc[VINTR] || passch == noecho.c_cc[VQUIT] ||
856 passch == noecho.c_cc[VEOF])
857 {
858 /*
859 * CTRL+C, CTRL+D, or CTRL+Z...
860 */
861
862 passptr = cg->password;
863 break;
864 }
865 else if ((passch & 255) < 0x20 || passptr >= passend)
866 putchar(0x07);
867 else
868 {
869 *passptr++ = passch;
870 putchar(_CUPS_PASSCHAR);
871 }
872
873 fflush(stdout);
874 }
875
876 putchar('\n');
877 fflush(stdout);
878
879 /*
880 * Cleanup...
881 */
882
883 tcsetattr(tty, TCSAFLUSH, &original);
884 close(tty);
885
886 /*
887 * Return the proper value...
888 */
889
890 if (passbytes == 1 && passptr > cg->password)
891 {
892 *passptr = '\0';
893 return (cg->password);
894 }
7cf5915e 895 else
dcb445bc
MS
896 {
897 memset(cg->password, 0, sizeof(cg->password));
898 return (NULL);
899 }
19dc16f7 900#endif /* _WIN32 */
5a6b583a 901}
ef416fc2 902
903
eac3a0a0
MS
904#ifdef HAVE_GSSAPI
905/*
906 * '_cupsGSSServiceName()' - Get the GSS (Kerberos) service name.
907 */
908
909const char *
910_cupsGSSServiceName(void)
911{
912 _cups_globals_t *cg = _cupsGlobals(); /* Thread globals */
913
914
915 if (!cg->gss_service_name[0])
916 _cupsSetDefaults();
917
918 return (cg->gss_service_name);
919}
920#endif /* HAVE_GSSAPI */
921
922
ef416fc2 923/*
e07d4801 924 * '_cupsSetDefaults()' - Set the default server, port, and encryption.
b423cd4c 925 */
926
e07d4801
MS
927void
928_cupsSetDefaults(void)
b423cd4c 929{
930 cups_file_t *fp; /* File */
3abb875b 931 const char *home; /* Home directory of user */
b423cd4c 932 char filename[1024]; /* Filename */
3abb875b 933 _cups_client_conf_t cc; /* client.conf values */
b423cd4c 934 _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
935
936
e07d4801
MS
937 DEBUG_puts("_cupsSetDefaults()");
938
939 /*
3abb875b
MS
940 * Load initial client.conf values...
941 */
942
943 cups_init_client_conf(&cc);
944
945 /*
946 * Read the /etc/cups/client.conf and ~/.cups/client.conf files, if
947 * present.
948 */
949
950 snprintf(filename, sizeof(filename), "%s/client.conf", cg->cups_serverroot);
951 if ((fp = cupsFileOpen(filename, "r")) != NULL)
952 {
953 cups_read_client_conf(fp, &cc);
954 cupsFileClose(fp);
955 }
956
957# ifdef HAVE_GETEUID
958 if ((geteuid() == getuid() || !getuid()) && getegid() == getgid() && (home = getenv("HOME")) != NULL)
19dc16f7 959# elif !defined(_WIN32)
3abb875b
MS
960 if (getuid() && (home = getenv("HOME")) != NULL)
961# else
962 if ((home = getenv("HOME")) != NULL)
963# endif /* HAVE_GETEUID */
964 {
965 /*
966 * Look for ~/.cups/client.conf...
967 */
968
969 snprintf(filename, sizeof(filename), "%s/.cups/client.conf", home);
970 if ((fp = cupsFileOpen(filename, "r")) != NULL)
971 {
972 cups_read_client_conf(fp, &cc);
973 cupsFileClose(fp);
974 }
975 }
976
977 /*
978 * Finalize things so every client.conf value is set...
e07d4801
MS
979 */
980
3abb875b
MS
981 cups_finalize_client_conf(&cc);
982
983 if (cg->encryption == (http_encryption_t)-1)
984 cg->encryption = cc.encryption;
985
986 if (!cg->server[0] || !cg->ipp_port)
987 cupsSetServer(cc.server_name);
988
989 if (!cg->ipp_port)
4b9daaf4 990 cups_set_default_ipp_port(cg);
3abb875b
MS
991
992 if (!cg->user[0])
993 strlcpy(cg->user, cc.user, sizeof(cg->user));
994
995#ifdef HAVE_GSSAPI
996 if (!cg->gss_service_name[0])
997 strlcpy(cg->gss_service_name, cc.gss_service_name, sizeof(cg->gss_service_name));
998#endif /* HAVE_GSSAPI */
999
08d56b1f
MS
1000 if (cg->trust_first < 0)
1001 cg->trust_first = cc.trust_first;
1002
3abb875b
MS
1003 if (cg->any_root < 0)
1004 cg->any_root = cc.any_root;
1005
1006 if (cg->expired_certs < 0)
1007 cg->expired_certs = cc.expired_certs;
1008
1009 if (cg->validate_certs < 0)
1010 cg->validate_certs = cc.validate_certs;
1011
1012#ifdef HAVE_SSL
8f1fbdec 1013 _httpTLSSetOptions(cc.ssl_options | _HTTP_TLS_SET_DEFAULT, cc.ssl_min_version, cc.ssl_max_version);
3abb875b
MS
1014#endif /* HAVE_SSL */
1015}
1016
1017
08d56b1f
MS
1018#ifdef __APPLE__
1019/*
1020 * 'cups_apple_get_boolean()' - Get a boolean setting from the CUPS preferences.
1021 */
1022
1023static int /* O - 1 if set, 0 otherwise */
1024cups_apple_get_boolean(
1025 CFStringRef key, /* I - Key (name) */
1026 int *value) /* O - Boolean value */
1027{
1028 Boolean bval, /* Preference value */
1029 bval_set; /* Value is set? */
1030
1031
1032 bval = CFPreferencesGetAppBooleanValue(key, kCUPSPrintingPrefs, &bval_set);
1033
1034 if (bval_set)
1035 *value = (int)bval;
1036
1037 return ((int)bval_set);
1038}
1039
1040
1041/*
1042 * 'cups_apple_get_string()' - Get a string setting from the CUPS preferences.
1043 */
1044
1045static int /* O - 1 if set, 0 otherwise */
1046cups_apple_get_string(
1047 CFStringRef key, /* I - Key (name) */
1048 char *value, /* O - String value */
1049 size_t valsize) /* I - Size of value buffer */
1050{
1051 CFStringRef sval; /* String value */
1052
1053
1054 if ((sval = CFPreferencesCopyAppValue(key, kCUPSPrintingPrefs)) != NULL)
1055 {
1056 Boolean result = CFStringGetCString(sval, value, (CFIndex)valsize, kCFStringEncodingUTF8);
1057
1058 CFRelease(sval);
1059
1060 if (result)
1061 return (1);
1062 }
1063
1064 return (0);
1065}
1066#endif /* __APPLE__ */
1067
1068
3abb875b
MS
1069/*
1070 * 'cups_boolean_value()' - Convert a string to a boolean value.
1071 */
1072
1073static int /* O - Boolean value */
1074cups_boolean_value(const char *value) /* I - String value */
1075{
1076 return (!_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "on") || !_cups_strcasecmp(value, "true"));
1077}
1078
1079
1080/*
1081 * 'cups_finalize_client_conf()' - Finalize client.conf values.
1082 */
1083
1084static void
1085cups_finalize_client_conf(
1086 _cups_client_conf_t *cc) /* I - client.conf values */
1087{
1088 const char *value; /* Environment variable */
1089
1090
08d56b1f
MS
1091 if ((value = getenv("CUPS_TRUSTFIRST")) != NULL)
1092 cc->trust_first = cups_boolean_value(value);
1093
3abb875b
MS
1094 if ((value = getenv("CUPS_ANYROOT")) != NULL)
1095 cc->any_root = cups_boolean_value(value);
1096
1097 if ((value = getenv("CUPS_ENCRYPTION")) != NULL)
1098 cups_set_encryption(cc, value);
1099
1100 if ((value = getenv("CUPS_EXPIREDCERTS")) != NULL)
1101 cc->expired_certs = cups_boolean_value(value);
1102
07ed0e9a 1103#ifdef HAVE_GSSAPI
3abb875b
MS
1104 if ((value = getenv("CUPS_GSSSERVICENAME")) != NULL)
1105 cups_set_gss_service_name(cc, value);
07ed0e9a 1106#endif /* HAVE_GSSAPI */
3abb875b
MS
1107
1108 if ((value = getenv("CUPS_SERVER")) != NULL)
1109 cups_set_server_name(cc, value);
1110
1111 if ((value = getenv("CUPS_USER")) != NULL)
1112 cups_set_user(cc, value);
1113
1114 if ((value = getenv("CUPS_VALIDATECERTS")) != NULL)
1115 cc->validate_certs = cups_boolean_value(value);
e07d4801
MS
1116
1117 /*
3abb875b 1118 * Then apply defaults for those values that haven't been set...
e07d4801
MS
1119 */
1120
08d56b1f
MS
1121 if (cc->trust_first < 0)
1122 cc->trust_first = 1;
1123
3abb875b
MS
1124 if (cc->any_root < 0)
1125 cc->any_root = 1;
1126
1127 if (cc->encryption == (http_encryption_t)-1)
1128 cc->encryption = HTTP_ENCRYPTION_IF_REQUESTED;
1129
1130 if (cc->expired_certs < 0)
08d56b1f 1131 cc->expired_certs = 0;
3abb875b
MS
1132
1133#ifdef HAVE_GSSAPI
1134 if (!cc->gss_service_name[0])
1135 cups_set_gss_service_name(cc, CUPS_DEFAULT_GSSSERVICENAME);
1136#endif /* HAVE_GSSAPI */
1137
1138 if (!cc->server_name[0])
e07d4801 1139 {
3abb875b 1140#ifdef CUPS_DEFAULT_DOMAINSOCKET
63aefcd5 1141 /*
3abb875b
MS
1142 * If we are compiled with domain socket support, only use the
1143 * domain socket if it exists and has the right permissions...
63aefcd5
MS
1144 */
1145
89b7fd55 1146 if (!access(CUPS_DEFAULT_DOMAINSOCKET, R_OK))
3abb875b
MS
1147 cups_set_server_name(cc, CUPS_DEFAULT_DOMAINSOCKET);
1148 else
1149#endif /* CUPS_DEFAULT_DOMAINSOCKET */
1150 cups_set_server_name(cc, "localhost");
1151 }
63aefcd5 1152
3abb875b
MS
1153 if (!cc->user[0])
1154 {
19dc16f7 1155#ifdef _WIN32
63aefcd5 1156 /*
3abb875b 1157 * Get the current user name from the OS...
63aefcd5
MS
1158 */
1159
3abb875b 1160 DWORD size; /* Size of string */
63aefcd5 1161
3abb875b 1162 size = sizeof(cc->user);
86206ccf 1163 if (!GetUserNameA(cc->user, &size))
3abb875b 1164#else
63aefcd5 1165 /*
3abb875b 1166 * Try the USER environment variable as the default username...
63aefcd5
MS
1167 */
1168
3abb875b
MS
1169 const char *envuser = getenv("USER");
1170 /* Default username */
1171 struct passwd *pw = NULL; /* Account information */
1172
1173 if (envuser)
d09495fa 1174 {
10d09e33 1175 /*
3abb875b
MS
1176 * Validate USER matches the current UID, otherwise don't allow it to
1177 * override things... This makes sure that printing after doing su
1178 * or sudo records the correct username.
10d09e33 1179 */
e07d4801 1180
3abb875b
MS
1181 if ((pw = getpwnam(envuser)) != NULL && pw->pw_uid != getuid())
1182 pw = NULL;
1183 }
1184
1185 if (!pw)
1186 pw = getpwuid(getuid());
e07d4801 1187
3abb875b
MS
1188 if (pw)
1189 strlcpy(cc->user, pw->pw_name, sizeof(cc->user));
1190 else
19dc16f7 1191#endif /* _WIN32 */
3abb875b 1192 {
e07d4801 1193 /*
3abb875b 1194 * Use the default "unknown" user name...
e07d4801
MS
1195 */
1196
3abb875b 1197 strlcpy(cc->user, "unknown", sizeof(cc->user));
63aefcd5 1198 }
e07d4801 1199 }
3abb875b
MS
1200
1201 if (cc->validate_certs < 0)
1202 cc->validate_certs = 0;
1203}
1204
1205
1206/*
1207 * 'cups_init_client_conf()' - Initialize client.conf values.
1208 */
1209
1210static void
1211cups_init_client_conf(
1212 _cups_client_conf_t *cc) /* I - client.conf values */
1213{
1214 /*
1215 * Clear all values to "not set"...
1216 */
1217
1218 memset(cc, 0, sizeof(_cups_client_conf_t));
1219
3c2cb822 1220#if defined(__APPLE__) && !TARGET_OS_OSX
588c2205 1221 cups_set_user(cc, "mobile");
3c2cb822 1222#endif /* __APPLE__ && !TARGET_OS_OSX */
588c2205 1223
60da78ba 1224#ifdef HAVE_SSL
c88f441f
MS
1225 cc->ssl_min_version = _HTTP_TLS_1_0;
1226 cc->ssl_max_version = _HTTP_TLS_MAX;
60da78ba 1227#endif /* HAVE_SSL */
c88f441f
MS
1228 cc->encryption = (http_encryption_t)-1;
1229 cc->trust_first = -1;
1230 cc->any_root = -1;
1231 cc->expired_certs = -1;
1232 cc->validate_certs = -1;
08d56b1f
MS
1233
1234 /*
1235 * Load settings from the org.cups.PrintingPrefs plist (which trump
1236 * everything...)
1237 */
1238
b908d72c 1239#if defined(__APPLE__) && defined(HAVE_SSL)
08d56b1f
MS
1240 char sval[1024]; /* String value */
1241 int bval; /* Boolean value */
1242
1243 if (cups_apple_get_boolean(kAllowAnyRootKey, &bval))
1244 cc->any_root = bval;
1245
1246 if (cups_apple_get_boolean(kAllowExpiredCertsKey, &bval))
1247 cc->expired_certs = bval;
1248
1249 if (cups_apple_get_string(kEncryptionKey, sval, sizeof(sval)))
1250 cups_set_encryption(cc, sval);
1251
1252 if (cups_apple_get_string(kSSLOptionsKey, sval, sizeof(sval)))
588c2205 1253 {
08d56b1f 1254 cups_set_ssl_options(cc, sval);
588c2205
MS
1255 }
1256 else
1257 {
1258 sval[0] = '\0';
1259
1260 if (cups_apple_get_boolean(kAllowRC4, &bval) && bval)
1261 strlcat(sval, " AllowRC4", sizeof(sval));
1262 if (cups_apple_get_boolean(kAllowSSL3, &bval) && bval)
1263 strlcat(sval, " AllowSSL3", sizeof(sval));
1264 if (cups_apple_get_boolean(kAllowDH, &bval) && bval)
1265 strlcat(sval, " AllowDH", sizeof(sval));
1266
1267 if (sval[0])
1268 cups_set_ssl_options(cc, sval);
1269 }
08d56b1f
MS
1270
1271 if (cups_apple_get_boolean(kTrustOnFirstUseKey, &bval))
1272 cc->trust_first = bval;
1273
1274 if (cups_apple_get_boolean(kValidateCertsKey, &bval))
1275 cc->validate_certs = bval;
b908d72c 1276#endif /* __APPLE__ && HAVE_SSL */
e07d4801
MS
1277}
1278
1279
1280/*
1281 * 'cups_read_client_conf()' - Read a client.conf file.
1282 */
1283
1284static void
1285cups_read_client_conf(
3abb875b
MS
1286 cups_file_t *fp, /* I - File to read */
1287 _cups_client_conf_t *cc) /* I - client.conf values */
e07d4801
MS
1288{
1289 int linenum; /* Current line number */
1290 char line[1024], /* Line from file */
3abb875b 1291 *value; /* Pointer into line */
e07d4801
MS
1292
1293
1294 /*
1295 * Read from the file...
1296 */
1297
1298 linenum = 0;
1299 while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
1300 {
3abb875b
MS
1301 if (!_cups_strcasecmp(line, "Encryption") && value)
1302 cups_set_encryption(cc, value);
85dda01c
MS
1303#ifndef __APPLE__
1304 /*
8072030b 1305 * The ServerName directive is not supported on macOS due to app
3abb875b 1306 * sandboxing restrictions, i.e. not all apps request network access.
85dda01c 1307 */
3abb875b
MS
1308 else if (!_cups_strcasecmp(line, "ServerName") && value)
1309 cups_set_server_name(cc, value);
85dda01c 1310#endif /* !__APPLE__ */
3abb875b
MS
1311 else if (!_cups_strcasecmp(line, "User") && value)
1312 cups_set_user(cc, value);
08d56b1f
MS
1313 else if (!_cups_strcasecmp(line, "TrustOnFirstUse") && value)
1314 cc->trust_first = cups_boolean_value(value);
3abb875b
MS
1315 else if (!_cups_strcasecmp(line, "AllowAnyRoot") && value)
1316 cc->any_root = cups_boolean_value(value);
1317 else if (!_cups_strcasecmp(line, "AllowExpiredCerts") &&
7cf5915e 1318 value)
3abb875b
MS
1319 cc->expired_certs = cups_boolean_value(value);
1320 else if (!_cups_strcasecmp(line, "ValidateCerts") && value)
1321 cc->validate_certs = cups_boolean_value(value);
07ed0e9a 1322#ifdef HAVE_GSSAPI
3abb875b
MS
1323 else if (!_cups_strcasecmp(line, "GSSServiceName") && value)
1324 cups_set_gss_service_name(cc, value);
07ed0e9a 1325#endif /* HAVE_GSSAPI */
22ebb7d0 1326#ifdef HAVE_SSL
3abb875b
MS
1327 else if (!_cups_strcasecmp(line, "SSLOptions") && value)
1328 cups_set_ssl_options(cc, value);
1329#endif /* HAVE_SSL */
1330 }
1331}
63aefcd5 1332
63aefcd5 1333
4b9daaf4
MS
1334/*
1335 * 'cups_set_default_ipp_port()' - Set the default IPP port value.
1336 */
1337
1338static void
1339cups_set_default_ipp_port(
1340 _cups_globals_t *cg) /* I - Global data */
1341{
1342 const char *ipp_port; /* IPP_PORT environment variable */
1343
1344
1345 if ((ipp_port = getenv("IPP_PORT")) != NULL)
1346 {
1347 if ((cg->ipp_port = atoi(ipp_port)) <= 0)
1348 cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
1349 }
1350 else
1351 cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
1352}
1353
3abb875b
MS
1354/*
1355 * 'cups_set_encryption()' - Set the Encryption value.
1356 */
63aefcd5 1357
3abb875b
MS
1358static void
1359cups_set_encryption(
1360 _cups_client_conf_t *cc, /* I - client.conf values */
1361 const char *value) /* I - Value */
1362{
1363 if (!_cups_strcasecmp(value, "never"))
1364 cc->encryption = HTTP_ENCRYPTION_NEVER;
1365 else if (!_cups_strcasecmp(value, "always"))
1366 cc->encryption = HTTP_ENCRYPTION_ALWAYS;
1367 else if (!_cups_strcasecmp(value, "required"))
1368 cc->encryption = HTTP_ENCRYPTION_REQUIRED;
1369 else
1370 cc->encryption = HTTP_ENCRYPTION_IF_REQUESTED;
1371}
e07d4801 1372
e07d4801 1373
3abb875b
MS
1374/*
1375 * 'cups_set_gss_service_name()' - Set the GSSServiceName value.
1376 */
b423cd4c 1377
3abb875b
MS
1378#ifdef HAVE_GSSAPI
1379static void
1380cups_set_gss_service_name(
1381 _cups_client_conf_t *cc, /* I - client.conf values */
1382 const char *value) /* I - Value */
1383{
1384 strlcpy(cc->gss_service_name, value, sizeof(cc->gss_service_name));
1385}
1386#endif /* HAVE_GSSAPI */
7cf5915e 1387
10d09e33 1388
3abb875b
MS
1389/*
1390 * 'cups_set_server_name()' - Set the ServerName value.
1391 */
10d09e33 1392
3abb875b
MS
1393static void
1394cups_set_server_name(
1395 _cups_client_conf_t *cc, /* I - client.conf values */
1396 const char *value) /* I - Value */
1397{
1398 strlcpy(cc->server_name, value, sizeof(cc->server_name));
1399}
10d09e33 1400
10d09e33 1401
3abb875b
MS
1402/*
1403 * 'cups_set_ssl_options()' - Set the SSLOptions value.
1404 */
10d09e33 1405
3abb875b
MS
1406#ifdef HAVE_SSL
1407static void
1408cups_set_ssl_options(
1409 _cups_client_conf_t *cc, /* I - client.conf values */
1410 const char *value) /* I - Value */
1411{
1412 /*
ee6226a5 1413 * SSLOptions [AllowRC4] [AllowSSL3] [AllowDH] [DenyTLS1.0] [None]
3abb875b 1414 */
10d09e33 1415
8f1fbdec
MS
1416 int options = _HTTP_TLS_NONE, /* SSL/TLS options */
1417 min_version = _HTTP_TLS_1_0, /* Minimum SSL/TLS version */
1418 max_version = _HTTP_TLS_MAX; /* Maximum SSL/TLS version */
3abb875b
MS
1419 char temp[256], /* Copy of value */
1420 *start, /* Start of option */
1421 *end; /* End of option */
3e7fe0ca 1422
3e7fe0ca 1423
3abb875b 1424 strlcpy(temp, value, sizeof(temp));
3e7fe0ca 1425
3abb875b
MS
1426 for (start = temp; *start; start = end)
1427 {
a8db9df8 1428 /*
3abb875b
MS
1429 * Find end of keyword...
1430 */
3e7fe0ca 1431
3abb875b
MS
1432 end = start;
1433 while (*end && !_cups_isspace(*end))
1434 end ++;
93e3d3f5 1435
3abb875b
MS
1436 if (*end)
1437 *end++ = '\0';
93e3d3f5 1438
3abb875b
MS
1439 /*
1440 * Compare...
1441 */
3e7fe0ca 1442
3abb875b
MS
1443 if (!_cups_strcasecmp(start, "AllowRC4"))
1444 options |= _HTTP_TLS_ALLOW_RC4;
1445 else if (!_cups_strcasecmp(start, "AllowSSL3"))
8f1fbdec 1446 min_version = _HTTP_TLS_SSL3;
ee6226a5
MS
1447 else if (!_cups_strcasecmp(start, "AllowDH"))
1448 options |= _HTTP_TLS_ALLOW_DH;
f2e87147
MS
1449 else if (!_cups_strcasecmp(start, "DenyCBC"))
1450 options |= _HTTP_TLS_DENY_CBC;
ee6226a5 1451 else if (!_cups_strcasecmp(start, "DenyTLS1.0"))
8f1fbdec
MS
1452 min_version = _HTTP_TLS_1_1;
1453 else if (!_cups_strcasecmp(start, "MaxTLS1.0"))
1454 max_version = _HTTP_TLS_1_0;
1455 else if (!_cups_strcasecmp(start, "MaxTLS1.1"))
1456 max_version = _HTTP_TLS_1_1;
1457 else if (!_cups_strcasecmp(start, "MaxTLS1.2"))
1458 max_version = _HTTP_TLS_1_2;
1459 else if (!_cups_strcasecmp(start, "MaxTLS1.3"))
1460 max_version = _HTTP_TLS_1_3;
1461 else if (!_cups_strcasecmp(start, "MinTLS1.0"))
1462 min_version = _HTTP_TLS_1_0;
1463 else if (!_cups_strcasecmp(start, "MinTLS1.1"))
1464 min_version = _HTTP_TLS_1_1;
1465 else if (!_cups_strcasecmp(start, "MinTLS1.2"))
1466 min_version = _HTTP_TLS_1_2;
1467 else if (!_cups_strcasecmp(start, "MinTLS1.3"))
1468 min_version = _HTTP_TLS_1_3;
3abb875b 1469 else if (!_cups_strcasecmp(start, "None"))
ee6226a5 1470 options = _HTTP_TLS_NONE;
3e7fe0ca
MS
1471 }
1472
8f1fbdec
MS
1473 cc->ssl_options = options;
1474 cc->ssl_max_version = max_version;
1475 cc->ssl_min_version = min_version;
b37d45d9 1476
8f1fbdec 1477 DEBUG_printf(("4cups_set_ssl_options(cc=%p, value=\"%s\") options=%x, min_version=%d, max_version=%d", (void *)cc, value, options, min_version, max_version));
3abb875b
MS
1478}
1479#endif /* HAVE_SSL */
07ed0e9a 1480
7cf5915e 1481
3abb875b
MS
1482/*
1483 * 'cups_set_user()' - Set the User value.
1484 */
f51f3773 1485
3abb875b
MS
1486static void
1487cups_set_user(
1488 _cups_client_conf_t *cc, /* I - client.conf values */
1489 const char *value) /* I - Value */
1490{
1491 strlcpy(cc->user, value, sizeof(cc->user));
b423cd4c 1492}