Remove tabs introduced from VNC ACL series
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6727 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									76655d6dec
								
							
						
					
					
						commit
						28a76be8f4
					
				
							
								
								
									
										64
									
								
								acl.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								acl.c
									
									
									
									
									
								
							| @ -41,8 +41,8 @@ qemu_acl *qemu_acl_find(const char *aclname) | ||||
| { | ||||
|     int i; | ||||
|     for (i = 0 ; i < nacls ; i++) { | ||||
| 	if (strcmp(acls[i]->aclname, aclname) == 0) | ||||
| 	    return acls[i]; | ||||
|         if (strcmp(acls[i]->aclname, aclname) == 0) | ||||
|             return acls[i]; | ||||
|     } | ||||
| 
 | ||||
|     return NULL; | ||||
| @ -54,7 +54,7 @@ qemu_acl *qemu_acl_init(const char *aclname) | ||||
| 
 | ||||
|     acl = qemu_acl_find(aclname); | ||||
|     if (acl) | ||||
| 	return acl; | ||||
|         return acl; | ||||
| 
 | ||||
|     acl = qemu_malloc(sizeof(*acl)); | ||||
|     acl->aclname = qemu_strdup(aclname); | ||||
| @ -74,19 +74,19 @@ qemu_acl *qemu_acl_init(const char *aclname) | ||||
| } | ||||
| 
 | ||||
