1*4bff34e3Sthurlow /* 2*4bff34e3Sthurlow * Copyright (c) 2001 Apple Computer, Inc. All rights reserved. 3*4bff34e3Sthurlow * 4*4bff34e3Sthurlow * @APPLE_LICENSE_HEADER_START@ 5*4bff34e3Sthurlow * 6*4bff34e3Sthurlow * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7*4bff34e3Sthurlow * Reserved. This file contains Original Code and/or Modifications of 8*4bff34e3Sthurlow * Original Code as defined in and that are subject to the Apple Public 9*4bff34e3Sthurlow * Source License Version 1.0 (the 'License'). You may not use this file 10*4bff34e3Sthurlow * except in compliance with the License. Please obtain a copy of the 11*4bff34e3Sthurlow * License at http://www.apple.com/publicsource and read it before using 12*4bff34e3Sthurlow * this file. 13*4bff34e3Sthurlow * 14*4bff34e3Sthurlow * The Original Code and all software distributed under the License are 15*4bff34e3Sthurlow * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16*4bff34e3Sthurlow * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17*4bff34e3Sthurlow * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18*4bff34e3Sthurlow * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19*4bff34e3Sthurlow * License for the specific language governing rights and limitations 20*4bff34e3Sthurlow * under the License." 21*4bff34e3Sthurlow * 22*4bff34e3Sthurlow * @APPLE_LICENSE_HEADER_END@ 23*4bff34e3Sthurlow */ 24*4bff34e3Sthurlow 25*4bff34e3Sthurlow #pragma ident "%Z%%M% %I% %E% SMI" 26*4bff34e3Sthurlow 27*4bff34e3Sthurlow /* 28*4bff34e3Sthurlow * Routines for interacting with the user to get credentials 29*4bff34e3Sthurlow * (workgroup/domain, username, password, etc.) 30*4bff34e3Sthurlow */ 31*4bff34e3Sthurlow 32*4bff34e3Sthurlow #include <stdlib.h> 33*4bff34e3Sthurlow #include <stdio.h> 34*4bff34e3Sthurlow #include <string.h> 35*4bff34e3Sthurlow #include <errno.h> 36*4bff34e3Sthurlow #include <unistd.h> 37*4bff34e3Sthurlow #include <libintl.h> 38*4bff34e3Sthurlow #include <ctype.h> 39*4bff34e3Sthurlow 40*4bff34e3Sthurlow #include <netsmb/smb_lib.h> 41*4bff34e3Sthurlow #include <netsmb/smb_keychain.h> 42*4bff34e3Sthurlow 43*4bff34e3Sthurlow #define MAXLINE 127 44*4bff34e3Sthurlow #define MAXPASSWD 256 /* from libc:getpass */ 45*4bff34e3Sthurlow 46*4bff34e3Sthurlow static void 47*4bff34e3Sthurlow smb_tty_prompt(char *prmpt, 48*4bff34e3Sthurlow char *buf, size_t buflen) 49*4bff34e3Sthurlow { 50*4bff34e3Sthurlow char temp[MAXLINE+1]; 51*4bff34e3Sthurlow char *cp; 52*4bff34e3Sthurlow int ch; 53*4bff34e3Sthurlow 54*4bff34e3Sthurlow memset(temp, 0, sizeof (temp)); 55*4bff34e3Sthurlow 56*4bff34e3Sthurlow fprintf(stderr, "%s", prmpt); 57*4bff34e3Sthurlow cp = temp; 58*4bff34e3Sthurlow while ((ch = getc(stdin)) != EOF) { 59*4bff34e3Sthurlow if (ch == '\n' || ch == '\r') 60*4bff34e3Sthurlow break; 61*4bff34e3Sthurlow if (isspace(ch) || iscntrl(ch)) 62*4bff34e3Sthurlow continue; 63*4bff34e3Sthurlow *cp++ = ch; 64*4bff34e3Sthurlow if (cp == &temp[MAXLINE]) 65*4bff34e3Sthurlow break; 66*4bff34e3Sthurlow } 67*4bff34e3Sthurlow 68*4bff34e3Sthurlow /* If input empty, accept default. */ 69*4bff34e3Sthurlow if (cp == temp) 70*4bff34e3Sthurlow return; 71*4bff34e3Sthurlow 72*4bff34e3Sthurlow /* Use input as new value. */ 73*4bff34e3Sthurlow strncpy(buf, temp, buflen); 74*4bff34e3Sthurlow } 75*4bff34e3Sthurlow 76*4bff34e3Sthurlow int 77*4bff34e3Sthurlow smb_get_authentication( 78*4bff34e3Sthurlow char *dom, size_t domlen, 79*4bff34e3Sthurlow char *usr, size_t usrlen, 80*4bff34e3Sthurlow char *passwd, size_t passwdlen, 81*4bff34e3Sthurlow const char *systemname, struct smb_ctx *ctx) 82*4bff34e3Sthurlow { 83*4bff34e3Sthurlow char *npw; 84*4bff34e3Sthurlow int error, i, kcask, kcerr; 85*4bff34e3Sthurlow 86*4bff34e3Sthurlow if (ctx->ct_flags & SMBCF_KCFOUND || ctx->ct_flags & SMBCF_KCBAD) { 87*4bff34e3Sthurlow ctx->ct_flags &= ~SMBCF_KCFOUND; 88*4bff34e3Sthurlow } else { 89*4bff34e3Sthurlow ctx->ct_flags &= ~(SMBCF_KCFOUND | SMBCF_KCDOMAIN); 90*4bff34e3Sthurlow 91*4bff34e3Sthurlow /* 92*4bff34e3Sthurlow * 1st: try lookup using system name 93*4bff34e3Sthurlow */ 94*4bff34e3Sthurlow kcerr = smbfs_keychain_chk(systemname, usr); 95*4bff34e3Sthurlow if (!kcerr) { 96*4bff34e3Sthurlow /* 97*4bff34e3Sthurlow * Need passwd to be not empty for existing logic. 98*4bff34e3Sthurlow * The string here is arbitrary (a debugging hint) 99*4bff34e3Sthurlow * and will be replaced in the driver by the real 100*4bff34e3Sthurlow * password from the keychain. 101*4bff34e3Sthurlow */ 102*4bff34e3Sthurlow strcpy(passwd, "$KC_SYSTEM"); 103*4bff34e3Sthurlow ctx->ct_flags |= SMBCF_KCFOUND; 104*4bff34e3Sthurlow if (smb_debug) { 105*4bff34e3Sthurlow printf("found keychain entry for" 106*4bff34e3Sthurlow " server/user: %s/%s\n", 107*4bff34e3Sthurlow systemname, usr); 108*4bff34e3Sthurlow } 109*4bff34e3Sthurlow return (0); 110*4bff34e3Sthurlow } 111*4bff34e3Sthurlow 112*4bff34e3Sthurlow /* 113*4bff34e3Sthurlow * 2nd: try lookup using domain name 114*4bff34e3Sthurlow */ 115*4bff34e3Sthurlow kcerr = smbfs_keychain_chk(dom, usr); 116*4bff34e3Sthurlow if (!kcerr) { 117*4bff34e3Sthurlow /* Need passwd to be not empty... (see above) */ 118*4bff34e3Sthurlow strcpy(passwd, "$KC_DOMAIN"); 119*4bff34e3Sthurlow ctx->ct_flags |= (SMBCF_KCFOUND | SMBCF_KCDOMAIN); 120*4bff34e3Sthurlow if (smb_debug) { 121*4bff34e3Sthurlow printf("found keychain entry for" 122*4bff34e3Sthurlow " domain/user: %s/%s\n", 123*4bff34e3Sthurlow dom, usr); 124*4bff34e3Sthurlow } 125*4bff34e3Sthurlow return (0); 126*4bff34e3Sthurlow } 127*4bff34e3Sthurlow } 128*4bff34e3Sthurlow 129*4bff34e3Sthurlow if (isatty(STDIN_FILENO)) { /* need command-line prompting? */ 130*4bff34e3Sthurlow if (passwd && passwd[0] == '\0') { 131*4bff34e3Sthurlow npw = getpassphrase(dgettext(TEXT_DOMAIN, "Password:")); 132*4bff34e3Sthurlow strncpy(passwd, npw, passwdlen); 133*4bff34e3Sthurlow } 134*4bff34e3Sthurlow return (0); 135*4bff34e3Sthurlow } 136*4bff34e3Sthurlow 137*4bff34e3Sthurlow /* 138*4bff34e3Sthurlow * XXX: Ask the user for help, possibly via 139*4bff34e3Sthurlow * GNOME dbus or some such... (todo). 140*4bff34e3Sthurlow */ 141*4bff34e3Sthurlow smb_error(dgettext(TEXT_DOMAIN, 142*4bff34e3Sthurlow "Cannot prompt for a password when input is redirected."), 0); 143*4bff34e3Sthurlow 144*4bff34e3Sthurlow return (ENOTTY); 145*4bff34e3Sthurlow } 146*4bff34e3Sthurlow 147*4bff34e3Sthurlow int 148*4bff34e3Sthurlow smb_browse(struct smb_ctx *ctx, int anon) 149*4bff34e3Sthurlow { 150*4bff34e3Sthurlow /* 151*4bff34e3Sthurlow * Let user pick a share. 152*4bff34e3Sthurlow * Not supported. 153*4bff34e3Sthurlow */ 154*4bff34e3Sthurlow return (EINTR); 155*4bff34e3Sthurlow } 156