about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--WWW/Library/Implementation/HTAABrow.c110
-rw-r--r--WWW/Library/Implementation/HTAABrow.h7
-rw-r--r--WWW/Library/Implementation/HTFTP.c4
-rw-r--r--WWW/Library/Implementation/HTNews.c4
-rw-r--r--WWW/Library/Implementation/HTTP.c6
-rw-r--r--src/HTAlert.c20
-rw-r--r--src/HTAlert.h4
8 files changed, 122 insertions, 38 deletions
diff --git a/CHANGES b/CHANGES
index dd6fba2c..2981e04d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,9 +1,12 @@
--- $LynxId: CHANGES,v 1.868 2016/11/24 20:42:26 tom Exp $
+-- $LynxId: CHANGES,v 1.869 2016/11/24 23:47:53 tom Exp $
 ===============================================================================
 Changes since Lynx 2.8 release
 ===============================================================================
 
 2016-11-24 (2.8.9dev.12)
+* accept userinfo in a URL, subject to override by -auth option or -pauth
+  options.  According to RFC-3986, this is deprecated, but testing shows other
+  clients support it -TD
 * fix several minor warnings reported by Coverity -TD
 * remove redundant asserts which follow a check that leads to outofmem(),
   added in 2.8.8dev.4 to appease clang 2.6, since clang 3.x understands
diff --git a/WWW/Library/Implementation/HTAABrow.c b/WWW/Library/Implementation/HTAABrow.c
index 31a0a469..4bc1add2 100644
--- a/WWW/Library/Implementation/HTAABrow.c
+++ b/WWW/Library/Implementation/HTAABrow.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTAABrow.c,v 1.41 2016/11/24 15:14:00 tom Exp $
+ * $LynxId: HTAABrow.c,v 1.42 2016/11/24 23:57:57 tom Exp $
  *
  * MODULE							HTAABrow.c
  *		BROWSER SIDE ACCESS AUTHORIZATION MODULE
@@ -532,6 +532,72 @@ static HTAARealm *HTAARealm_new(HTList *realm_table,
     return realm;
 }
 
+BOOL HTAA_HaveUserinfo(const char *hostname)
+{
+    int gen_delims = 0;
+    char *my_info = NULL;
+    char *at_sign = HTSkipToAt(StrAllocCopy(my_info, hostname), &gen_delims);
+
+    free(my_info);
+    return (at_sign != NULL && gen_delims == 0) ? TRUE : FALSE;
+}
+
+/*
+ * If there is userinfo in the hostname string, update the realm to use that
+ * information.  The command-line "-auth" option will override this.
+ */
+static void fill_in_userinfo(HTAARealm *realm, const char *hostname)
+{
+    int gen_delims = 0;
+    char *my_info = NULL;
+    char *at_sign = HTSkipToAt(StrAllocCopy(my_info, hostname), &gen_delims);
+
+    if (at_sign != NULL && gen_delims == 0) {
+	char *colon;
+
+	*at_sign = '\0';
+	if ((colon = StrChr(my_info, ':')) != 0) {
+	    *colon++ = '\0';
+	}
+	if (non_empty(my_info)) {
+	    char *msg;
+	    BOOL prior = non_empty(realm->username);
+
+	    if (prior && strcmp(realm->username, my_info)) {
+		msg = 0;
+		HTSprintf0(&msg,
+			   gettext("username for realm %s changed from %s to %s"),
+			   realm->realmname,
+			   realm->username,
+			   my_info);
+		HTAlert(msg);
+		free(msg);
+		FREE(realm->username);
+		StrAllocCopy(realm->username, my_info);
+	    } else if (!prior) {
+		StrAllocCopy(realm->username, my_info);
+	    }
+	    if (non_empty(colon)) {
+		prior = non_empty(realm->password);
+		if (prior && strcmp(realm->password, colon)) {
+		    msg = 0;
+		    HTSprintf0(&msg,
+			       gettext("password for realm %s user %s changed"),
+			       realm->realmname,
+			       realm->username);
+		    HTAlert(msg);
+		    free(msg);
+		    FREE(realm->password);
+		    StrAllocCopy(realm->password, colon);
+		} else if (!prior) {
+		    StrAllocCopy(realm->password, colon);
+		}
+	    }
+	}
+    }
+    free(my_info);
+}
+
 /***************** Basic and Pubkey Authentication ************************/
 
 /* static						compose_auth_string()
@@ -540,6 +606,7 @@ static HTAARealm *HTAARealm_new(HTList *realm_table,
  *		PROMPTS FOR USERNAME AND PASSWORD IF NEEDED
  *
  * ON ENTRY:
+ *	hostname	may include user- and password information
  *	scheme		is either HTAA_BASIC or HTAA_PUBKEY.
  *	setup		is the current server setup.
  *	IsProxy		should be TRUE if this is a proxy.
@@ -555,7 +622,10 @@ static HTAARealm *HTAARealm_new(HTList *realm_table,
  *	returned by AA package needs to (or should) be freed.
  *
  */
