4 * User, system, and password routines for CUPS.
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * Include necessary headers...
22 #include "cups-private.h"
30 # include <sys/utsname.h>
38 #define _CUPS_PASSCHAR '*' /* Character that is echoed for password */
45 static void cups_read_client_conf(cups_file_t
*fp
,
47 const char *cups_encryption
,
48 const char *cups_server
,
49 const char *cups_user
,
51 const char *cups_gssservicename
,
52 #endif /* HAVE_GSSAPI */
53 const char *cups_anyroot
,
54 const char *cups_expiredcerts
,
55 const char *cups_validatecerts
,
60 * 'cupsEncryption()' - Get the current encryption settings.
62 * The default encryption setting comes from the CUPS_ENCRYPTION
63 * environment variable, then the ~/.cups/client.conf file, and finally the
64 * /etc/cups/client.conf file. If not set, the default is
65 * @code HTTP_ENCRYPTION_IF_REQUESTED@.
67 * Note: The current encryption setting is tracked separately for each thread
68 * in a program. Multi-threaded programs that override the setting via the
69 * @link cupsSetEncryption@ function need to do so in each thread for the same
73 http_encryption_t
/* O - Encryption settings */
76 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
79 if (cg
->encryption
== (http_encryption_t
)-1)
82 return (cg
->encryption
);
87 * 'cupsGetPassword()' - Get a password from the user.
89 * Uses the current password callback function. Returns @code NULL@ if the
90 * user does not provide a password.
92 * Note: The current password callback function is tracked separately for each
93 * thread in a program. Multi-threaded programs that override the setting via
94 * the @link cupsSetPasswordCB@ or @link cupsSetPasswordCB2@ functions need to
95 * do so in each thread for the same function to be used.
98 const char * /* O - Password */
99 cupsGetPassword(const char *prompt
) /* I - Prompt string */
101 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
104 return ((cg
->password_cb
)(prompt
, NULL
, NULL
, NULL
, cg
->password_data
));
109 * 'cupsGetPassword2()' - Get a password from the user using the advanced
112 * Uses the current password callback function. Returns @code NULL@ if the
113 * user does not provide a password.
115 * Note: The current password callback function is tracked separately for each
116 * thread in a program. Multi-threaded programs that override the setting via
117 * the @link cupsSetPasswordCB@ or @link cupsSetPasswordCB2@ functions need to
118 * do so in each thread for the same function to be used.
120 * @since CUPS 1.4/OS X 10.6@
123 const char * /* O - Password */
124 cupsGetPassword2(const char *prompt
, /* I - Prompt string */
125 http_t
*http
, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
126 const char *method
, /* I - Request method ("GET", "POST", "PUT") */
127 const char *resource
) /* I - Resource path */
129 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
133 http
= _cupsConnect();
135 return ((cg
->password_cb
)(prompt
, http
, method
, resource
, cg
->password_data
));
140 * 'cupsServer()' - Return the hostname/address of the current server.
142 * The default server comes from the CUPS_SERVER environment variable, then the
143 * ~/.cups/client.conf file, and finally the /etc/cups/client.conf file. If not
144 * set, the default is the local system - either "localhost" or a domain socket
147 * The returned value can be a fully-qualified hostname, a numeric IPv4 or IPv6
148 * address, or a domain socket pathname.
150 * Note: The current server is tracked separately for each thread in a program.
151 * Multi-threaded programs that override the server via the
152 * @link cupsSetServer@ function need to do so in each thread for the same
156 const char * /* O - Server name */
159 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
170 * 'cupsSetClientCertCB()' - Set the client certificate callback.
172 * Pass @code NULL@ to restore the default callback.
174 * Note: The current certificate callback is tracked separately for each thread
175 * in a program. Multi-threaded programs that override the callback need to do
176 * so in each thread for the same callback to be used.
178 * @since CUPS 1.5/OS X 10.7@
183 cups_client_cert_cb_t cb
, /* I - Callback function */
184 void *user_data
) /* I - User data pointer */
186 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
189 cg
->client_cert_cb
= cb
;
190 cg
->client_cert_data
= user_data
;
195 * 'cupsSetCredentials()' - Set the default credentials to be used for SSL/TLS
198 * Note: The default credentials are tracked separately for each thread in a
199 * program. Multi-threaded programs that override the setting need to do so in
200 * each thread for the same setting to be used.
202 * @since CUPS 1.5/OS X 10.7@
205 int /* O - Status of call (0 = success) */
207 cups_array_t
*credentials
) /* I - Array of credentials */
209 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
212 if (cupsArrayCount(credentials
) < 1)
216 _httpFreeCredentials(cg
->tls_credentials
);
217 cg
->tls_credentials
= _httpCreateCredentials(credentials
);
218 #endif /* HAVE_SSL */
220 return (cg
->tls_credentials
? 0 : -1);
225 * 'cupsSetEncryption()' - Set the encryption preference.
227 * The default encryption setting comes from the CUPS_ENCRYPTION
228 * environment variable, then the ~/.cups/client.conf file, and finally the
229 * /etc/cups/client.conf file. If not set, the default is
230 * @code HTTP_ENCRYPTION_IF_REQUESTED@.
232 * Note: The current encryption setting is tracked separately for each thread
233 * in a program. Multi-threaded programs that override the setting need to do
234 * so in each thread for the same setting to be used.
238 cupsSetEncryption(http_encryption_t e
) /* I - New encryption preference */
240 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
246 httpEncryption(cg
->http
, e
);
251 * 'cupsSetPasswordCB()' - Set the password callback for CUPS.
253 * Pass @code NULL@ to restore the default (console) password callback, which
254 * reads the password from the console. Programs should call either this
255 * function or @link cupsSetPasswordCB2@, as only one callback can be registered
256 * by a program per thread.
258 * Note: The current password callback is tracked separately for each thread
259 * in a program. Multi-threaded programs that override the callback need to do
260 * so in each thread for the same callback to be used.
264 cupsSetPasswordCB(cups_password_cb_t cb
)/* I - Callback function */
266 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
269 if (cb
== (cups_password_cb_t
)0)
270 cg
->password_cb
= (cups_password_cb2_t
)_cupsGetPassword
;
272 cg
->password_cb
= (cups_password_cb2_t
)cb
;
274 cg
->password_data
= NULL
;
279 * 'cupsSetPasswordCB2()' - Set the advanced password callback for CUPS.
281 * Pass @code NULL@ to restore the default (console) password callback, which
282 * reads the password from the console. Programs should call either this
283 * function or @link cupsSetPasswordCB2@, as only one callback can be registered
284 * by a program per thread.
286 * Note: The current password callback is tracked separately for each thread
287 * in a program. Multi-threaded programs that override the callback need to do
288 * so in each thread for the same callback to be used.
290 * @since CUPS 1.4/OS X 10.6@
295 cups_password_cb2_t cb
, /* I - Callback function */
296 void *user_data
) /* I - User data pointer */
298 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
301 if (cb
== (cups_password_cb2_t
)0)
302 cg
->password_cb
= (cups_password_cb2_t
)_cupsGetPassword
;
304 cg
->password_cb
= cb
;
306 cg
->password_data
= user_data
;
311 * 'cupsSetServer()' - Set the default server name and port.
313 * The "server" string can be a fully-qualified hostname, a numeric
314 * IPv4 or IPv6 address, or a domain socket pathname. Hostnames and numeric IP
315 * addresses can be optionally followed by a colon and port number to override
316 * the default port 631, e.g. "hostname:8631". Pass @code NULL@ to restore the
317 * default server name and port.
319 * Note: The current server is tracked separately for each thread in a program.
320 * Multi-threaded programs that override the server need to do so in each
321 * thread for the same server to be used.
325 cupsSetServer(const char *server
) /* I - Server name */
327 char *options
, /* Options */
328 *port
; /* Pointer to port */
329 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
334 strlcpy(cg
->server
, server
, sizeof(cg
->server
));
336 if (cg
->server
[0] != '/' && (options
= strrchr(cg
->server
, '/')) != NULL
)
340 if (!strcmp(options
, "version=1.0"))
341 cg
->server_version
= 10;
342 else if (!strcmp(options
, "version=1.1"))
343 cg
->server_version
= 11;
344 else if (!strcmp(options
, "version=2.0"))
345 cg
->server_version
= 20;
346 else if (!strcmp(options
, "version=2.1"))
347 cg
->server_version
= 21;
348 else if (!strcmp(options
, "version=2.2"))
349 cg
->server_version
= 22;
352 cg
->server_version
= 20;
354 if (cg
->server
[0] != '/' && (port
= strrchr(cg
->server
, ':')) != NULL
&&
355 !strchr(port
, ']') && isdigit(port
[1] & 255))
359 cg
->ipp_port
= atoi(port
);
362 if (cg
->server
[0] == '/')
363 strlcpy(cg
->servername
, "localhost", sizeof(cg
->servername
));
365 strlcpy(cg
->servername
, cg
->server
, sizeof(cg
->servername
));
369 cg
->server
[0] = '\0';
370 cg
->servername
[0] = '\0';
371 cg
->server_version
= 20;
383 * 'cupsSetServerCertCB()' - Set the server certificate callback.
385 * Pass @code NULL@ to restore the default callback.
387 * Note: The current credentials callback is tracked separately for each thread
388 * in a program. Multi-threaded programs that override the callback need to do
389 * so in each thread for the same callback to be used.
391 * @since CUPS 1.5/OS X 10.7@
396 cups_server_cert_cb_t cb
, /* I - Callback function */
397 void *user_data
) /* I - User data pointer */
399 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
402 cg
->server_cert_cb
= cb
;
403 cg
->server_cert_data
= user_data
;
408 * 'cupsSetUser()' - Set the default user name.
410 * Pass @code NULL@ to restore the default user name.
412 * Note: The current user name is tracked separately for each thread in a
413 * program. Multi-threaded programs that override the user name need to do so
414 * in each thread for the same user name to be used.
418 cupsSetUser(const char *user
) /* I - User name */
420 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
424 strlcpy(cg
->user
, user
, sizeof(cg
->user
));
431 * 'cupsSetUserAgent()' - Set the default HTTP User-Agent string.
433 * Setting the string to NULL forces the default value containing the CUPS
434 * version, IPP version, and operating system version and architecture.
436 * @since CUPS 1.7/OS X 10.9@
440 cupsSetUserAgent(const char *user_agent
)/* I - User-Agent string or @code NULL@ */
442 _cups_globals_t
*cg
= _cupsGlobals();
445 SYSTEM_INFO sysinfo
; /* System information */
446 OSVERSIONINFO version
; /* OS version info */
448 struct utsname name
; /* uname info */
454 strlcpy(cg
->user_agent
, user_agent
, sizeof(cg
->user_agent
));
459 version
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
460 GetVersionEx(&version
);
461 GetNativeSystemInfo(&sysinfo
);
463 snprintf(cg
->user_agent
, sizeof(cg
->user_agent
),
464 CUPS_MINIMAL
" (Windows %d.%d; %s) IPP/2.0",
465 version
.dwMajorVersion
, version
.dwMinorVersion
,
466 sysinfo
.wProcessorArchitecture
467 == PROCESSOR_ARCHITECTURE_AMD64
? "amd64" :
468 sysinfo
.wProcessorArchitecture
469 == PROCESSOR_ARCHITECTURE_ARM
? "arm" :
470 sysinfo
.wProcessorArchitecture
471 == PROCESSOR_ARCHITECTURE_IA64
? "ia64" :
472 sysinfo
.wProcessorArchitecture
473 == PROCESSOR_ARCHITECTURE_INTEL
? "intel" :
479 snprintf(cg
->user_agent
, sizeof(cg
->user_agent
),
480 CUPS_MINIMAL
" (%s %s; %s) IPP/2.0",
481 name
.sysname
, name
.release
, name
.machine
);
487 * 'cupsUser()' - Return the current user's name.
489 * Note: The current user name is tracked separately for each thread in a
490 * program. Multi-threaded programs that override the user name with the
491 * @link cupsSetUser@ function need to do so in each thread for the same user
495 const char * /* O - User name */
498 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
509 * 'cupsUserAgent()' - Return the default HTTP User-Agent string.
511 * @since CUPS 1.7/OS X 10.9@
514 const char * /* O - User-Agent string */
517 _cups_globals_t
*cg
= _cupsGlobals(); /* Thread globals */
520 if (!cg
->user_agent
[0])
521 cupsSetUserAgent(NULL
);
523 return (cg
->user_agent
);
528 * '_cupsGetPassword()' - Get a password from the user.
531 const char * /* O - Password or @code NULL@ if none */
532 _cupsGetPassword(const char *prompt
) /* I - Prompt string */
535 HANDLE tty
; /* Console handle */
536 DWORD mode
; /* Console mode */
537 char passch
, /* Current key press */
538 *passptr
, /* Pointer into password string */
539 *passend
; /* End of password string */
540 DWORD passbytes
; /* Bytes read */
541 _cups_globals_t
*cg
= _cupsGlobals();
546 * Disable input echo and set raw input...
549 if ((tty
= GetStdHandle(STD_INPUT_HANDLE
)) == INVALID_HANDLE_VALUE
)
552 if (!GetConsoleMode(tty
, &mode
))
555 if (!SetConsoleMode(tty
, 0))
559 * Display the prompt...
562 printf("%s ", prompt
);
566 * Read the password string from /dev/tty until we get interrupted or get a
567 * carriage return or newline...
570 passptr
= cg
->password
;
571 passend
= cg
->password
+ sizeof(cg
->password
) - 1;
573 while (ReadFile(tty
, &passch
, 1, &passbytes
, NULL
))
575 if (passch
== 0x0A || passch
== 0x0D)
583 else if (passch
== 0x08 || passch
== 0x7F)
586 * Backspace/delete (erase character)...
589 if (passptr
> cg
->password
)
592 fputs("\010 \010", stdout
);
597 else if (passch
== 0x15)
600 * CTRL+U (erase line)
603 if (passptr
> cg
->password
)
605 while (passptr
> cg
->password
)
608 fputs("\010 \010", stdout
);
614 else if (passch
== 0x03)
620 passptr
= cg
->password
;
623 else if ((passch
& 255) < 0x20 || passptr
>= passend
)
628 putchar(_CUPS_PASSCHAR
);
641 SetConsoleMode(tty
, mode
);
644 * Return the proper value...
647 if (passbytes
== 1 && passptr
> cg
->password
)
650 return (cg
->password
);
654 memset(cg
->password
, 0, sizeof(cg
->password
));
659 int tty
; /* /dev/tty - never read from stdin */
660 struct termios original
, /* Original input mode */
661 noecho
; /* No echo input mode */
662 char passch
, /* Current key press */
663 *passptr
, /* Pointer into password string */
664 *passend
; /* End of password string */
665 ssize_t passbytes
; /* Bytes read */
666 _cups_globals_t
*cg
= _cupsGlobals();
671 * Disable input echo and set raw input...
674 if ((tty
= open("/dev/tty", O_RDONLY
)) < 0)
677 if (tcgetattr(tty
, &original
))
684 noecho
.c_lflag
&= (tcflag_t
)~(ICANON
| ECHO
| ECHOE
| ISIG
);
686 if (tcsetattr(tty
, TCSAFLUSH
, &noecho
))
693 * Display the prompt...
696 printf("%s ", prompt
);
700 * Read the password string from /dev/tty until we get interrupted or get a
701 * carriage return or newline...
704 passptr
= cg
->password
;
705 passend
= cg
->password
+ sizeof(cg
->password
) - 1;
707 while ((passbytes
= read(tty
, &passch
, 1)) == 1)
709 if (passch
== noecho
.c_cc
[VEOL
] ||
711 passch
== noecho
.c_cc
[VEOL2
] ||
713 passch
== 0x0A || passch
== 0x0D)
721 else if (passch
== noecho
.c_cc
[VERASE
] ||
722 passch
== 0x08 || passch
== 0x7F)
725 * Backspace/delete (erase character)...
728 if (passptr
> cg
->password
)
731 fputs("\010 \010", stdout
);
736 else if (passch
== noecho
.c_cc
[VKILL
])
739 * CTRL+U (erase line)
742 if (passptr
> cg
->password
)
744 while (passptr
> cg
->password
)
747 fputs("\010 \010", stdout
);
753 else if (passch
== noecho
.c_cc
[VINTR
] || passch
== noecho
.c_cc
[VQUIT
] ||
754 passch
== noecho
.c_cc
[VEOF
])
757 * CTRL+C, CTRL+D, or CTRL+Z...
760 passptr
= cg
->password
;
763 else if ((passch
& 255) < 0x20 || passptr
>= passend
)
768 putchar(_CUPS_PASSCHAR
);
781 tcsetattr(tty
, TCSAFLUSH
, &original
);
785 * Return the proper value...
788 if (passbytes
== 1 && passptr
> cg
->password
)
791 return (cg
->password
);
795 memset(cg
->password
, 0, sizeof(cg
->password
));
804 * '_cupsGSSServiceName()' - Get the GSS (Kerberos) service name.
808 _cupsGSSServiceName(void)
810 _cups_globals_t
*cg
= _cupsGlobals(); /* Thread globals */
813 if (!cg
->gss_service_name
[0])
816 return (cg
->gss_service_name
);
818 #endif /* HAVE_GSSAPI */
822 * '_cupsSetDefaults()' - Set the default server, port, and encryption.
826 _cupsSetDefaults(void)
828 cups_file_t
*fp
; /* File */
829 const char *home
, /* Home directory of user */
830 *cups_encryption
, /* CUPS_ENCRYPTION env var */
831 *cups_server
, /* CUPS_SERVER env var */
832 *cups_user
, /* CUPS_USER/USER env var */
834 *cups_gssservicename
, /* CUPS_GSSSERVICENAME env var */
835 #endif /* HAVE_GSSAPI */
836 *cups_anyroot
, /* CUPS_ANYROOT env var */
837 *cups_expiredcerts
, /* CUPS_EXPIREDCERTS env var */
838 *cups_validatecerts
; /* CUPS_VALIDATECERTS env var */
839 char filename
[1024]; /* Filename */
840 _cups_globals_t
*cg
= _cupsGlobals(); /* Pointer to library globals */
843 DEBUG_puts("_cupsSetDefaults()");
846 * First collect environment variables...
849 cups_encryption
= getenv("CUPS_ENCRYPTION");
850 cups_server
= getenv("CUPS_SERVER");
852 cups_gssservicename
= getenv("CUPS_GSSSERVICENAME");
853 #endif /* HAVE_GSSAPI */
854 cups_anyroot
= getenv("CUPS_ANYROOT");
855 cups_expiredcerts
= getenv("CUPS_EXPIREDCERTS");
856 cups_user
= getenv("CUPS_USER");
857 cups_validatecerts
= getenv("CUPS_VALIDATECERTS");
860 * Then, if needed, read the ~/.cups/client.conf or /etc/cups/client.conf
861 * files to get the default values...
864 if (cg
->encryption
== (http_encryption_t
)-1 || !cg
->server
[0] ||
865 !cg
->user
[0] || !cg
->ipp_port
)
868 * Look for CUPS_SERVERROOT/client.conf...
871 snprintf(filename
, sizeof(filename
), "%s/client.conf",
872 cg
->cups_serverroot
);
873 fp
= cupsFileOpen(filename
, "r");
876 * Read the configuration file and apply any environment variables; both
877 * functions handle NULL cups_file_t pointers...
880 cups_read_client_conf(fp
, cg
, cups_encryption
, cups_server
, cups_user
,
883 #endif /* HAVE_GSSAPI */
884 cups_anyroot
, cups_expiredcerts
, cups_validatecerts
, 1);
888 * Then user defaults, if it is safe to do so...
892 if ((geteuid() == getuid() || !getuid()) && getegid() == getgid() && (home
= getenv("HOME")) != NULL
)
893 # elif !defined(WIN32)
894 if (getuid() && (home
= getenv("HOME")) != NULL
)
896 if ((home
= getenv("HOME")) != NULL
)
897 # endif /* HAVE_GETEUID */
900 * Look for ~/.cups/client.conf...
903 snprintf(filename
, sizeof(filename
), "%s/.cups/client.conf", home
);
904 fp
= cupsFileOpen(filename
, "r");
907 * Read the configuration file and apply any environment variables; both
908 * functions handle NULL cups_file_t pointers...
911 cups_read_client_conf(fp
, cg
, cups_encryption
, cups_server
, cups_user
,
914 #endif /* HAVE_GSSAPI */
915 cups_anyroot
, cups_expiredcerts
, cups_validatecerts
, 0);
923 * 'cups_read_client_conf()' - Read a client.conf file.
927 cups_read_client_conf(
928 cups_file_t
*fp
, /* I - File to read */
929 _cups_globals_t
*cg
, /* I - Global data */
930 const char *cups_encryption
, /* I - CUPS_ENCRYPTION env var */
931 const char *cups_server
, /* I - CUPS_SERVER env var */
932 const char *cups_user
, /* I - CUPS_USER env var */
934 const char *cups_gssservicename
,
935 /* I - CUPS_GSSSERVICENAME env var */
936 #endif /* HAVE_GSSAPI */
937 const char *cups_anyroot
, /* I - CUPS_ANYROOT env var */
938 const char *cups_expiredcerts
, /* I - CUPS_EXPIREDCERTS env var */
939 const char *cups_validatecerts
,/* I - CUPS_VALIDATECERTS env var */
940 int ssl_options
) /* I - Allow setting of SSLOptions? */
942 int linenum
; /* Current line number */
943 char line
[1024], /* Line from file */
944 *value
, /* Pointer into line */
945 encryption
[1024], /* Encryption value */
947 server_name
[1024], /* ServerName value */
948 #endif /* !__APPLE__ */
949 user
[256], /* User value */
950 any_root
[1024], /* AllowAnyRoot value */
951 expired_certs
[1024], /* AllowExpiredCerts value */
952 validate_certs
[1024]; /* ValidateCerts value */
954 char gss_service_name
[32]; /* GSSServiceName value */
955 #endif /* HAVE_GSSAPI */
958 (void)ssl_options
; /* Silence compiler warning */
961 * Read from the file...
965 while (cupsFileGetConf(fp
, line
, sizeof(line
), &value
, &linenum
))
967 if (!cups_encryption
&& cg
->encryption
== (http_encryption_t
)-1 &&
968 !_cups_strcasecmp(line
, "Encryption") && value
)
970 strlcpy(encryption
, value
, sizeof(encryption
));
971 cups_encryption
= encryption
;
975 * The Server directive is not supported on OS X due to app sandboxing
976 * restrictions, i.e. not all apps request network access.
978 else if (!cups_server
&& (!cg
->server
[0] || !cg
->ipp_port
) &&
979 !_cups_strcasecmp(line
, "ServerName") && value
)
981 strlcpy(server_name
, value
, sizeof(server_name
));
982 cups_server
= server_name
;
984 #endif /* !__APPLE__ */
985 else if (!cups_user
&& !_cups_strcasecmp(line
, "User") && value
)
987 strlcpy(user
, value
, sizeof(user
));
990 else if (!cups_anyroot
&& !_cups_strcasecmp(line
, "AllowAnyRoot") && value
)
992 strlcpy(any_root
, value
, sizeof(any_root
));
993 cups_anyroot
= any_root
;
995 else if (!cups_expiredcerts
&& !_cups_strcasecmp(line
, "AllowExpiredCerts") &&
998 strlcpy(expired_certs
, value
, sizeof(expired_certs
));
999 cups_expiredcerts
= expired_certs
;
1001 else if (!cups_validatecerts
&& !_cups_strcasecmp(line
, "ValidateCerts") && value
)
1003 strlcpy(validate_certs
, value
, sizeof(validate_certs
));
1004 cups_validatecerts
= validate_certs
;
1007 else if (!cups_gssservicename
&& !_cups_strcasecmp(line
, "GSSServiceName") &&
1010 strlcpy(gss_service_name
, value
, sizeof(gss_service_name
));
1011 cups_gssservicename
= gss_service_name
;
1013 #endif /* HAVE_GSSAPI */
1015 else if (ssl_options
&& !_cups_strcasecmp(line
, "SSLOptions") && value
)
1018 * SSLOptions [AllowRC4] [AllowSSL3] [None]
1021 int options
= 0; /* SSL/TLS options */
1022 char *start
, /* Start of option */
1023 *end
; /* End of option */
1025 for (start
= value
; *start
; start
= end
)
1028 * Find end of keyword...
1032 while (*end
&& !_cups_isspace(*end
))
1042 if (!_cups_strcasecmp(start
, "AllowRC4"))
1043 options
|= _HTTP_TLS_ALLOW_RC4
;
1044 else if (!_cups_strcasecmp(start
, "AllowSSL3"))
1045 options
|= _HTTP_TLS_ALLOW_SSL3
;
1046 else if (!_cups_strcasecmp(start
, "None"))
1050 _httpTLSSetOptions(options
);
1052 #endif /* HAVE_SSL */
1059 if (cg
->encryption
== (http_encryption_t
)-1 && cups_encryption
)
1061 if (!_cups_strcasecmp(cups_encryption
, "never"))
1062 cg
->encryption
= HTTP_ENCRYPTION_NEVER
;
1063 else if (!_cups_strcasecmp(cups_encryption
, "always"))
1064 cg
->encryption
= HTTP_ENCRYPTION_ALWAYS
;
1065 else if (!_cups_strcasecmp(cups_encryption
, "required"))
1066 cg
->encryption
= HTTP_ENCRYPTION_REQUIRED
;
1068 cg
->encryption
= HTTP_ENCRYPTION_IF_REQUESTED
;
1071 if ((!cg
->server
[0] || !cg
->ipp_port
) && cups_server
)
1072 cupsSetServer(cups_server
);
1076 #ifdef CUPS_DEFAULT_DOMAINSOCKET
1078 * If we are compiled with domain socket support, only use the
1079 * domain socket if it exists and has the right permissions...
1082 struct stat sockinfo
; /* Domain socket information */
1084 if (!stat(CUPS_DEFAULT_DOMAINSOCKET
, &sockinfo
) &&
1085 (sockinfo
.st_mode
& S_IRWXO
) == S_IRWXO
)
1086 cups_server
= CUPS_DEFAULT_DOMAINSOCKET
;
1088 #endif /* CUPS_DEFAULT_DOMAINSOCKET */
1089 cups_server
= "localhost";
1091 cupsSetServer(cups_server
);
1096 const char *ipp_port
; /* IPP_PORT environment variable */
1098 if ((ipp_port
= getenv("IPP_PORT")) != NULL
)
1100 if ((cg
->ipp_port
= atoi(ipp_port
)) <= 0)
1101 cg
->ipp_port
= CUPS_DEFAULT_IPP_PORT
;
1104 cg
->ipp_port
= CUPS_DEFAULT_IPP_PORT
;
1110 strlcpy(cg
->user
, cups_user
, sizeof(cg
->user
));
1115 * Get the current user name from the OS...
1118 DWORD size
; /* Size of string */
1120 size
= sizeof(cg
->user
);
1121 if (!GetUserName(cg
->user
, &size
))
1124 * Try the USER environment variable as the default username...
1127 const char *envuser
= getenv("USER");
1128 /* Default username */
1129 struct passwd
*pw
= NULL
; /* Account information */
1134 * Validate USER matches the current UID, otherwise don't allow it to
1135 * override things... This makes sure that printing after doing su or
1136 * sudo records the correct username.
1139 if ((pw
= getpwnam(envuser
)) != NULL
&& pw
->pw_uid
!= getuid())
1144 pw
= getpwuid(getuid());
1147 strlcpy(cg
->user
, pw
->pw_name
, sizeof(cg
->user
));
1152 * Use the default "unknown" user name...
1155 strlcpy(cg
->user
, "unknown", sizeof(cg
->user
));
1161 if (!cups_gssservicename
)
1162 cups_gssservicename
= CUPS_DEFAULT_GSSSERVICENAME
;
1164 strlcpy(cg
->gss_service_name
, cups_gssservicename
,
1165 sizeof(cg
->gss_service_name
));
1166 #endif /* HAVE_GSSAPI */
1169 cg
->any_root
= !_cups_strcasecmp(cups_anyroot
, "yes") ||
1170 !_cups_strcasecmp(cups_anyroot
, "on") ||
1171 !_cups_strcasecmp(cups_anyroot
, "true");
1173 if (cups_expiredcerts
)
1174 cg
->expired_certs
= !_cups_strcasecmp(cups_expiredcerts
, "yes") ||
1175 !_cups_strcasecmp(cups_expiredcerts
, "on") ||
1176 !_cups_strcasecmp(cups_expiredcerts
, "true");
1178 if (cups_validatecerts
)
1179 cg
->validate_certs
= !_cups_strcasecmp(cups_validatecerts
, "yes") ||
1180 !_cups_strcasecmp(cups_validatecerts
, "on") ||
1181 !_cups_strcasecmp(cups_validatecerts
, "true");