00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 #define SECURITY_MASK 0
00024 #define SECURITY_SET 0
00025
00026
00027 #define CAPABILITY_MASK 0
00028 #define CAPABILITY_SET 0
00029
00030
00031 #define CLI_CAPABILITY_MASK 0
00032 #define CLI_CAPABILITY_SET 0
00033
00034 static char *netbiosname;
00035 static char packet[BUFFER_SIZE];
00036
00037 static void save_file(const char *fname, void *ppacket, size_t length)
00038 {
00039 int fd;
00040 fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
00041 if (fd == -1) {
00042 perror(fname);
00043 return;
00044 }
00045 if (write(fd, ppacket, length) != length) {
00046 fprintf(stderr,"Failed to write %s\n", fname);
00047 return;
00048 }
00049 close(fd);
00050 printf("Wrote %ld bytes to %s\n", (unsigned long)length, fname);
00051 }
00052
00053 static void filter_reply(char *buf)
00054 {
00055 int msg_type = CVAL(buf,0);
00056 int type = CVAL(buf,smb_com);
00057 unsigned x;
00058
00059 if (msg_type) return;
00060
00061 switch (type) {
00062
00063 case SMBnegprot:
00064
00065 x = CVAL(buf, smb_vwv1);
00066 x = (x | SECURITY_SET) & ~SECURITY_MASK;
00067 SCVAL(buf, smb_vwv1, x);
00068
00069
00070 x = IVAL(buf,smb_vwv9+1);
00071 x = (x | CAPABILITY_SET) & ~CAPABILITY_MASK;
00072 SIVAL(buf, smb_vwv9+1, x);
00073 break;
00074
00075 }
00076 }
00077
00078 static void filter_request(char *buf)
00079 {
00080 int msg_type = CVAL(buf,0);
00081 int type = CVAL(buf,smb_com);
00082 pstring name1,name2;
00083 unsigned x;
00084
00085 if (msg_type) {
00086
00087 switch (msg_type) {
00088 case 0x81:
00089
00090 name_extract(buf,4,name1);
00091 name_extract(buf,4 + name_len(buf + 4),name2);
00092 d_printf("sesion_request: %s -> %s\n",
00093 name1, name2);
00094 if (netbiosname) {
00095
00096 name_mangle(netbiosname, buf+4, 0x20);
00097 }
00098 }
00099 return;
00100 }
00101
00102
00103 switch (type) {
00104 case SMBsesssetupX:
00105
00106 x = IVAL(buf,smb_vwv11);
00107 d_printf("SMBsesssetupX cap=0x%08x\n", x);
00108 d_printf("pwlen=%d/%d\n", SVAL(buf, smb_vwv7), SVAL(buf, smb_vwv8));
00109 system("mv sessionsetup.dat sessionsetup1.dat");
00110 save_file("sessionsetup.dat", smb_buf(buf), SVAL(buf, smb_vwv7));
00111 x = (x | CLI_CAPABILITY_SET) & ~CLI_CAPABILITY_MASK;
00112 SIVAL(buf, smb_vwv11, x);
00113 break;
00114 }
00115
00116 }
00117
00118
00119 static void filter_child(int c, struct in_addr dest_ip)
00120 {
00121 int s;
00122
00123
00124 s = open_socket_out(SOCK_STREAM, &dest_ip, 445, LONG_CONNECT_TIMEOUT);
00125
00126 if (s == -1) {
00127 d_printf("Unable to connect to %s\n", inet_ntoa(dest_ip));
00128 exit(1);
00129 }
00130
00131 while (c != -1 || s != -1) {
00132 fd_set fds;
00133 int num;
00134
00135 FD_ZERO(&fds);
00136 if (s != -1) FD_SET(s, &fds);
00137 if (c != -1) FD_SET(c, &fds);
00138
00139 num = sys_select_intr(MAX(s+1, c+1),&fds,NULL,NULL,NULL);
00140 if (num <= 0) continue;
00141
00142 if (c != -1 && FD_ISSET(c, &fds)) {
00143 if (!receive_smb(c, packet, BUFFER_SIZE, 0)) {
00144 d_printf("client closed connection\n");
00145 exit(0);
00146 }
00147 filter_request(packet);
00148 if (!send_smb(s, packet)) {
00149 d_printf("server is dead\n");
00150 exit(1);
00151 }
00152 }
00153 if (s != -1 && FD_ISSET(s, &fds)) {
00154 if (!receive_smb(s, packet, BUFFER_SIZE, 0)) {
00155 d_printf("server closed connection\n");
00156 exit(0);
00157 }
00158 filter_reply(packet);
00159 if (!send_smb(c, packet)) {
00160 d_printf("client is dead\n");
00161 exit(1);
00162 }
00163 }
00164 }
00165 d_printf("Connection closed\n");
00166 exit(0);
00167 }
00168
00169
00170 static void start_filter(char *desthost)
00171 {
00172 int s, c;
00173 struct in_addr dest_ip;
00174
00175 CatchChild();
00176
00177
00178 s = open_socket_in(SOCK_STREAM, 445, 0, 0, True);
00179
00180 if (s == -1) {
00181 d_printf("bind failed\n");
00182 exit(1);
00183 }
00184
00185 if (listen(s, 5) == -1) {
00186 d_printf("listen failed\n");
00187 }
00188
00189 if (!resolve_name(desthost, &dest_ip, 0x20)) {
00190 d_printf("Unable to resolve host %s\n", desthost);
00191 exit(1);
00192 }
00193
00194 while (1) {
00195 fd_set fds;
00196 int num;
00197 struct sockaddr addr;
00198 socklen_t in_addrlen = sizeof(addr);
00199
00200 FD_ZERO(&fds);
00201 FD_SET(s, &fds);
00202
00203 num = sys_select_intr(s+1,&fds,NULL,NULL,NULL);
00204 if (num > 0) {
00205 c = accept(s, &addr, &in_addrlen);
00206 if (c != -1) {
00207 if (fork() == 0) {
00208 close(s);
00209 filter_child(c, dest_ip);
00210 exit(0);
00211 } else {
00212 close(c);
00213 }
00214 }
00215 }
00216 }
00217 }
00218
00219
00220 int main(int argc, char *argv[])
00221 {
00222 char *desthost;
00223 pstring configfile;
00224
00225 setup_logging(argv[0],True);
00226
00227 pstrcpy(configfile,dyn_CONFIGFILE);
00228
00229 if (argc < 2) {
00230 fprintf(stderr,"smbfilter <desthost> <netbiosname>\n");
00231 exit(1);
00232 }
00233
00234 desthost = argv[1];
00235 if (argc > 2) {
00236 netbiosname = argv[2];
00237 }
00238
00239 if (!lp_load(configfile,True,False,False,True)) {
00240 d_printf("Unable to load config file\n");
00241 }
00242
00243 start_filter(desthost);
00244 return 0;
00245 }