Skip to content

Commit ded408f

Browse files
committed
Merge branch 'jk/git-prompt'
* jk/git-prompt: contrib: add credential helper for OS X Keychain Makefile: OS X has /dev/tty Makefile: linux has /dev/tty credential: use git_prompt instead of git_getpass prompt: use git_terminal_prompt add generic terminal prompt function refactor git_getpass into generic prompt function move git_getpass to its own source file imap-send: don't check return value of git_getpass imap-send: avoid buffer overflow Conflicts: Makefile
2 parents 200888e + 34961d3 commit ded408f

File tree

12 files changed

+374
-60
lines changed

12 files changed

+374
-60
lines changed

Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ all::
245245
#
246246
# Define NO_REGEX if you have no or inferior regex support in your C library.
247247
#
248+
# Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
249+
# user.
250+
#
248251
# Define GETTEXT_POISON if you are debugging the choice of strings marked
249252
# for translation. In a GETTEXT_POISON build, you can turn all strings marked
250253
# for translation into gibberish by setting the GIT_GETTEXT_POISON variable
@@ -543,6 +546,7 @@ LIB_H += compat/bswap.h
543546
LIB_H += compat/cygwin.h
544547
LIB_H += compat/mingw.h
545548
LIB_H += compat/obstack.h
549+
LIB_H += compat/terminal.h
546550
LIB_H += compat/win32/pthread.h
547551
LIB_H += compat/win32/syslog.h
548552
LIB_H += compat/win32/poll.h
@@ -585,6 +589,7 @@ LIB_H += parse-options.h
585589
LIB_H += patch-ids.h
586590
LIB_H += pkt-line.h
587591
LIB_H += progress.h
592+
LIB_H += prompt.h
588593
LIB_H += quote.h
589594
LIB_H += reflog-walk.h
590595
LIB_H += refs.h
@@ -632,6 +637,7 @@ LIB_OBJS += color.o
632637
LIB_OBJS += combine-diff.o
633638
LIB_OBJS += commit.o
634639
LIB_OBJS += compat/obstack.o
640+
LIB_OBJS += compat/terminal.o
635641
LIB_OBJS += config.o
636642
LIB_OBJS += connect.o
637643
LIB_OBJS += connected.o
@@ -694,6 +700,7 @@ LIB_OBJS += pkt-line.o
694700
LIB_OBJS += preload-index.o
695701
LIB_OBJS += pretty.o
696702
LIB_OBJS += progress.o
703+
LIB_OBJS += prompt.o
697704
LIB_OBJS += quote.o
698705
LIB_OBJS += reachable.o
699706
LIB_OBJS += read-cache.o
@@ -856,6 +863,7 @@ ifeq ($(uname_S),Linux)
856863
NO_MKSTEMPS = YesPlease
857864
HAVE_PATHS_H = YesPlease
858865
LIBC_CONTAINS_LIBINTL = YesPlease
866+
HAVE_DEV_TTY = YesPlease
859867
endif
860868
ifeq ($(uname_S),GNU/kFreeBSD)
861869
NO_STRLCPY = YesPlease
@@ -917,6 +925,7 @@ ifeq ($(uname_S),Darwin)
917925
endif
918926
NO_MEMMEM = YesPlease
919927
USE_ST_TIMESPEC = YesPlease
928+
HAVE_DEV_TTY = YesPlease
920929
endif
921930
ifeq ($(uname_S),SunOS)
922931
NEEDS_SOCKET = YesPlease
@@ -1685,6 +1694,10 @@ ifdef HAVE_LIBCHARSET_H
16851694
BASIC_CFLAGS += -DHAVE_LIBCHARSET_H
16861695
endif
16871696

1697+
ifdef HAVE_DEV_TTY
1698+
BASIC_CFLAGS += -DHAVE_DEV_TTY
1699+
endif
1700+
16881701
ifdef DIR_HAS_BSD_GROUP_SEMANTICS
16891702
COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS
16901703
endif

