1/*
2 * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
7 * Reserved.  This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License').  You may not use this file
10 * except in compliance with the License.  Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25/*
26 * Routines for interacting with the user to get credentials
27 * (workgroup/domain, username, password, etc.)
28 */
29
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33#include <errno.h>
34#include <unistd.h>
35#include <libintl.h>
36#include <ctype.h>
37
38#include <netsmb/smb_lib.h>
39#include "private.h"
40#include "ntlm.h"
41
42#if 0 /* not yet */
43#define	MAXLINE 	127
44static void
45smb_tty_prompt(char *prmpt,
46	char *buf, size_t buflen)
47{
48	char temp[MAXLINE+1];
49	char *cp;
50	int ch;
51
52	memset(temp, 0, sizeof (temp));
53
54	fprintf(stderr, "%s", prmpt);
55	cp = temp;
56	while ((ch = getc(stdin)) != EOF) {
57		if (ch == '\n' || ch == '\r')
58			break;
59		if (isspace(ch) || iscntrl(ch))
60			continue;
61		*cp++ = ch;
62		if (cp == &temp[MAXLINE])
63			break;
64	}
65
66	/* If input empty, accept default. */
67	if (cp == temp)
68		return;
69
70	/* Use input as new value. */
71	strncpy(buf, temp, buflen);
72}
73#endif /* not yet */
74
75/*
76 * Prompt for a new password after auth. failure.
77 * (and maybe new user+domain, but not yet)
78 */
79int
80smb_get_authentication(struct smb_ctx *ctx)
81{
82	char *npw;
83	int err;
84
85	/*
86	 * If we're getting a password, we must be doing
87	 * some kind of NTLM, possibly after a failure to
88	 * authenticate using Kerberos.  Turn off krb5.
89	 */
90	ctx->ct_authflags &= ~SMB_AT_KRB5;
91
92	if (ctx->ct_flags & SMBCF_KCFOUND) {
93		/* Tried a keychain hash and failed. */
94		/* XXX: delete the KC entry? */
95		ctx->ct_flags |= SMBCF_KCBAD;
96	}
97
98	if (ctx->ct_flags & SMBCF_NOPWD)
99		return (ENOTTY);
100
101	if (isatty(STDIN_FILENO)) {
102
103		/* Need command-line prompting. */
104		npw = getpassphrase(dgettext(TEXT_DOMAIN, "Password:"));
105		if (npw == NULL)
106			return (EINTR);
107		memset(ctx->ct_password, 0, sizeof (ctx->ct_password));
108		strlcpy(ctx->ct_password, npw, sizeof (ctx->ct_password));
109	} else {
110
111		/*
112		 * XXX: Ask the user for help, possibly via
113		 * GNOME dbus or some such... (todo).
114		 */
115		smb_error(dgettext(TEXT_DOMAIN,
116	"Cannot prompt for a password when input is redirected."), 0);
117		return (ENOTTY);
118	}
119
120	/*
121	 * Recompute the password hashes.
122	 */
123	if (ctx->ct_password[0]) {
124		err = ntlm_compute_lm_hash(ctx->ct_lmhash, ctx->ct_password);
125		if (err != 0)
126			return (err);
127		err = ntlm_compute_nt_hash(ctx->ct_nthash, ctx->ct_password);
128		if (err != 0)
129			return (err);
130	}
131
132	return (0);
133}
134
135/*ARGSUSED*/
136int
137smb_browse(struct smb_ctx *ctx, int anon)
138{
139	/*
140	 * Let user pick a share.
141	 * Not supported.
142	 */
143	return (EINTR);
144}
145