| int qemu_acl_party_is_allowed(qemu_acl *acl, | ||||
| 			      const char *party) | ||||
|                               const char *party) | ||||
| { | ||||
|     qemu_acl_entry *entry; | ||||
| 
 | ||||
|     TAILQ_FOREACH(entry, &acl->entries, next) { | ||||
| #ifdef HAVE_FNMATCH_H | ||||
| 	if (fnmatch(entry->match, party, 0) == 0) | ||||
| 	    return entry->deny ? 0 : 1; | ||||
|         if (fnmatch(entry->match, party, 0) == 0) | ||||
|             return entry->deny ? 0 : 1; | ||||
| #else | ||||
| 	/* No fnmatch, so fallback to exact string matching
 | ||||
| 	 * instead of allowing wildcards */ | ||||
| 	if (strcmp(entry->match, party) == 0) | ||||
| 	    return entry->deny ? 0 : 1; | ||||
|         /* No fnmatch, so fallback to exact string matching
 | ||||
|          * instead of allowing wildcards */ | ||||
|         if (strcmp(entry->match, party) == 0) | ||||
|             return entry->deny ? 0 : 1; | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
| @ -103,17 +103,17 @@ void qemu_acl_reset(qemu_acl *acl) | ||||
|      * access control list */ | ||||
|     acl->defaultDeny = 1; | ||||
|     TAILQ_FOREACH(entry, &acl->entries, next) { | ||||
| 	TAILQ_REMOVE(&acl->entries, entry, next); | ||||
| 	free(entry->match); | ||||
| 	free(entry); | ||||
|         TAILQ_REMOVE(&acl->entries, entry, next); | ||||
|         free(entry->match); | ||||
|         free(entry); | ||||
|     } | ||||
|     acl->nentries = 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int qemu_acl_append(qemu_acl *acl, | ||||
| 		    int deny, | ||||
| 		    const char *match) | ||||
|                     int deny, | ||||
|                     const char *match) | ||||
| { | ||||
|     qemu_acl_entry *entry; | ||||
| 
 | ||||
| @ -129,18 +129,18 @@ int qemu_acl_append(qemu_acl *acl, | ||||
| 
 | ||||
| 
 | ||||
| int qemu_acl_insert(qemu_acl *acl, | ||||
| 		    int deny, | ||||
| 		    const char *match, | ||||
| 		    int index) | ||||
|                     int deny, | ||||
|                     const char *match, | ||||
|                     int index) | ||||
| { | ||||
|     qemu_acl_entry *entry; | ||||
|     qemu_acl_entry *tmp; | ||||
|     int i = 0; | ||||
| 
 | ||||
|     if (index <= 0) | ||||
| 	return -1; | ||||
|         return -1; | ||||
|     if (index >= acl->nentries) | ||||
| 	return qemu_acl_append(acl, deny, match); | ||||
|         return qemu_acl_append(acl, deny, match); | ||||
| 
 | ||||
| 
 | ||||
|     entry = qemu_malloc(sizeof(*entry)); | ||||
| @ -148,29 +148,29 @@ int qemu_acl_insert(qemu_acl *acl, | ||||
|     entry->deny = deny; | ||||
| 
 | ||||
|     TAILQ_FOREACH(tmp, &acl->entries, next) { | ||||
| 	i++; | ||||
| 	if (i == index) { | ||||
| 	    TAILQ_INSERT_BEFORE(tmp, entry, next); | ||||
| 	    acl->nentries++; | ||||
| 	    break; | ||||
| 	} | ||||
|         i++; | ||||
|         if (i == index) { | ||||
|             TAILQ_INSERT_BEFORE(tmp, entry, next); | ||||
|             acl->nentries++; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return i; | ||||
| } | ||||
| 
 | ||||
| int qemu_acl_remove(qemu_acl *acl, | ||||
| 		    const char *match) | ||||
|                     const char *match) | ||||
| { | ||||
|     qemu_acl_entry *entry; | ||||
|     int i = 0; | ||||
| 
 | ||||
|     TAILQ_FOREACH(entry, &acl->entries, next) { | ||||
| 	i++; | ||||
| 	if (strcmp(entry->match, match) == 0) { | ||||
| 	    TAILQ_REMOVE(&acl->entries, entry, next); | ||||
| 	    return i; | ||||
| 	} | ||||
|         i++; | ||||
|         if (strcmp(entry->match, match) == 0) { | ||||
|             TAILQ_REMOVE(&acl->entries, entry, next); | ||||
|             return i; | ||||
|         } | ||||
|     } | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
							
								
								
									
										162
									
								
								monitor.c
									
									
									
									
									
								
							
							
						
						
									
										162
									
								
								monitor.c
									
									
									
									
									
								
							| @ -160,25 +160,25 @@ void monitor_print_filename(Monitor *mon, const char *filename) | ||||
|     int i; | ||||
| 
 | ||||
|     for (i = 0; filename[i]; i++) { | ||||
| 	switch (filename[i]) { | ||||
| 	case ' ': | ||||
| 	case '"': | ||||
| 	case '\\': | ||||
| 	    monitor_printf(mon, "\\%c", filename[i]); | ||||
| 	    break; | ||||
| 	case '\t': | ||||
| 	    monitor_printf(mon, "\\t"); | ||||
| 	    break; | ||||
| 	case '\r': | ||||
| 	    monitor_printf(mon, "\\r"); | ||||
| 	    break; | ||||
| 	case '\n': | ||||
| 	    monitor_printf(mon, "\\n"); | ||||
| 	    break; | ||||
| 	default: | ||||
| 	    monitor_printf(mon, "%c", filename[i]); | ||||
| 	    break; | ||||
| 	} | ||||
|         switch (filename[i]) { | ||||
|         case ' ': | ||||
|         case '"': | ||||
|         case '\\': | ||||
|             monitor_printf(mon, "\\%c", filename[i]); | ||||
|             break; | ||||
|         case '\t': | ||||
|             monitor_printf(mon, "\\t"); | ||||
|             break; | ||||
|         case '\r': | ||||
|             monitor_printf(mon, "\\r"); | ||||
|             break; | ||||
|         case '\n': | ||||
|             monitor_printf(mon, "\\n"); | ||||
|             break; | ||||
|         default: | ||||
|             monitor_printf(mon, "%c", filename[i]); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -474,17 +474,17 @@ static void change_vnc_password_cb(Monitor *mon, const char *password, | ||||
| static void do_change_vnc(Monitor *mon, const char *target, const char *arg) | ||||
| { | ||||
|     if (strcmp(target, "passwd") == 0 || | ||||
| 	strcmp(target, "password") == 0) { | ||||
| 	if (arg) { | ||||
|         strcmp(target, "password") == 0) { | ||||
|         if (arg) { | ||||
|             char password[9]; | ||||
| 	    strncpy(password, arg, sizeof(password)); | ||||
| 	    password[sizeof(password) - 1] = '\0'; | ||||
|             strncpy(password, arg, sizeof(password)); | ||||
|             password[sizeof(password) - 1] = '\0'; | ||||
|             change_vnc_password_cb(mon, password, NULL); | ||||
|         } else { | ||||
|             monitor_read_password(mon, change_vnc_password_cb, NULL); | ||||
|         } | ||||
|     } else { | ||||
| 	if (vnc_display_open(NULL, target) < 0) | ||||
|         if (vnc_display_open(NULL, target) < 0) | ||||
|             monitor_printf(mon, "could not start VNC server on %s\n", target); | ||||
|     } | ||||
| } | ||||
| @ -493,9 +493,9 @@ static void do_change(Monitor *mon, const char *device, const char *target, | ||||
|                       const char *arg) | ||||
| { | ||||
|     if (strcmp(device, "vnc") == 0) { | ||||
| 	do_change_vnc(mon, target, arg); | ||||
|         do_change_vnc(mon, target, arg); | ||||
|     } else { | ||||
| 	do_change_block(mon, device, target, arg); | ||||
|         do_change_block(mon, device, target, arg); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -1535,81 +1535,81 @@ static void do_info_balloon(Monitor *mon) | ||||
| 
 | ||||
| static void do_acl(Monitor *mon, | ||||
|                    const char *command, | ||||
| 		   const char *aclname, | ||||
| 		   const char *match, | ||||
| 		   int has_index, | ||||
| 		   int index) | ||||
|                    const char *aclname, | ||||
|                    const char *match, | ||||
|                    int has_index, | ||||
|                    int index) | ||||
| { | ||||
|     qemu_acl *acl; | ||||
| 
 | ||||
|     acl = qemu_acl_find(aclname); | ||||
|     if (!acl) { | ||||
| 	monitor_printf(mon, "acl: unknown list '%s'\n", aclname); | ||||
| 	return; | ||||
|         monitor_printf(mon, "acl: unknown list '%s'\n", aclname); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (strcmp(command, "show") == 0) { | ||||
| 	int i = 0; | ||||
| 	qemu_acl_entry *entry; | ||||
| 	monitor_printf(mon, "policy: %s\n", | ||||
|         int i = 0; | ||||
|         qemu_acl_entry *entry; | ||||
|         monitor_printf(mon, "policy: %s\n", | ||||
|                        acl->defaultDeny ? "deny" : "allow"); | ||||
| 	TAILQ_FOREACH(entry, &acl->entries, next) { | ||||
| 	    i++; | ||||
| 	    monitor_printf(mon, "%d: %s %s\n", i, | ||||
|         TAILQ_FOREACH(entry, &acl->entries, next) { | ||||
|             i++; | ||||
|             monitor_printf(mon, "%d: %s %s\n", i, | ||||
|                            entry->deny ? "deny" : "allow", | ||||
|                            entry->match); | ||||
| 	} | ||||
|         } | ||||
|     } else if (strcmp(command, "reset") == 0) { | ||||
| 	qemu_acl_reset(acl); | ||||
| 	monitor_printf(mon, "acl: removed all rules\n"); | ||||
|         qemu_acl_reset(acl); | ||||
|         monitor_printf(mon, "acl: removed all rules\n"); | ||||
|     } else if (strcmp(command, "policy") == 0) { | ||||
| 	if (!match) { | ||||
| 	    monitor_printf(mon, "acl: missing policy parameter\n"); | ||||
| 	    return; | ||||
| 	} | ||||
|         if (!match) { | ||||
|             monitor_printf(mon, "acl: missing policy parameter\n"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
| 	if (strcmp(match, "allow") == 0) { | ||||
| 	    acl->defaultDeny = 0; | ||||
| 	    monitor_printf(mon, "acl: policy set to 'allow'\n"); | ||||
| 	} else if (strcmp(match, "deny") == 0) { | ||||
| 	    acl->defaultDeny = 1; | ||||
| 	    monitor_printf(mon, "acl: policy set to 'deny'\n"); | ||||
| 	} else { | ||||
| 	    monitor_printf(mon, "acl: unknown policy '%s', expected 'deny' or 'allow'\n", match); | ||||
| 	} | ||||
|         if (strcmp(match, "allow") == 0) { | ||||
|             acl->defaultDeny = 0; | ||||
|             monitor_printf(mon, "acl: policy set to 'allow'\n"); | ||||
|         } else if (strcmp(match, "deny") == 0) { | ||||
|             acl->defaultDeny = 1; | ||||
|             monitor_printf(mon, "acl: policy set to 'deny'\n"); | ||||
|         } else { | ||||
|             monitor_printf(mon, "acl: unknown policy '%s', expected 'deny' or 'allow'\n", match); | ||||
|         } | ||||
|     } else if ((strcmp(command, "allow") == 0) || | ||||
| 	       (strcmp(command, "deny") == 0)) { | ||||
| 	int deny = strcmp(command, "deny") == 0 ? 1 : 0; | ||||
| 	int ret; | ||||
|                (strcmp(command, "deny") == 0)) { | ||||
|         int deny = strcmp(command, "deny") == 0 ? 1 : 0; | ||||
|         int ret; | ||||
| 
 | ||||
| 	if (!match) { | ||||
| 	    monitor_printf(mon, "acl: missing match parameter\n"); | ||||
| 	    return; | ||||
| 	} | ||||
|         if (!match) { | ||||
|             monitor_printf(mon, "acl: missing match parameter\n"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
| 	if (has_index) | ||||
| 	    ret = qemu_acl_insert(acl, deny, match, index); | ||||
| 	else | ||||
| 	    ret = qemu_acl_append(acl, deny, match); | ||||
| 	if (ret < 0) | ||||
| 	    monitor_printf(mon, "acl: unable to add acl entry\n"); | ||||
| 	else | ||||
| 	    monitor_printf(mon, "acl: added rule at position %d\n", ret); | ||||
|         if (has_index) | ||||
|             ret = qemu_acl_insert(acl, deny, match, index); | ||||
|         else | ||||
|             ret = qemu_acl_append(acl, deny, match); | ||||
|         if (ret < 0) | ||||
|             monitor_printf(mon, "acl: unable to add acl entry\n"); | ||||
|         else | ||||
|             monitor_printf(mon, "acl: added rule at position %d\n", ret); | ||||
|     } else if (strcmp(command, "remove") == 0) { | ||||
| 	int ret; | ||||
|         int ret; | ||||
| 
 | ||||
| 	if (!match) { | ||||
| 	    monitor_printf(mon, "acl: missing match parameter\n"); | ||||
| 	    return; | ||||
| 	} | ||||
|         if (!match) { | ||||
|             monitor_printf(mon, "acl: missing match parameter\n"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
| 	ret = qemu_acl_remove(acl, match); | ||||
| 	if (ret < 0) | ||||
| 	    monitor_printf(mon, "acl: no matching acl entry\n"); | ||||
| 	else | ||||
| 	    monitor_printf(mon, "acl: removed rule at position %d\n", ret); | ||||
|         ret = qemu_acl_remove(acl, match); | ||||
|         if (ret < 0) | ||||
|             monitor_printf(mon, "acl: no matching acl entry\n"); | ||||
|         else | ||||
|             monitor_printf(mon, "acl: removed rule at position %d\n", ret); | ||||
|     } else { | ||||
| 	monitor_printf(mon, "acl: unknown command '%s'\n", command); | ||||
|         monitor_printf(mon, "acl: unknown command '%s'\n", command); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -1839,7 +1839,7 @@ static target_long monitor_get_ccr (const struct MonitorDef *md, int val) | ||||
| 
 | ||||
|     u = 0; | ||||
|     for (i = 0; i < 8; i++) | ||||
| 	u |= env->crf[i] << (32 - (4 * i)); | ||||
|         u |= env->crf[i] << (32 - (4 * i)); | ||||
| 
 | ||||
|     return u; | ||||
| } | ||||
|  | ||||
							
								
								
									
										470
									
								
								vnc-auth-sasl.c
									
									
									
									
									
								
							
							
						
						
									
										470
									
								
								vnc-auth-sasl.c
									
									
									
									
									
								
							| @ -31,14 +31,14 @@ | ||||
| void vnc_sasl_client_cleanup(VncState *vs) | ||||
| { | ||||
|     if (vs->sasl.conn) { | ||||
| 	vs->sasl.runSSF = vs->sasl.waitWriteSSF = vs->sasl.wantSSF = 0; | ||||
| 	vs->sasl.encodedLength = vs->sasl.encodedOffset = 0; | ||||
| 	vs->sasl.encoded = NULL; | ||||
| 	free(vs->sasl.username); | ||||
| 	free(vs->sasl.mechlist); | ||||
| 	vs->sasl.username = vs->sasl.mechlist = NULL; | ||||
| 	sasl_dispose(&vs->sasl.conn); | ||||
| 	vs->sasl.conn = NULL; | ||||
|         vs->sasl.runSSF = vs->sasl.waitWriteSSF = vs->sasl.wantSSF = 0; | ||||
|         vs->sasl.encodedLength = vs->sasl.encodedOffset = 0; | ||||
|         vs->sasl.encoded = NULL; | ||||
|         free(vs->sasl.username); | ||||
|         free(vs->sasl.mechlist); | ||||
|         vs->sasl.username = vs->sasl.mechlist = NULL; | ||||
|         sasl_dispose(&vs->sasl.conn); | ||||
|         vs->sasl.conn = NULL; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -48,33 +48,33 @@ long vnc_client_write_sasl(VncState *vs) | ||||
|     long ret; | ||||
| 
 | ||||
|     VNC_DEBUG("Write SASL: Pending output %p size %d offset %d Encoded: %p size %d offset %d\n", | ||||
| 	      vs->output.buffer, vs->output.capacity, vs->output.offset, | ||||
| 	      vs->sasl.encoded, vs->sasl.encodedLength, vs->sasl.encodedOffset); | ||||
|               vs->output.buffer, vs->output.capacity, vs->output.offset, | ||||
|               vs->sasl.encoded, vs->sasl.encodedLength, vs->sasl.encodedOffset); | ||||
| 
 | ||||
|     if (!vs->sasl.encoded) { | ||||
| 	int err; | ||||
| 	err = sasl_encode(vs->sasl.conn, | ||||
| 			  (char *)vs->output.buffer, | ||||
| 			  vs->output.offset, | ||||
| 			  (const char **)&vs->sasl.encoded, | ||||
| 			  &vs->sasl.encodedLength); | ||||
| 	if (err != SASL_OK) | ||||
| 	    return vnc_client_io_error(vs, -1, EIO); | ||||
|         int err; | ||||
|         err = sasl_encode(vs->sasl.conn, | ||||
|                           (char *)vs->output.buffer, | ||||
|                           vs->output.offset, | ||||
|                           (const char **)&vs->sasl.encoded, | ||||
|                           &vs->sasl.encodedLength); | ||||
|         if (err != SASL_OK) | ||||
|             return vnc_client_io_error(vs, -1, EIO); | ||||
| 
 | ||||
| 	vs->sasl.encodedOffset = 0; | ||||
|         vs->sasl.encodedOffset = 0; | ||||
|     } | ||||
| 
 | ||||
|     ret = vnc_client_write_buf(vs, | ||||
| 			       vs->sasl.encoded + vs->sasl.encodedOffset, | ||||
| 			       vs->sasl.encodedLength - vs->sasl.encodedOffset); | ||||
|                                vs->sasl.encoded + vs->sasl.encodedOffset, | ||||
|                                vs->sasl.encodedLength - vs->sasl.encodedOffset); | ||||
|     if (!ret) | ||||
| 	return 0; | ||||
|         return 0; | ||||
| 
 | ||||
|     vs->sasl.encodedOffset += ret; | ||||
|     if (vs->sasl.encodedOffset == vs->sasl.encodedLength) { | ||||
| 	vs->output.offset = 0; | ||||
| 	vs->sasl.encoded = NULL; | ||||
| 	vs->sasl.encodedOffset = vs->sasl.encodedLength = 0; | ||||
|         vs->output.offset = 0; | ||||
|         vs->sasl.encoded = NULL; | ||||
|         vs->sasl.encodedOffset = vs->sasl.encodedLength = 0; | ||||
|     } | ||||
| 
 | ||||
|     /* Can't merge this block with one above, because
 | ||||
| @ -83,7 +83,7 @@ long vnc_client_write_sasl(VncState *vs) | ||||
|      * SASL encoded output | ||||
|      */ | ||||
|     if (vs->output.offset == 0) { | ||||
| 	qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); | ||||
|         qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| @ -100,16 +100,16 @@ long vnc_client_read_sasl(VncState *vs) | ||||
| 
 | ||||
|     ret = vnc_client_read_buf(vs, encoded, sizeof(encoded)); | ||||
|     if (!ret) | ||||
| 	return 0; | ||||
|         return 0; | ||||
| 
 | ||||
|     err = sasl_decode(vs->sasl.conn, | ||||
| 		      (char *)encoded, ret, | ||||
| 		      &decoded, &decodedLen); | ||||
|                       (char *)encoded, ret, | ||||
|                       &decoded, &decodedLen); | ||||
| 
 | ||||
|     if (err != SASL_OK) | ||||
| 	return vnc_client_io_error(vs, -1, -EIO); | ||||
|         return vnc_client_io_error(vs, -1, -EIO); | ||||
|     VNC_DEBUG("Read SASL Encoded %p size %ld Decoded %p size %d\n", | ||||
| 	      encoded, ret, decoded, decodedLen); | ||||
|               encoded, ret, decoded, decodedLen); | ||||
|     buffer_reserve(&vs->input, decodedLen); | ||||
|     buffer_append(&vs->input, decoded, decodedLen); | ||||
|     return decodedLen; | ||||
| @ -124,27 +124,27 @@ static int vnc_auth_sasl_check_access(VncState *vs) | ||||
| 
 | ||||
|     err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val); | ||||
|     if (err != SASL_OK) { | ||||
| 	VNC_DEBUG("cannot query SASL username on connection %d (%s), denying access\n", | ||||
| 		  err, sasl_errstring(err, NULL, NULL)); | ||||
| 	return -1; | ||||
|         VNC_DEBUG("cannot query SASL username on connection %d (%s), denying access\n", | ||||
|                   err, sasl_errstring(err, NULL, NULL)); | ||||
|         return -1; | ||||
|     } | ||||
|     if (val == NULL) { | ||||
| 	VNC_DEBUG("no client username was found, denying access\n"); | ||||
| 	return -1; | ||||
|         VNC_DEBUG("no client username was found, denying access\n"); | ||||
|         return -1; | ||||
|     } | ||||
|     VNC_DEBUG("SASL client username %s\n", (const char *)val); | ||||
| 
 | ||||
|     vs->sasl.username = qemu_strdup((const char*)val); | ||||
| 
 | ||||
|     if (vs->vd->sasl.acl == NULL) { | ||||
| 	VNC_DEBUG("no ACL activated, allowing access\n"); | ||||
| 	return 0; | ||||
|         VNC_DEBUG("no ACL activated, allowing access\n"); | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     allow = qemu_acl_party_is_allowed(vs->vd->sasl.acl, vs->sasl.username); | ||||
| 
 | ||||
|     VNC_DEBUG("SASL client %s %s by ACL\n", vs->sasl.username, | ||||
| 	      allow ? "allowed" : "denied"); | ||||
|               allow ? "allowed" : "denied"); | ||||
|     return allow ? 0 : -1; | ||||
| } | ||||
| 
 | ||||
| @ -154,16 +154,16 @@ static int vnc_auth_sasl_check_ssf(VncState *vs) | ||||
|     int err, ssf; | ||||
| 
 | ||||
|     if (!vs->sasl.wantSSF) | ||||
| 	return 1; | ||||
|         return 1; | ||||
| 
 | ||||
|     err = sasl_getprop(vs->sasl.conn, SASL_SSF, &val); | ||||
|     if (err != SASL_OK) | ||||
| 	return 0; | ||||
|         return 0; | ||||
| 
 | ||||
|     ssf = *(const int *)val; | ||||
|     VNC_DEBUG("negotiated an SSF of %d\n", ssf); | ||||
|     if (ssf < 56) | ||||
| 	return 0; /* 56 is good for Kerberos */ | ||||
|         return 0; /* 56 is good for Kerberos */ | ||||
| 
 | ||||
|     /* Only setup for read initially, because we're about to send an RPC
 | ||||
|      * reply which must be in plain text. When the next incoming RPC | ||||
| @ -204,73 +204,73 @@ static int protocol_client_auth_sasl_step(VncState *vs, uint8_t *data, size_t le | ||||
| 
 | ||||
|     /* NB, distinction of NULL vs "" is *critical* in SASL */ | ||||
|     if (datalen) { | ||||
| 	clientdata = (char*)data; | ||||
| 	clientdata[datalen-1] = '\0'; /* Wire includes '\0', but make sure */ | ||||
| 	datalen--; /* Don't count NULL byte when passing to _start() */ | ||||
|         clientdata = (char*)data; | ||||
|         clientdata[datalen-1] = '\0'; /* Wire includes '\0', but make sure */ | ||||
|         datalen--; /* Don't count NULL byte when passing to _start() */ | ||||
|     } | ||||
| 
 | ||||
|     VNC_DEBUG("Step using SASL Data %p (%d bytes)\n", | ||||
| 	      clientdata, datalen); | ||||
|               clientdata, datalen); | ||||
|     err = sasl_server_step(vs->sasl.conn, | ||||
| 			   clientdata, | ||||
| 			   datalen, | ||||
| 			   &serverout, | ||||
| 			   &serveroutlen); | ||||
|                            clientdata, | ||||
|                            datalen, | ||||
|                            &serverout, | ||||
|                            &serveroutlen); | ||||
|     if (err != SASL_OK && | ||||
| 	err != SASL_CONTINUE) { | ||||
| 	VNC_DEBUG("sasl step failed %d (%s)\n", | ||||
| 		  err, sasl_errdetail(vs->sasl.conn)); | ||||
| 	sasl_dispose(&vs->sasl.conn); | ||||
| 	vs->sasl.conn = NULL; | ||||
| 	goto authabort; | ||||
|         err != SASL_CONTINUE) { | ||||
|         VNC_DEBUG("sasl step failed %d (%s)\n", | ||||
|                   err, sasl_errdetail(vs->sasl.conn)); | ||||
|         sasl_dispose(&vs->sasl.conn); | ||||
|         vs->sasl.conn = NULL; | ||||
|         goto authabort; | ||||
|     } | ||||
| 
 | ||||
|     if (serveroutlen > SASL_DATA_MAX_LEN) { | ||||
| 	VNC_DEBUG("sasl step reply data too long %d\n", | ||||
| 		  serveroutlen); | ||||
| 	sasl_dispose(&vs->sasl.conn); | ||||
| 	vs->sasl.conn = NULL; | ||||
| 	goto authabort; | ||||
|         VNC_DEBUG("sasl step reply data too long %d\n", | ||||
|                   serveroutlen); | ||||
|         sasl_dispose(&vs->sasl.conn); | ||||
|         vs->sasl.conn = NULL; | ||||
|         goto authabort; | ||||
|     } | ||||
| 
 | ||||
|     VNC_DEBUG("SASL return data %d bytes, nil; %d\n", | ||||
| 	      serveroutlen, serverout ? 0 : 1); | ||||
|               serveroutlen, serverout ? 0 : 1); | ||||
| 
 | ||||
|     if (serveroutlen) { | ||||
| 	vnc_write_u32(vs, serveroutlen + 1); | ||||
| 	vnc_write(vs, serverout, serveroutlen + 1); | ||||
|         vnc_write_u32(vs, serveroutlen + 1); | ||||
|         vnc_write(vs, serverout, serveroutlen + 1); | ||||
|     } else { | ||||
| 	vnc_write_u32(vs, 0); | ||||
|         vnc_write_u32(vs, 0); | ||||
|     } | ||||
| 
 | ||||
|     /* Whether auth is complete */ | ||||
|     vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1); | ||||
| 
 | ||||
|     if (err == SASL_CONTINUE) { | ||||
| 	VNC_DEBUG("%s", "Authentication must continue\n"); | ||||
| 	/* Wait for step length */ | ||||
| 	vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4); | ||||
|         VNC_DEBUG("%s", "Authentication must continue\n"); | ||||
|         /* Wait for step length */ | ||||
|         vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4); | ||||
|     } else { | ||||
| 	if (!vnc_auth_sasl_check_ssf(vs)) { | ||||
| 	    VNC_DEBUG("Authentication rejected for weak SSF %d\n", vs->csock); | ||||
| 	    goto authreject; | ||||
| 	} | ||||
|         if (!vnc_auth_sasl_check_ssf(vs)) { | ||||
|             VNC_DEBUG("Authentication rejected for weak SSF %d\n", vs->csock); | ||||
|             goto authreject; | ||||
|         } | ||||
| 
 | ||||
| 	/* Check username whitelist ACL */ | ||||
| 	if (vnc_auth_sasl_check_access(vs) < 0) { | ||||
| 	    VNC_DEBUG("Authentication rejected for ACL %d\n", vs->csock); | ||||
| 	    goto authreject; | ||||
| 	} | ||||
|         /* Check username whitelist ACL */ | ||||
|         if (vnc_auth_sasl_check_access(vs) < 0) { | ||||
|             VNC_DEBUG("Authentication rejected for ACL %d\n", vs->csock); | ||||
|             goto authreject; | ||||
|         } | ||||
| 
 | ||||
| 	VNC_DEBUG("Authentication successful %d\n", vs->csock); | ||||
| 	vnc_write_u32(vs, 0); /* Accept auth */ | ||||
| 	/*
 | ||||
| 	 * Delay writing in SSF encoded mode until pending output | ||||
| 	 * buffer is written | ||||
| 	 */ | ||||
| 	if (vs->sasl.runSSF) | ||||
| 	    vs->sasl.waitWriteSSF = vs->output.offset; | ||||
| 	start_client_init(vs); | ||||
|         VNC_DEBUG("Authentication successful %d\n", vs->csock); | ||||
|         vnc_write_u32(vs, 0); /* Accept auth */ | ||||
|         /*
 | ||||
|          * Delay writing in SSF encoded mode until pending output | ||||
|          * buffer is written | ||||
|          */ | ||||
|         if (vs->sasl.runSSF) | ||||
|             vs->sasl.waitWriteSSF = vs->output.offset; | ||||
|         start_client_init(vs); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| @ -293,15 +293,15 @@ static int protocol_client_auth_sasl_step_len(VncState *vs, uint8_t *data, size_ | ||||
|     uint32_t steplen = read_u32(data, 0); | ||||
|     VNC_DEBUG("Got client step len %d\n", steplen); | ||||
|     if (steplen > SASL_DATA_MAX_LEN) { | ||||
| 	VNC_DEBUG("Too much SASL data %d\n", steplen); | ||||
| 	vnc_client_error(vs); | ||||
| 	return -1; | ||||
|         VNC_DEBUG("Too much SASL data %d\n", steplen); | ||||
|         vnc_client_error(vs); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     if (steplen == 0) | ||||
| 	return protocol_client_auth_sasl_step(vs, NULL, 0); | ||||
|         return protocol_client_auth_sasl_step(vs, NULL, 0); | ||||
|     else | ||||
| 	vnc_read_when(vs, protocol_client_auth_sasl_step, steplen); | ||||
|         vnc_read_when(vs, protocol_client_auth_sasl_step, steplen); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| @ -332,67 +332,67 @@ static int protocol_client_auth_sasl_start(VncState *vs, uint8_t *data, size_t l | ||||
| 
 | ||||
|     /* NB, distinction of NULL vs "" is *critical* in SASL */ | ||||
|     if (datalen) { | ||||
| 	clientdata = (char*)data; | ||||
| 	clientdata[datalen-1] = '\0'; /* Should be on wire, but make sure */ | ||||
| 	datalen--; /* Don't count NULL byte when passing to _start() */ | ||||
|         clientdata = (char*)data; | ||||
|         clientdata[datalen-1] = '\0'; /* Should be on wire, but make sure */ | ||||
|         datalen--; /* Don't count NULL byte when passing to _start() */ | ||||
|     } | ||||
| 
 | ||||
|     VNC_DEBUG("Start SASL auth with mechanism %s. Data %p (%d bytes)\n", | ||||
| 	      vs->sasl.mechlist, clientdata, datalen); | ||||
|               vs->sasl.mechlist, clientdata, datalen); | ||||
|     err = sasl_server_start(vs->sasl.conn, | ||||
| 			    vs->sasl.mechlist, | ||||
| 			    clientdata, | ||||
| 			    datalen, | ||||
| 			    &serverout, | ||||
| 			    &serveroutlen); | ||||
|                             vs->sasl.mechlist, | ||||
|                             clientdata, | ||||
|                             datalen, | ||||
|                             &serverout, | ||||
|                             &serveroutlen); | ||||
|     if (err != SASL_OK && | ||||
| 	err != SASL_CONTINUE) { | ||||
| 	VNC_DEBUG("sasl start failed %d (%s)\n", | ||||
| 		  err, sasl_errdetail(vs->sasl.conn)); | ||||
| 	sasl_dispose(&vs->sasl.conn); | ||||
| 	vs->sasl.conn = NULL; | ||||
| 	goto authabort; | ||||
|         err != SASL_CONTINUE) { | ||||
|         VNC_DEBUG("sasl start failed %d (%s)\n", | ||||
|                   err, sasl_errdetail(vs->sasl.conn)); | ||||
|         sasl_dispose(&vs->sasl.conn); | ||||
|         vs->sasl.conn = NULL; | ||||
|         goto authabort; | ||||
|     } | ||||
|     if (serveroutlen > SASL_DATA_MAX_LEN) { | ||||
| 	VNC_DEBUG("sasl start reply data too long %d\n", | ||||
| 		  serveroutlen); | ||||
| 	sasl_dispose(&vs->sasl.conn); | ||||
| 	vs->sasl.conn = NULL; | ||||
| 	goto authabort; | ||||
|         VNC_DEBUG("sasl start reply data too long %d\n", | ||||
|                   serveroutlen); | ||||
|         sasl_dispose(&vs->sasl.conn); | ||||
|         vs->sasl.conn = NULL; | ||||
|         goto authabort; | ||||
|     } | ||||
| 
 | ||||
|     VNC_DEBUG("SASL return data %d bytes, nil; %d\n", | ||||
| 	      serveroutlen, serverout ? 0 : 1); | ||||
|               serveroutlen, serverout ? 0 : 1); | ||||
| 
 | ||||
|     if (serveroutlen) { | ||||
| 	vnc_write_u32(vs, serveroutlen + 1); | ||||
| 	vnc_write(vs, serverout, serveroutlen + 1); | ||||
|         vnc_write_u32(vs, serveroutlen + 1); | ||||
|         vnc_write(vs, serverout, serveroutlen + 1); | ||||
|     } else { | ||||
| 	vnc_write_u32(vs, 0); | ||||
|         vnc_write_u32(vs, 0); | ||||
|     } | ||||
| 
 | ||||
|     /* Whether auth is complete */ | ||||
|     vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1); | ||||
| 
 | ||||
|     if (err == SASL_CONTINUE) { | ||||
| 	VNC_DEBUG("%s", "Authentication must continue\n"); | ||||
| 	/* Wait for step length */ | ||||
| 	vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4); | ||||
|         VNC_DEBUG("%s", "Authentication must continue\n"); | ||||
|         /* Wait for step length */ | ||||
|         vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4); | ||||
|     } else { | ||||
| 	if (!vnc_auth_sasl_check_ssf(vs)) { | ||||
| 	    VNC_DEBUG("Authentication rejected for weak SSF %d\n", vs->csock); | ||||
| 	    goto authreject; | ||||
| 	} | ||||
|         if (!vnc_auth_sasl_check_ssf(vs)) { | ||||
|             VNC_DEBUG("Authentication rejected for weak SSF %d\n", vs->csock); | ||||
|             goto authreject; | ||||
|         } | ||||
| 
 | ||||
| 	/* Check username whitelist ACL */ | ||||
| 	if (vnc_auth_sasl_check_access(vs) < 0) { | ||||
| 	    VNC_DEBUG("Authentication rejected for ACL %d\n", vs->csock); | ||||
| 	    goto authreject; | ||||
| 	} | ||||
|         /* Check username whitelist ACL */ | ||||
|         if (vnc_auth_sasl_check_access(vs) < 0) { | ||||
|             VNC_DEBUG("Authentication rejected for ACL %d\n", vs->csock); | ||||
|             goto authreject; | ||||
|         } | ||||
| 
 | ||||
| 	VNC_DEBUG("Authentication successful %d\n", vs->csock); | ||||
| 	vnc_write_u32(vs, 0); /* Accept auth */ | ||||
| 	start_client_init(vs); | ||||
|         VNC_DEBUG("Authentication successful %d\n", vs->csock); | ||||
|         vnc_write_u32(vs, 0); /* Accept auth */ | ||||
|         start_client_init(vs); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| @ -415,13 +415,13 @@ static int protocol_client_auth_sasl_start_len(VncState *vs, uint8_t *data, size | ||||
|     uint32_t startlen = read_u32(data, 0); | ||||
|     VNC_DEBUG("Got client start len %d\n", startlen); | ||||
|     if (startlen > SASL_DATA_MAX_LEN) { | ||||
| 	VNC_DEBUG("Too much SASL data %d\n", startlen); | ||||
| 	vnc_client_error(vs); | ||||
| 	return -1; | ||||
|         VNC_DEBUG("Too much SASL data %d\n", startlen); | ||||
|         vnc_client_error(vs); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     if (startlen == 0) | ||||
| 	return protocol_client_auth_sasl_start(vs, NULL, 0); | ||||
|         return protocol_client_auth_sasl_start(vs, NULL, 0); | ||||
| 
 | ||||
|     vnc_read_when(vs, protocol_client_auth_sasl_start, startlen); | ||||
|     return 0; | ||||
| @ -431,35 +431,35 @@ static int protocol_client_auth_sasl_mechname(VncState *vs, uint8_t *data, size_ | ||||
| { | ||||
|     char *mechname = malloc(len + 1); | ||||
|     if (!mechname) { | ||||
| 	VNC_DEBUG("Out of memory reading mechname\n"); | ||||
| 	vnc_client_error(vs); | ||||
|         VNC_DEBUG("Out of memory reading mechname\n"); | ||||
|         vnc_client_error(vs); | ||||
|     } | ||||
|     strncpy(mechname, (char*)data, len); | ||||
|     mechname[len] = '\0'; | ||||
|     VNC_DEBUG("Got client mechname '%s' check against '%s'\n", | ||||
| 	      mechname, vs->sasl.mechlist); | ||||
|               mechname, vs->sasl.mechlist); | ||||
| 
 | ||||
|     if (strncmp(vs->sasl.mechlist, mechname, len) == 0) { | ||||
| 	if (vs->sasl.mechlist[len] != '\0' && | ||||
| 	    vs->sasl.mechlist[len] != ',') { | ||||
| 	    VNC_DEBUG("One %d", vs->sasl.mechlist[len]); | ||||
| 	    vnc_client_error(vs); | ||||
| 	    return -1; | ||||
| 	} | ||||
|         if (vs->sasl.mechlist[len] != '\0' && | ||||
|             vs->sasl.mechlist[len] != ',') { | ||||
|             VNC_DEBUG("One %d", vs->sasl.mechlist[len]); | ||||
|             vnc_client_error(vs); | ||||
|             return -1; | ||||
|         } | ||||
|     } else { | ||||
| 	char *offset = strstr(vs->sasl.mechlist, mechname); | ||||
| 	VNC_DEBUG("Two %p\n", offset); | ||||
| 	if (!offset) { | ||||
| 	    vnc_client_error(vs); | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	VNC_DEBUG("Two '%s'\n", offset); | ||||
| 	if (offset[-1] != ',' || | ||||
| 	    (offset[len] != '\0'&& | ||||
| 	     offset[len] != ',')) { | ||||
| 	    vnc_client_error(vs); | ||||
| 	    return -1; | ||||
| 	} | ||||
|         char *offset = strstr(vs->sasl.mechlist, mechname); | ||||
|         VNC_DEBUG("Two %p\n", offset); | ||||
|         if (!offset) { | ||||
|             vnc_client_error(vs); | ||||
|             return -1; | ||||
|         } | ||||
|         VNC_DEBUG("Two '%s'\n", offset); | ||||
|         if (offset[-1] != ',' || | ||||
|             (offset[len] != '\0'&& | ||||
|              offset[len] != ',')) { | ||||
|             vnc_client_error(vs); | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     free(vs->sasl.mechlist); | ||||
| @ -475,20 +475,20 @@ static int protocol_client_auth_sasl_mechname_len(VncState *vs, uint8_t *data, s | ||||
|     uint32_t mechlen = read_u32(data, 0); | ||||
|     VNC_DEBUG("Got client mechname len %d\n", mechlen); | ||||
|     if (mechlen > 100) { | ||||
| 	VNC_DEBUG("Too long SASL mechname data %d\n", mechlen); | ||||
| 	vnc_client_error(vs); | ||||
| 	return -1; | ||||
|         VNC_DEBUG("Too long SASL mechname data %d\n", mechlen); | ||||
|         vnc_client_error(vs); | ||||
|         return -1; | ||||
|     } | ||||
|     if (mechlen < 1) { | ||||
| 	VNC_DEBUG("Too short SASL mechname %d\n", mechlen); | ||||
| 	vnc_client_error(vs); | ||||
| 	return -1; | ||||
|         VNC_DEBUG("Too short SASL mechname %d\n", mechlen); | ||||
|         vnc_client_error(vs); | ||||
|         return -1; | ||||
|     } | ||||
|     vnc_read_when(vs, protocol_client_auth_sasl_mechname,mechlen); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| #define USES_X509_AUTH(vs)			      \ | ||||
| #define USES_X509_AUTH(vs)                              \ | ||||
|     ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE ||   \ | ||||
|      (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC ||    \ | ||||
|      (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN ||  \ | ||||
| @ -507,116 +507,116 @@ void start_auth_sasl(VncState *vs) | ||||
| 
 | ||||
|     /* Get local & remote client addresses in form  IPADDR;PORT */ | ||||
|     if (!(localAddr = vnc_socket_local_addr("%s;%s", vs->csock))) | ||||
| 	goto authabort; | ||||
|         goto authabort; | ||||
| 
 | ||||
|     if (!(remoteAddr = vnc_socket_remote_addr("%s;%s", vs->csock))) { | ||||
| 	free(localAddr); | ||||
| 	goto authabort; | ||||
|         free(localAddr); | ||||
|         goto authabort; | ||||
|     } | ||||
| 
 | ||||
|     err = sasl_server_new("vnc", | ||||
| 			  NULL, /* FQDN - just delegates to gethostname */ | ||||
| 			  NULL, /* User realm */ | ||||
| 			  localAddr, | ||||
| 			  remoteAddr, | ||||
| 			  NULL, /* Callbacks, not needed */ | ||||
| 			  SASL_SUCCESS_DATA, | ||||
| 			  &vs->sasl.conn); | ||||
|                           NULL, /* FQDN - just delegates to gethostname */ | ||||
|                           NULL, /* User realm */ | ||||
|                           localAddr, | ||||
|                           remoteAddr, | ||||
|                           NULL, /* Callbacks, not needed */ | ||||
|                           SASL_SUCCESS_DATA, | ||||
|                           &vs->sasl.conn); | ||||
|     free(localAddr); | ||||
|     free(remoteAddr); | ||||
|     localAddr = remoteAddr = NULL; | ||||
| 
 | ||||
|     if (err != SASL_OK) { | ||||
| 	VNC_DEBUG("sasl context setup failed %d (%s)", | ||||
| 		  err, sasl_errstring(err, NULL, NULL)); | ||||
| 	vs->sasl.conn = NULL; | ||||
| 	goto authabort; | ||||
|         VNC_DEBUG("sasl context setup failed %d (%s)", | ||||
|                   err, sasl_errstring(err, NULL, NULL)); | ||||
|         vs->sasl.conn = NULL; | ||||
|         goto authabort; | ||||
|     } | ||||
| 
 | ||||
| #ifdef CONFIG_VNC_TLS | ||||
|     /* Inform SASL that we've got an external SSF layer from TLS/x509 */ | ||||
|     if (vs->vd->auth == VNC_AUTH_VENCRYPT && | ||||
| 	vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) { | ||||
| 	gnutls_cipher_algorithm_t cipher; | ||||
| 	sasl_ssf_t ssf; | ||||
|         vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) { | ||||
|         gnutls_cipher_algorithm_t cipher; | ||||
|         sasl_ssf_t ssf; | ||||
| 
 | ||||
| 	cipher = gnutls_cipher_get(vs->tls.session); | ||||
| 	if (!(ssf = (sasl_ssf_t)gnutls_cipher_get_key_size(cipher))) { | ||||
| 	    VNC_DEBUG("%s", "cannot TLS get cipher size\n"); | ||||
| 	    sasl_dispose(&vs->sasl.conn); | ||||
| 	    vs->sasl.conn = NULL; | ||||
| 	    goto authabort; | ||||
| 	} | ||||
| 	ssf *= 8; /* tls key size is bytes, sasl wants bits */ | ||||
|         cipher = gnutls_cipher_get(vs->tls.session); | ||||
|         if (!(ssf = (sasl_ssf_t)gnutls_cipher_get_key_size(cipher))) { | ||||
|             VNC_DEBUG("%s", "cannot TLS get cipher size\n"); | ||||
|             sasl_dispose(&vs->sasl.conn); | ||||
|             vs->sasl.conn = NULL; | ||||
|             goto authabort; | ||||
|         } | ||||
|         ssf *= 8; /* tls key size is bytes, sasl wants bits */ | ||||
| 
 | ||||
| 	err = sasl_setprop(vs->sasl.conn, SASL_SSF_EXTERNAL, &ssf); | ||||
| 	if (err != SASL_OK) { | ||||
| 	    VNC_DEBUG("cannot set SASL external SSF %d (%s)\n", | ||||
| 		      err, sasl_errstring(err, NULL, NULL)); | ||||
| 	    sasl_dispose(&vs->sasl.conn); | ||||
| 	    vs->sasl.conn = NULL; | ||||
| 	    goto authabort; | ||||
| 	} | ||||
|         err = sasl_setprop(vs->sasl.conn, SASL_SSF_EXTERNAL, &ssf); | ||||
|         if (err != SASL_OK) { | ||||
|             VNC_DEBUG("cannot set SASL external SSF %d (%s)\n", | ||||
|                       err, sasl_errstring(err, NULL, NULL)); | ||||
|             sasl_dispose(&vs->sasl.conn); | ||||
|             vs->sasl.conn = NULL; | ||||
|             goto authabort; | ||||
|         } | ||||
|     } else | ||||
| #endif /* CONFIG_VNC_TLS */ | ||||
| 	vs->sasl.wantSSF = 1; | ||||
|         vs->sasl.wantSSF = 1; | ||||
| 
 | ||||
|     memset (&secprops, 0, sizeof secprops); | ||||
|     /* Inform SASL that we've got an external SSF layer from TLS */ | ||||
|     if (strncmp(vs->vd->display, "unix:", 5) == 0 | ||||
| #ifdef CONFIG_VNC_TLS | ||||
| 	/* Disable SSF, if using TLS+x509+SASL only. TLS without x509
 | ||||
| 	   is not sufficiently strong */ | ||||
| 	|| (vs->vd->auth == VNC_AUTH_VENCRYPT && | ||||
| 	    vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) | ||||
|         /* Disable SSF, if using TLS+x509+SASL only. TLS without x509
 | ||||
|            is not sufficiently strong */ | ||||
|         || (vs->vd->auth == VNC_AUTH_VENCRYPT && | ||||
|             vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) | ||||
| #endif /* CONFIG_VNC_TLS */ | ||||
| 	) { | ||||
| 	/* If we've got TLS or UNIX domain sock, we don't care about SSF */ | ||||
| 	secprops.min_ssf = 0; | ||||
| 	secprops.max_ssf = 0; | ||||
| 	secprops.maxbufsize = 8192; | ||||
| 	secprops.security_flags = 0; | ||||
|         ) { | ||||
|         /* If we've got TLS or UNIX domain sock, we don't care about SSF */ | ||||
|         secprops.min_ssf = 0; | ||||
|         secprops.max_ssf = 0; | ||||
|         secprops.maxbufsize = 8192; | ||||
|         secprops.security_flags = 0; | ||||
|     } else { | ||||
| 	/* Plain TCP, better get an SSF layer */ | ||||
| 	secprops.min_ssf = 56; /* Good enough to require kerberos */ | ||||
| 	secprops.max_ssf = 100000; /* Arbitrary big number */ | ||||
| 	secprops.maxbufsize = 8192; | ||||
| 	/* Forbid any anonymous or trivially crackable auth */ | ||||
| 	secprops.security_flags = | ||||
| 	    SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT; | ||||
|         /* Plain TCP, better get an SSF layer */ | ||||
|         secprops.min_ssf = 56; /* Good enough to require kerberos */ | ||||
|         secprops.max_ssf = 100000; /* Arbitrary big number */ | ||||
|         secprops.maxbufsize = 8192; | ||||
|         /* Forbid any anonymous or trivially crackable auth */ | ||||
|         secprops.security_flags = | ||||
|             SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT; | ||||
|     } | ||||
| 
 | ||||
|     err = sasl_setprop(vs->sasl.conn, SASL_SEC_PROPS, &secprops); | ||||
|     if (err != SASL_OK) { | ||||
| 	VNC_DEBUG("cannot set SASL security props %d (%s)\n", | ||||
| 		  err, sasl_errstring(err, NULL, NULL)); | ||||
| 	sasl_dispose(&vs->sasl.conn); | ||||
| 	vs->sasl.conn = NULL; | ||||
| 	goto authabort; | ||||
|         VNC_DEBUG("cannot set SASL security props %d (%s)\n", | ||||
|                   err, sasl_errstring(err, NULL, NULL)); | ||||
|         sasl_dispose(&vs->sasl.conn); | ||||
|         vs->sasl.conn = NULL; | ||||
|         goto authabort; | ||||
|     } | ||||
| 
 | ||||
|     err = sasl_listmech(vs->sasl.conn, | ||||
| 			NULL, /* Don't need to set user */ | ||||
| 			"", /* Prefix */ | ||||
| 			",", /* Separator */ | ||||
| 			"", /* Suffix */ | ||||
| 			&mechlist, | ||||
| 			NULL, | ||||
| 			NULL); | ||||
|                         NULL, /* Don't need to set user */ | ||||
|                         "", /* Prefix */ | ||||
|                         ",", /* Separator */ | ||||
|                         "", /* Suffix */ | ||||
|                         &mechlist, | ||||
|                         NULL, | ||||
|                         NULL); | ||||
|     if (err != SASL_OK) { | ||||
| 	VNC_DEBUG("cannot list SASL mechanisms %d (%s)\n", | ||||
| 		  err, sasl_errdetail(vs->sasl.conn)); | ||||
| 	sasl_dispose(&vs->sasl.conn); | ||||
| 	vs->sasl.conn = NULL; | ||||
| 	goto authabort; | ||||
|         VNC_DEBUG("cannot list SASL mechanisms %d (%s)\n", | ||||
|                   err, sasl_errdetail(vs->sasl.conn)); | ||||
|         sasl_dispose(&vs->sasl.conn); | ||||
|         vs->sasl.conn = NULL; | ||||
|         goto authabort; | ||||
|     } | ||||
|     VNC_DEBUG("Available mechanisms for client: '%s'\n", mechlist); | ||||
| 
 | ||||
|     if (!(vs->sasl.mechlist = strdup(mechlist))) { | ||||
| 	VNC_DEBUG("Out of memory"); | ||||
| 	sasl_dispose(&vs->sasl.conn); | ||||
| 	vs->sasl.conn = NULL; | ||||
| 	goto authabort; | ||||
|         VNC_DEBUG("Out of memory"); | ||||
|         sasl_dispose(&vs->sasl.conn); | ||||
|         vs->sasl.conn = NULL; | ||||
|         goto authabort; | ||||
|     } | ||||
|     mechlistlen = strlen(mechlist); | ||||
|     vnc_write_u32(vs, mechlistlen); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 aliguori
						aliguori