apache2-mod_nss/mod_nss-bnc863518-reopen_dev_tty.diff
Wolfgang Rosenauer ce9f02cd08 Accepting request 242385 from home:draht:branches:mozilla:Factory
- mod_nss-bnc863518-reopen_dev_tty.diff: close(0) and 
  open("/dev/tty", ...) to make sure that stdin can be read from.
  startproc may inherit wrongly opened file descriptors to httpd.
  (Note: An analogous fix exists in startproc(8), too.)
  [bnc#863518]
- VirtualHost part in /etc/apache2/conf.d/mod_nss.conf is now
  externalized to /etc/apache2/conf.d/vhost-nss.template and not
  activated/read by default. [bnc#878681]
- NSSCipherSuite update following additional ciphers of Feb 18
  change. [bnc#878681]

- mod_nss-SNI-callback.patch, mod_nss-SNI-checks.patch:
  server side SNI was not implemented when mod_nss was made;
  patches implement SNI with checks if SNI provided hostname
  equals Host: field in http request header.

OBS-URL: https://build.opensuse.org/request/show/242385
OBS-URL: https://build.opensuse.org/package/show/mozilla:Factory/apache2-mod_nss?expand=0&rev=10
2014-07-25 14:00:54 +00:00

224 lines
7.2 KiB
Diff

diff -rNU 50 ../mod_nss-1.0.8-o/nss_engine_pphrase.c ./nss_engine_pphrase.c
--- ../mod_nss-1.0.8-o/nss_engine_pphrase.c 2014-07-24 12:23:30.000000000 +0200
+++ ./nss_engine_pphrase.c 2014-07-24 13:54:23.000000000 +0200
@@ -181,199 +181,218 @@
* that may be done.
*/
static PRBool nss_check_password(unsigned char *cp)
{
int len;
unsigned char *end, ch;
len = strlen((char *)cp);
if (len < 8) {
return PR_TRUE;
}
end = cp + len;
while (cp < end) {
ch = *cp++;
if (!((ch >= 'A') && (ch <= 'Z')) &&
!((ch >= 'a') && (ch <= 'z'))) {
/* pass phrase has at least one non alphabetic in it */
return PR_TRUE;
}
}
return PR_TRUE;
}
/*
* Password callback so the user is not prompted to enter the password
* after the server starts.
*/
static char * nss_no_password(PK11SlotInfo *slot, PRBool retry, void *arg)
{
return NULL;
}
/*
* Password callback to prompt the user for a password. This requires
* twiddling with the tty. Alternatively, if the file password.conf
* exists then it may be used to store the token password(s).
*/
static char *nss_get_password(FILE *input, FILE *output,
PK11SlotInfo *slot,
PRBool (*ok)(unsigned char *),
pphrase_arg_t *parg)
{
char *pwdstr = NULL;
char *token_name = NULL;
int tmp;
FILE *pwd_fileptr;
char *ptr;
char line[1024];
unsigned char phrase[200];
int infd = fileno(input);
+ int tmpfd;
int isTTY = isatty(infd);
token_name = PK11_GetTokenName(slot);
if (parg->mc->pphrase_dialog_type == SSL_PPTYPE_FILE ||
parg->mc->pphrase_dialog_type == SSL_PPTYPE_DEFER) {
/* Try to get the passwords from the password file if it exists.
* THIS IS UNSAFE and is provided for convenience only. Without this
* capability the server would have to be started in foreground mode.
*/
if ((*parg->mc->pphrase_dialog_path != '\0') &&
((pwd_fileptr = fopen(parg->mc->pphrase_dialog_path, "r")) != NULL)) {
while(fgets(line, 1024, pwd_fileptr)) {
if (PL_strstr(line, token_name) == line) {
tmp = PL_strlen(line) - 1;
while((line[tmp] == ' ') || (line[tmp] == '\n'))
tmp--;
line[tmp+1] = '\0';
ptr = PL_strchr(line, ':');
if (ptr == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"Malformed password entry for token %s. Format should be token:password", token_name);
continue;
}
for(tmp=1; ptr[tmp] == ' '; tmp++) {}
pwdstr = strdup(&(ptr[tmp]));
}
}
fclose(pwd_fileptr);
} else {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"Unable to open password file %s", parg->mc->pphrase_dialog_path);
nss_die();
}
}
/* For SSL_PPTYPE_DEFER we only want to authenticate passwords found
* in the password file.
*/
if ((parg->mc->pphrase_dialog_type == SSL_PPTYPE_DEFER) &&
(pwdstr == NULL)) {
return NULL;
}
/* This purposely comes after the file check because that is more
* authoritative.
*/
if (parg->mc->nInitCount > 1) {
char buf[1024];
apr_status_t rv;
apr_size_t nBytes = 1024;
struct sembuf sb;
/* lock the pipe */
sb.sem_num = 0;
sb.sem_op = -1;
sb.sem_flg = SEM_UNDO;
if (semop(parg->mc->semid, &sb, 1) == -1) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"Unable to reserve semaphore resource");
}
snprintf(buf, 1024, "RETR\t%s", token_name);
rv = apr_file_write_full(parg->mc->proc.in, buf, strlen(buf), NULL);
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"Unable to write to pin store for slot: %s APR err: %d", PK11_GetTokenName(slot), rv);
nss_die();
}
/* The helper just returns a token pw or "", so we don't have much
* to check for.
*/
memset(buf, 0, sizeof(buf));
rv = apr_file_read(parg->mc->proc.out, buf, &nBytes);
sb.sem_op = 1;
if (semop(parg->mc->semid, &sb, 1) == -1) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"Unable to free semaphore resource");
/* perror("semop free resource id"); */
}
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"Unable to read from pin store for slot: %s APR err: %d", PK11_GetTokenName(slot), rv);
nss_die();
}
/* Just return what we got. If we got this far and we don't have a
* PIN then I/O is already shut down, so we can't do anything really
* clever.
*/
pwdstr = strdup(buf);
}
/* If we got a password we're done */
if (pwdstr)
return pwdstr;
-
+
+ /* It happens that stdin is not opened with O_RDONLY. Better make sure
+ * it is and re-open /dev/tty.
+ */
+ close(infd); /* is 0 normally. open(2) will return first available. */
+ tmpfd = open("/dev/tty", O_RDONLY);
+ if( tmpfd == -1) {
+ fprintf(output, "Cannot open /dev/tty for reading the passphrase.\n");
+ nss_die();
+ }
+ if(tmpfd != infd) {
+ if( dup2(tmpfd, infd) != infd) {
+ fprintf(output, "Problem duplicating /dev/tty file descriptor.\n");
+ close(tmpfd);
+ nss_die();
+ }
+ close(tmpfd);
+ }
+
for (;;) {
/* Prompt for password */
if (isTTY) {
if (parg->retryCount > 0) {
fprintf(output, "Password incorrect. Please try again.\n");
}
fprintf(output, "%s", prompt);
echoOff(infd);
}
fgets((char*) phrase, sizeof(phrase), input);
if (isTTY) {
fprintf(output, "\n");
echoOn(infd);
}
/* stomp on newline */
phrase[strlen((char*)phrase)-1] = 0;
/* Validate password */
if (!(*ok)(phrase)) {
/* Not weird enough */
if (!isTTY) return 0;
fprintf(output, "Password must be at least 8 characters long with one or more\n");
fprintf(output, "non-alphabetic characters\n");
continue;
}
if (PK11_IsFIPS() && strlen(phrase) == 0) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"The FIPS security policy requires that a password be set.");
nss_die();
} else
return (char*) PORT_Strdup((char*)phrase);
}
}
/*
* Turn the echoing off on a tty.
*/
static void echoOff(int fd)
{
if (isatty(fd)) {
struct termios tio;
tcgetattr(fd, &tio);
tio.c_lflag &= ~ECHO;
tcsetattr(fd, TCSAFLUSH, &tio);
}
}
/*
* Turn the echoing on on a tty.
*/