-static char *compose_auth_string(HTAAScheme scheme, HTAASetup * setup, int IsProxy)
+static char *compose_auth_string(const char *hostname,
+				 HTAAScheme scheme,
+				 HTAASetup * setup,
+				 int IsProxy)
 {
     char *cleartext = NULL;	/* Cleartext presentation */
     char *ciphertext = NULL;	/* Encrypted presentation */
@@ -573,9 +643,12 @@ static char *compose_auth_string(HTAAScheme scheme, HTAASetup * setup, int IsPro
 
     FREE(compose_auth_stringResult);	/* From previous call */
 
-    if ((scheme != HTAA_BASIC && scheme != HTAA_PUBKEY) || !setup ||
-	!setup->scheme_specifics || !setup->scheme_specifics[scheme] ||
-	!setup->server || !setup->server->realms)
+    if ((scheme != HTAA_BASIC && scheme != HTAA_PUBKEY) ||
+	!(setup &&
+	  setup->scheme_specifics &&
+	  setup->scheme_specifics[scheme] &&
+	  setup->server &&
+	  setup->server->realms))
 	return NULL;
 
     realmname = HTAssocList_lookup(setup->scheme_specifics[scheme], "realm");
@@ -583,9 +656,11 @@ static char *compose_auth_string(HTAAScheme scheme, HTAASetup * setup, int IsPro
 	return NULL;
 
     realm = HTAARealm_lookup(setup->server->realms, realmname);
+    setup->retry |= HTAA_HaveUserinfo(hostname);
+
     if (!(realm &&
-	  realm->username && *realm->username &&
-	  realm->password) || setup->retry) {
+	  non_empty(realm->username) &&
+	  non_empty(realm->password)) || setup->retry) {
 	if (!realm) {
 	    CTRACE((tfp, "%s `%s' %s\n",
 		    "compose_auth_string: realm:", realmname,
@@ -593,6 +668,7 @@ static char *compose_auth_string(HTAAScheme scheme, HTAASetup * setup, int IsPro
 	    realm = HTAARealm_new(setup->server->realms,
 				  realmname, NULL, NULL);
 	}
+	fill_in_userinfo(realm, hostname);
 	/*
 	 * The template should be either the '*' global for everything on the
 	 * server (always true for proxy authorization setups), or a path for
@@ -617,12 +693,7 @@ static char *compose_auth_string(HTAAScheme scheme, HTAASetup * setup, int IsPro
 	    setup->server->portnumber != 80) {
 	    HTSprintf0(&thePort, ":%d", setup->server->portnumber);
 	}
-	/*
-	 * Set up the message for the username prompt, and then issue the
-	 * prompt.  The default username is included in the call to the
-	 * prompting function, but the password is NULL-ed and always replaced. 
-	 * - FM
-	 */
+
 	HTSprintf0(&msg, gettext("Username for '%s' at %s '%s%s':"),
 		   realm->realmname,
 		   (IsProxy ? "proxy" : "server"),
@@ -630,13 +701,18 @@ static char *compose_auth_string(HTAAScheme scheme, HTAASetup * setup, int IsPro
 		   NonNull(thePort));
 	FREE(proxiedHost);
 	FREE(thePort);
-	StrAllocCopy(username, realm->username);
-	password = NULL;
+	if (non_empty(realm->username)) {
+	    StrAllocCopy(username, realm->username);
+	}
+	if (non_empty(realm->password)) {
+	    StrAllocCopy(password, realm->password);
+	}
 	HTPromptUsernameAndPassword(msg, &username, &password, IsProxy);
 
 	FREE(msg);
 	FREE(realm->username);
 	FREE(realm->password);
+
 	realm->username = username;
 	realm->password = password;
 
@@ -882,7 +958,7 @@ char *HTAA_composeAuth(const char *hostname,
 	switch (scheme = HTAA_selectScheme(proxy_setup)) {
 	case HTAA_BASIC:
 	case HTAA_PUBKEY:
-	    auth_string = compose_auth_string(scheme, proxy_setup, IsProxy);
+	    auth_string = compose_auth_string(hostname, scheme, proxy_setup, IsProxy);
 	    break;
 	case HTAA_KERBEROS_V4:
 	    /* OTHER AUTHENTICATION ROUTINES ARE CALLED HERE */
@@ -959,7 +1035,7 @@ char *HTAA_composeAuth(const char *hostname,
 	switch (scheme = HTAA_selectScheme(current_setup)) {
 	case HTAA_BASIC:
 	case HTAA_PUBKEY:
-	    auth_string = compose_auth_string(scheme, current_setup, IsProxy);
+	    auth_string = compose_auth_string(hostname, scheme, current_setup, IsProxy);
 	    break;
 	case HTAA_KERBEROS_V4:
 	    /* OTHER AUTHENTICATION ROUTINES ARE CALLED HERE */
diff --git a/WWW/Library/Implementation/HTAABrow.h b/WWW/Library/Implementation/HTAABrow.h
index 064f11e3..f151deb5 100644
--- a/WWW/Library/Implementation/HTAABrow.h
+++ b/WWW/Library/Implementation/HTAABrow.h
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTAABrow.h,v 1.16 2010/10/27 00:13:53 tom Exp $
+ * $LynxId: HTAABrow.h,v 1.17 2016/11/24 23:32:22 tom Exp $
  *
  *                          BROWSER SIDE ACCESS AUTHORIZATION MODULE
 
@@ -117,6 +117,11 @@ extern "C" {
     extern void HTClearHTTPAuthInfo(void);
 
 /*
+ * Check if a hostname-string contains user information.
+ */
+    extern BOOL HTAA_HaveUserinfo(const char *hostname);
+
+/*
 
 Enabling Gateway httpds to Forward Authorization
 
diff --git a/WWW/Library/Implementation/HTFTP.c b/WWW/Library/Implementation/HTFTP.c
index d2c8bdf2..03781a63 100644
--- a/WWW/Library/Implementation/HTFTP.c
+++ b/WWW/Library/Implementation/HTFTP.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTFTP.c,v 1.127 2016/11/24 16:22:50 tom Exp $
+ * $LynxId: HTFTP.c,v 1.128 2016/11/24 23:43:55 tom Exp $
  *
  *			File Transfer Protocol (FTP) Client
  *			for a WorldWideWeb browser
@@ -870,7 +870,7 @@ static int get_connection(const char *arg,
 		    HTSprintf0(&tmp, gettext("Enter password for user %s@%s:"),
 			       username, p1);
 		    FREE(user_entered_password);
-		    user_entered_password = HTPromptPassword(tmp);
+		    user_entered_password = HTPromptPassword(tmp, NULL);
 
 		}		/* else we already know the password */
 		password = user_entered_password;
diff --git a/WWW/Library/Implementation/HTNews.c b/WWW/Library/Implementation/HTNews.c
index 669f3a99..6e38b51e 100644
--- a/WWW/Library/Implementation/HTNews.c
+++ b/WWW/Library/Implementation/HTNews.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTNews.c,v 1.70 2013/11/28 11:13:46 tom Exp $
+ * $LynxId: HTNews.c,v 1.71 2016/11/24 23:43:38 tom Exp $
  *
  *			NEWS ACCESS				HTNews.c
  *			===========
@@ -501,7 +501,7 @@ static NNTPAuthResult HTHandleAuthInfo(char *host)
 	while (tries) {
 	    if (PassWord == NULL) {
 		HTSprintf0(&msg, gettext("Password for news host '%s':"), host);
-		PassWord = HTPromptPassword(msg);
+		PassWord = HTPromptPassword(msg, NULL);
 		FREE(msg);
 		if (!(PassWord && *PassWord)) {
 		    FREE(PassWord);
diff --git a/WWW/Library/Implementation/HTTP.c b/WWW/Library/Implementation/HTTP.c
index 2db68e25..581cb5e6 100644
--- a/WWW/Library/Implementation/HTTP.c
+++ b/WWW/Library/Implementation/HTTP.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTTP.c,v 1.162 2016/11/24 18:25:32 tom Exp $
+ * $LynxId: HTTP.c,v 1.163 2016/11/24 23:56:50 tom Exp $
  *
  * HyperText Tranfer Protocol	- Client implementation		HTTP.c
  * ==========================
@@ -2308,7 +2308,9 @@ static int HTLoadHTTP(const char *arg,
 						 length, s, NO)) {
 
 			HTTP_NETCLOSE(s, handle);
-			if (dump_output_immediately && !authentication_info[0]) {
+			if (dump_output_immediately &&
+			    !HTAA_HaveUserinfo(HTParse(arg, "", PARSE_HOST)) &&
+			    !authentication_info[0]) {
 			    fprintf(stderr,
 				    "HTTP: Access authorization required.\n");
 			    fprintf(stderr,
diff --git a/src/HTAlert.c b/src/HTAlert.c
index 34ddfa9f..aa185688 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTAlert.c,v 1.101 2013/11/28 11:17:04 tom Exp $
+ * $LynxId: HTAlert.c,v 1.102 2016/11/24 23:56:05 tom Exp $
  *
  *	Displaying messages and getting input for Lynx Browser
  *	==========================================================
@@ -668,20 +668,22 @@ char *HTPrompt(const char *Msg, const char *deflt)
  *	Prompt for password without echoing the reply.	HTPromptPassword()
  *	----------------------------------------------
  */
-char *HTPromptPassword(const char *Msg)
+char *HTPromptPassword(const char *Msg, const char *given)
 {
     char *result = NULL;
     bstring *data = NULL;
 
+    if (isEmpty(given))
+	given = "";
     if (!dump_output_immediately) {
 	_statusline(Msg ? Msg : PASSWORD_PROMPT);
-	BStrCopy0(data, "");
+	BStrCopy0(data, given);
 	(void) LYgetBString(&data, TRUE, 0, NORECALL);
 	StrAllocCopy(result, data->str);
 	BStrFree(data);
     } else {
 	printf("\n%s\n", PASSWORD_REQUIRED);
-	StrAllocCopy(result, "");
+	StrAllocCopy(result, given);
     }
     return result;
 }
@@ -755,7 +757,7 @@ void HTPromptUsernameAndPassword(const char *Msg,
 	    } else {
 		FREE(authentication_info[0]);
 	    }
-	} else {
+	} else if (isEmpty(*username)) {
 	    /*
 	     * Default to "WWWuser".  - FM
 	     */
@@ -773,7 +775,7 @@ void HTPromptUsernameAndPassword(const char *Msg,
 	    } else {
 		FREE(authentication_info[1]);
 	    }
-	} else {
+	} else if (isEmpty(*password)) {
 	    /*
 	     * Default to a zero-length string.  - FM
 	     */
@@ -822,11 +824,7 @@ void HTPromptUsernameAndPassword(const char *Msg,
 		FREE(authentication_info[1]);
 	    }
 	} else if (non_empty(*username)) {
-	    /*
-	     * We have a non-zero length username,
-	     * so prompt for the password.  - FM
-	     */
-	    *password = HTPromptPassword(PASSWORD_PROMPT);
+	    *password = HTPromptPassword(PASSWORD_PROMPT, *password);
 	} else {
 	    /*
 	     * Return a zero-length password.  - FM
diff --git a/src/HTAlert.h b/src/HTAlert.h
index 9c96755a..03106f54 100644
--- a/src/HTAlert.h
+++ b/src/HTAlert.h
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTAlert.h,v 1.34 2010/09/26 16:36:38 tom Exp $
+ * $LynxId: HTAlert.h,v 1.35 2016/11/24 23:44:49 tom Exp $
  *
  *      Displaying messages and getting input for WWW Library
  *      =====================================================
@@ -90,7 +90,7 @@ extern "C" {
 
 /*      Prompt for password without echoing the reply
  */
-    extern char *HTPromptPassword(const char *Msg);
+    extern char *HTPromptPassword(const char *Msg, const char *given);
 
 /*      Prompt both username and password       HTPromptUsernameAndPassword()
  *      ---------------------------------