Merged revisions 11610-11649 via svnmerge from
[wvapps.git] / wvdial / wvpapchap.cc
blobdc02317ad61c278c31e0cbc91cad9b95ee20ada8
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2003 Net Integration Technologies, Inc.
5 * Re-write of wvpapsecrets.cc. This one supports CHAP as well, and is also
6 * much safer.
7 */
9 #include "wvpapchap.h"
10 #include "wvfile.h"
11 #include "strutils.h"
12 #include <assert.h>
13 #include <ctype.h>
14 #include <sys/stat.h>
17 ///////////////////////////////////////////////////////////
18 // WvPapChap public functions
19 ///////////////////////////////////////////////////////////
21 void WvPapChap::put_secret( WvString username, WvString password,
22 WvString remote )
23 /*******************************************/
25 assert( remote[0] );
27 // PAP secrets:
28 contents.zap();
29 load_file( PAP_SECRETS );
30 do_secret( username, password, remote );
31 if( write_file( PAP_SECRETS ) == false )
32 pap_success = false;
34 // CHAP secrets:
35 contents.zap();
36 load_file( CHAP_SECRETS );
37 do_secret( username, password, remote );
38 if( write_file( CHAP_SECRETS ) == false )
39 chap_success = false;
43 ///////////////////////////////////////////////////////////
44 // WvPapChap private functions
45 ///////////////////////////////////////////////////////////
47 bool WvPapChap::load_file( char * filename )
48 /******************************************/
49 // Loads filename into the "contents" string list, one line per entry.
51 char * from_file;
52 WvString * tmp;
54 WvFile file( filename, O_RDONLY );
55 if( file.isok() == false )
56 return( false );
58 from_file = file.getline();
59 while( from_file ) {
60 tmp = new WvString( from_file );
61 contents.append( tmp, true );
62 from_file = file.getline();
64 file.close();
66 return( true );
69 bool WvPapChap::write_file( char * filename )
70 /*******************************************/
71 // Writes the "contents" list to the file, one entry per line.
73 WvFile file( filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR );
74 if( file.isok() == false )
75 return( false );
77 WvStringList::Iter iter( contents );
78 for( iter.rewind(); iter.next(); )
79 file.print( "%s\n", *iter );
81 file.close();
82 return( true );
85 void WvPapChap::do_secret( const char * _username, const char * _password,
86 const char * _remote )
87 /***********************************************/
88 // Goes through the "contents" list, looking for lines that have the same
89 // username. If they do, and the remote value is either "*" or remote,
90 // the secret is removed. Otherwise, it is left in place. At the end of the
91 // list, the secret "username remote password" is added.
92 // remote defaults to "wvdial".
94 WvStringList::Iter iter( contents );
95 WvString username;
96 WvString password;
97 WvString remote;
99 if( !_username || !_password )
100 return;
102 // we need to backslash-escape all punctuation, so that pppd reads it
103 // correctly.
104 username = backslash_escape( _username );
105 password = backslash_escape( _password );
106 remote = _remote;
108 if( !remote )
109 remote = "*";
111 for( iter.rewind(); iter.next(); ) {
112 // Is this line a comment?
113 if( iter()[0] == '#' )
114 continue;
116 // Is the line blank?
117 const char * p = iter();
119 p++;
120 while( *p != '\0' && isspace( *p ) );
121 p--;
122 if( *p == '\0' )
123 continue;
125 // p points at the first non-whitespace char.
126 const char * q = p;
128 q++;
129 while( *q != '\0' && !isspace( *q ) );
130 q--;
131 if( *q == '\0' ) {
132 // illegal line, so get rid of it.
133 iter.unlink();
134 iter.rewind();
135 continue;
137 if( strncmp( username, p, q-p ) != 0 )
138 // different username, so let it stay.
139 continue;
141 p=q;
143 p++;
144 while( *p != '\0' && isspace( *p ) );
145 // p now points to the beginning of the "remote" section.
146 if( strncmp( p, remote, strlen( remote ) ) == 0 || *p == '*' ) {
147 // conflicting secret, so get rid of it.
148 iter.unlink();
149 iter.rewind();
150 continue;
153 // This secret line should be fine.
156 contents.append( new WvString( "%s\t%s\t%s", username, remote, password ),
157 true );