]> git.saurik.com Git - apt.git/blob - apt-pkg/contrib/netrc.cc
add ftp support, basic debugging
[apt.git] / apt-pkg / contrib / netrc.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: netrc.c,v 1.38 2007-11-07 09:21:35 bagder Exp $
4 /* ######################################################################
5
6 netrc file parser - returns the login and password of a give host in
7 a specified netrc-type file
8
9 Originally written by Daniel Stenberg, <daniel@haxx.se>, et al. and
10 placed into the Public Domain, do with it what you will.
11
12 ##################################################################### */
13 /*}}}*/
14
15 #include <apt-pkg/configuration.h>
16 #include <iostream>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <pwd.h>
22
23 #include "netrc.h"
24
25
26 /* Get user and password from .netrc when given a machine name */
27
28 enum {
29 NOTHING,
30 HOSTFOUND, /* the 'machine' keyword was found */
31 HOSTCOMPLETE, /* the machine name following the keyword was found too */
32 HOSTVALID, /* this is "our" machine! */
33 HOSTEND /* LAST enum */
34 };
35
36 /* make sure we have room for at least this size: */
37 #define LOGINSIZE 64
38 #define PASSWORDSIZE 64
39 #define NETRC DOT_CHAR "netrc"
40
41 /* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
42 int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
43 {
44 FILE *file;
45 int retcode = 1;
46 int specific_login = (login[0] != 0);
47 char *home = NULL;
48 bool netrc_alloc = false;
49 int state = NOTHING;
50
51 char state_login = 0; /* Found a login keyword */
52 char state_password = 0; /* Found a password keyword */
53 int state_our_login = false; /* With specific_login,
54 found *our* login name */
55
56 if (!netrcfile) {
57 home = getenv ("HOME"); /* portable environment reader */
58
59 if (!home) {
60 struct passwd *pw;
61 pw = getpwuid (geteuid ());
62 if(pw)
63 home = pw->pw_dir;
64 }
65
66 if (!home)
67 return -1;
68
69 asprintf (&netrcfile, "%s%s%s", home, DIR_CHAR, NETRC);
70 if(!netrcfile)
71 return -1;
72 else
73 netrc_alloc = true;
74 }
75
76 file = fopen (netrcfile, "r");
77 if(file) {
78 char *tok;
79 char *tok_buf;
80 bool done = false;
81 char netrcbuffer[256];
82
83 while (!done && fgets(netrcbuffer, sizeof (netrcbuffer), file)) {
84 tok = strtok_r (netrcbuffer, " \t\n", &tok_buf);
85 while (!done && tok) {
86 if(login[0] && password[0]) {
87 done = true;
88 break;
89 }
90
91 switch(state) {
92 case NOTHING:
93 if (!strcasecmp ("machine", tok)) {
94 /* the next tok is the machine name, this is in itself the
95 delimiter that starts the stuff entered for this machine,
96 after this we need to search for 'login' and
97 'password'. */
98 state = HOSTFOUND;
99 }
100 break;
101 case HOSTFOUND:
102 if (!strcasecmp (host, tok)) {
103 /* and yes, this is our host! */
104 state = HOSTVALID;
105 retcode = 0; /* we did find our host */
106 }
107 else
108 /* not our host */
109 state = NOTHING;
110 break;
111 case HOSTVALID:
112 /* we are now parsing sub-keywords concerning "our" host */
113 if (state_login) {
114 if (specific_login)
115 state_our_login = !strcasecmp (login, tok);
116 else
117 strncpy (login, tok, LOGINSIZE - 1);
118 state_login = 0;
119 } else if (state_password) {
120 if (state_our_login || !specific_login)
121 strncpy (password, tok, PASSWORDSIZE - 1);
122 state_password = 0;
123 } else if (!strcasecmp ("login", tok))
124 state_login = 1;
125 else if (!strcasecmp ("password", tok))
126 state_password = 1;
127 else if(!strcasecmp ("machine", tok)) {
128 /* ok, there's machine here go => */
129 state = HOSTFOUND;
130 state_our_login = false;
131 }
132 break;
133 } /* switch (state) */
134
135 tok = strtok_r (NULL, " \t\n", &tok_buf);
136 } /* while(tok) */
137 } /* while fgets() */
138
139 fclose(file);
140 }
141
142 if (netrc_alloc)
143 free(netrcfile);
144
145 return retcode;
146 }
147
148 void maybe_add_auth (URI &Uri, string NetRCFile)
149 {
150 if (_config->FindB("Debug::Acquire::netrc", false) == true)
151 std::clog << "maybe_add_auth: " << NetRCFile << std::endl;
152 if (Uri.Password.empty () == true || Uri.User.empty () == true)
153 {
154 if (NetRCFile.empty () == false)
155 {
156 char login[64] = "";
157 char password[64] = "";
158 char *netrcfile = strdup (NetRCFile.c_str ());
159 char *host = strdup (Uri.Host.c_str ());
160
161 if (host && 0 == parsenetrc (host, login, password, netrcfile))
162 {
163 Uri.User = string (login);
164 Uri.Password = string (password);
165 }
166
167 if (host)
168 free (host);
169 free (netrcfile);
170 }
171 }
172 }
173
174 #ifdef DEBUG
175 int main(int argc, char* argv[])
176 {
177 char login[64] = "";
178 char password[64] = "";
179
180 if(argc < 2)
181 return -1;
182
183 if(0 == parsenetrc (argv[1], login, password, argv[2])) {
184 printf("HOST: %s LOGIN: %s PASSWORD: %s\n", argv[1], login, password);
185 }
186 }
187 #endif