1 /* ruserpass.c -- parse .netrc-format file.
3 * Portions of this code are
4 * Copyright (c) 1985 Regents of the University of California.
7 * Redistribution and use in source and binary forms are permitted
8 * provided that the above copyright notice and this paragraph are
9 * duplicated in all such forms and that any documentation,
10 * advertising materials, and other materials related to such
11 * distribution and use acknowledge that the software was developed
12 * by the University of California, Berkeley. The name of the
13 * University may not be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 * Portions of this code are Copyright (c) 2013, by the authors of
20 * nmh. See the COPYRIGHT file in the root directory of the nmh
21 * distribution for complete copyright information.
26 #include "ruserpass.h"
27 #include "credentials.h"
43 #define MAX_TOKVAL_SIZE 1024 /* Including terminating NUL. */
50 static struct toktab toktabs
[] = {
52 { "default", DEFAULT
},
54 { "password", PASSWD
},
56 { "account", ACCOUNT
},
65 static int token(char *);
69 ruserpass(const char *host
, char **aname
, char **apass
, int flags
)
74 init_credentials_file ();
76 cfile
= fopen (credentials_file
, "r");
79 perror (credentials_file
);
81 char tokval
[MAX_TOKVAL_SIZE
];
84 bool usedefault
= false;
85 while ((t
= token(tokval
))) {
93 if (token(tokval
) != ID
)
96 * Allow match either for user's host name.
98 if (strcasecmp(host
, tokval
) == 0)
103 while ((t
= token(tokval
)) && t
!= MACH
&& t
!= DEFAULT
) {
106 if (token(tokval
) && *aname
== 0)
107 *aname
= mh_xstrdup(tokval
);
111 if (!credentials_no_perm_check
&&
112 fstat(fileno(cfile
), &stb
) >= 0 &&
113 (stb
.st_mode
& 077) != 0) {
114 /* We make this a fatal error to force the
115 user to correct it. */
116 inform("group or other permissions, %#o, "
117 "forbidden: %s", stb
.st_mode
, credentials_file
);
118 die("Remove password or correct file "
121 if (token(tokval
) && *apass
== 0)
122 *apass
= mh_xstrdup(tokval
);
134 "Unknown keyword %s in credentials file %s\n",
135 tokval
, credentials_file
);
144 if (!*aname
&& ! (flags
& RUSERPASS_NO_PROMPT_USER
)) {
148 if ((myname
= getlogin()) == NULL
) {
151 if ((pp
= getpwuid (getuid())) != NULL
)
152 myname
= pp
->pw_name
;
154 printf("Name (%s:%s): ", host
, myname
);
156 if (fgets(tmp
, sizeof tmp
, stdin
) == NULL
) {
157 advise ("tmp", "fgets");
159 trim_suffix_c(tmp
, '\n');
160 if (*tmp
!= '\0' || myname
== NULL
) {
164 *aname
= mh_xstrdup(myname
);
167 if (!*apass
&& ! (flags
& RUSERPASS_NO_PROMPT_PASSWORD
)) {
171 snprintf(prompt
, sizeof(prompt
), "Password (%s:%s): ", host
, *aname
);
172 mypass
= nmh_getpass(prompt
);
174 if (*mypass
== '\0') {
178 *aname
= mh_xstrdup(mypass
);
187 const char normalStop
[] = "\t\n ,"; /* Each breaks a word. */
192 if (feof(cfile
) || ferror(cfile
))
196 while ((c
= getc(cfile
)) != EOF
&& c
&& strchr(stop
, c
))
203 /* FIXME: Where is the quoted-string syntax of netrc documented?
204 * This code treats «"foo""bar"» as two tokens without further
208 /* Might be backslash. Get it again later. It's handled then. */
209 if (ungetc(c
, cfile
) == EOF
)
212 while ((c
= getc(cfile
)) != EOF
&& c
&& !strchr(stop
, c
)) {
213 if (c
== '\\' && (c
= getc(cfile
)) == EOF
)
214 return TOK_EOF
; /* Discard whole token. */
217 if (cp
- tokval
> MAX_TOKVAL_SIZE
-1) {
218 die("credential tokens restricted to length %d",
219 MAX_TOKVAL_SIZE
- 1);
224 for (t
= toktabs
; t
->tokstr
; t
++)
225 if (!strcmp(t
->tokstr
, tokval
))