cache.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,6 @@ struct ref {
10281028
extern struct ref *find_ref_by_name(const struct ref *list, const char *name);
10291029

10301030
#define CONNECT_VERBOSE (1u << 0)
1031-
extern char *git_getpass(const char *prompt);
10321031
extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
10331032
extern int finish_connect(struct child_process *conn);
10341033
extern int git_connection_is_socket(struct child_process *conn);

compat/terminal.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include "git-compat-util.h"
2+
#include "compat/terminal.h"
3+
#include "sigchain.h"
4+
#include "strbuf.h"
5+
6+
#ifdef HAVE_DEV_TTY
7+
8+
static int term_fd = -1;
9+
static struct termios old_term;
10+
11+
static void restore_term(void)
12+
{
13+
if (term_fd < 0)
14+
return;
15+
16+
tcsetattr(term_fd, TCSAFLUSH, &old_term);
17+
term_fd = -1;
18+
}
19+
20+
static void restore_term_on_signal(int sig)
21+
{
22+
restore_term();
23+
sigchain_pop(sig);
24+
raise(sig);
25+
}
26+
27+
char *git_terminal_prompt(const char *prompt, int echo)
28+
{
29+
static struct strbuf buf = STRBUF_INIT;
30+
int r;
31+
FILE *fh;
32+
33+
fh = fopen("/dev/tty", "w+");
34+
if (!fh)
35+
return NULL;
36+
37+
if (!echo) {
38+
struct termios t;
39+
40+
if (tcgetattr(fileno(fh), &t) < 0) {
41+
fclose(fh);
42+
return NULL;
43+
}
44+
45+
old_term = t;
46+
term_fd = fileno(fh);
47+
sigchain_push_common(restore_term_on_signal);
48+
49+
t.c_lflag &= ~ECHO;
50+
if (tcsetattr(fileno(fh), TCSAFLUSH, &t) < 0) {
51+
term_fd = -1;
52+
fclose(fh);
53+
return NULL;
54+
}
55+
}
56+
57+
fputs(prompt, fh);
58+
fflush(fh);
59+
60+
r = strbuf_getline(&buf, fh, '\n');
61+
if (!echo) {
62+
putc('\n', fh);
63+
fflush(fh);
64+
}
65+
66+
restore_term();
67+
fclose(fh);
68+
69+
if (r == EOF)
70+
return NULL;
71+
return buf.buf;
72+
}
73+
74+
#else
75+
76+
char *git_terminal_prompt(const char *prompt, int echo)
77+
{
78+
return getpass(prompt);
79+
}
80+
81+
#endif

compat/terminal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef COMPAT_TERMINAL_H
2+
#define COMPAT_TERMINAL_H
3+
4+
char *git_terminal_prompt(const char *prompt, int echo);
5+
6+
#endif /* COMPAT_TERMINAL_H */

connect.c

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -608,47 +608,3 @@ int finish_connect(struct child_process *conn)
608608
free(conn);
609609
return code;
610610
}
611-
612-
char *git_getpass(const char *prompt)
613-
{
614-
const char *askpass;
615-
struct child_process pass;
616-
const char *args[3];
617-
static struct strbuf buffer = STRBUF_INIT;
618-
619-
askpass = getenv("GIT_ASKPASS");
620-
if (!askpass)
621-
askpass = askpass_program;
622-
if (!askpass)
623-
askpass = getenv("SSH_ASKPASS");
624-
if (!askpass || !(*askpass)) {
625-
char *result = getpass(prompt);
626-
if (!result)
627-
die_errno("Could not read password");
628-
return result;
629-
}
630-
631-
args[0] = askpass;
632-
args[1] = prompt;
633-
args[2] = NULL;
634-
635-
memset(&pass, 0, sizeof(pass));
636-
pass.argv = args;
637-
pass.out = -1;
638-
639-
if (start_command(&pass))
640-
exit(1);
641-
642-
strbuf_reset(&buffer);
643-
if (strbuf_read(&buffer, pass.out, 20) < 0)
644-
die("failed to read password from %s\n", askpass);
645-
646-
close(pass.out);
647-
648-
if (finish_command(&pass))
649-
exit(1);
650-
651-
strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
652-
653-
return buffer.buf;
654-
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
git-credential-osxkeychain
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
all:: git-credential-osxkeychain
2+
3+
CC = gcc
4+
RM = rm -f
5+
CFLAGS = -g -Wall
6+
7+
git-credential-osxkeychain: git-credential-osxkeychain.o
8+
$(CC) -o $@ $< -Wl,-framework -Wl,Security
9+
10+
git-credential-osxkeychain.o: git-credential-osxkeychain.c
11+
$(CC) -c $(CFLAGS) $<
12+
13+
clean:
14+
$(RM) git-credential-osxkeychain git-credential-osxkeychain.o

0 commit comments

Comments
 (0)