Solved

more secure read and write! how can i do this?

Posted on 2004-09-22
28
201 Views
Last Modified: 2010-04-01
Hello
in this program
i read one file

#include <iostream>
#include <fstream>
using namespace std;

int main(){
ifstream in ("Data/testtext.txt", ios::in);

if(!in) {
cout << "cannot open testtext.\n";
return 1;
}

char str[1000];
in.read(str, 999);
str[999] = '\0';
cout << ' ' << str;

in.close();
return 0;
}

in the file i have something like this

data2/somefolder/picture1
data2/somefolder/picture2

is it possible to put somewhere in the proggram
this
data2/somefolder/
so in the file i write only

picture1
picture2
...

my point here is to make more secure my proggram

thank you
0
Comment
Question by:sibas
  • 15
  • 12
28 Comments
 
LVL 11

Expert Comment

by:Jase-Coder
Comment Utility
you could store the path in a constant or you could, you the windows API to get the current working directory

const char path[] = "data2/somefolder/picture1";

then you could do

strcat(path, filename);

I think this answer your question :S
0
 

Author Comment

by:sibas
Comment Utility
Jase thanks, but is no way to working like this
first i am not working in windows
second i have more than 500 pictures to load
so to write 500 times
const char path[] = "data2/somefolder/picture1";
const char path[] = "data2/somefolder/picture2";
...
is a bit problem ;)
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
Are the files numbered 1..500?

i.e.
--------8<--------
#include <iostream>
#include <fstream>
#include <cstdio>
using namespace std;

int main()
{
      for (int i = 1;i <= 500;i++) {
            char filename[1024],str[1000];
            sprintf(filename,"data2/somefolder/picture%d",i);
            ifstream in(filename);
            if (!in) {
                  cerr << "Error: Unable to open " << filename << '\n';
                  continue;
            }
            in.read(str,999);
            str[999] = '\0';
            cout << str;
      }
}
--------8<--------
0
 

Author Comment

by:sibas
Comment Utility
Thanks rstaveley
maybe i dont say in the right way what i want,
the pictures picture1, picture2, is only an example
is no way to know from begin the names of those pictures
maybe is sexygirl.png or nicemoon.gif
only the path i know
and because my proggram you can modify from internet
i have to make it more secure
thanks
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
Do you want it to process all files in a directory?

> and because my proggram you can modify from internet

You mean to say that your program can be edited and recompiled?? What are you guarding against?
0
 

Author Comment

by:sibas
Comment Utility
i mean my program can read pictures from internet
when they stored in text file from internet,
but this is big risk if someone gives another path
i hope you realize what i mean
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
Ah I understand. You'll need to look for '/' to prevent people from getting clever with filenames like ../../../etc/passwd or whatever. You open a file with a bunch of filenames separated by newline characters.

--------8<--------
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(int argc,const char *argv[])
{
/* Open a file, which contains a list of filenames separated by newlines, specified at command line */
     if (argc < 2)
          return 1;
     ifstream filenames(*++argv);
     if (!filenames)
          return 1;
     string filename;
     while (getline(filenames,filename)) {
          if (filename.find('/') != string::npos)
               continue; // Path has a '/' - hacker reject!
          ifstream in(string("data2/somefolder/"+filename).c_str());
          if (!in) {
               cerr << "Error: Unable to open " << filename << '\n';
               continue;
          }
          // Your code from here....
          char str[1000];
          in.read(str,999);
          str[999] = '\0';
          cout << str;
     }
     return 0;
}
--------8<--------

Alternatively, for filenames separated by white space (i.e. no filenames with ' ' in them), use:
--------8<--------
     while (filenames >> filename) {
--------8<--------

This allows you to have more than one filename on the same line, which might be better for your CGI.
0
 

Author Comment

by:sibas
Comment Utility
hi rstaveley
i try this, is really nice,
but somewhere i cant make it work
so i try like this
int main(int argc,const char *argv[])
{
ifstream in ("/home/tests/progr14a/data/Rrpictures", ios::in);
if(!in) {
cout << "cannot open Rrpictures.\n";
return 1;
}

     string filename;
     while (getline(in,filename)) {
          if (filename.find('/') != string::npos)
               continue; // Path has a '/' - hacker reject!
          ifstream in(string("data2/somefolder/"+filename).c_str());
          if (!in) {
              cerr << "Error: Unable to open " << filename << '\n';
               continue;
         }
          // Your code from here....
          char str[100];
         in.read(str,99);
          str[99] = '\0';
          cout << str;
     }
     return 0;
}

and i have this result

./readcpp
Error: Unable to open S10.jpg
Error: Unable to open s11.png

so this read the text but why it stop?

0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
If it cannot read the files, it may be because your working directory isn't the directory you expected. Try using an absolute path (one that starts with '/').

e.g.

          ifstream in(string("/home/sibas/data2/somefolder/"+filename).c_str());

You will of course need to make the path right for your system :-)


0
 

Author Comment

by:sibas
Comment Utility
i try olso this but i have the same results

if you try to open a text working for you?
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
Do you have permissions?
0
 

Author Comment

by:sibas
Comment Utility
what you mean with this
i try with the same permissions that i have in my example,
for the text and dir
0
 
LVL 17

Accepted Solution

by:
rstaveley earned 125 total points
Comment Utility
This works for me on FreeBSD and Linux with files in /home/rob/src/. :

read.cpp
-----8<-----
#include <iostream>
#include <fstream>
#include <string>

int main(int argc,const char *argv[])
{
        ifstream in ("/home/rob/src/files.txt", ios::in);
        if(!in) {
                cout << "cannot open Rrpictures.\n";
                return 1;
        }

     string filename;
     while (getline(in,filename)) {
          if (filename.find('/') != string::npos)
               continue; // Path has a '/' - hacker reject!
          ifstream in(string("/home/rob/src/"+filename).c_str());
          if (!in) {
              cerr << "Error: Unable to open " << filename << '\n';
               continue;
         }
          // Your code from here....
          char str[100];
         in.read(str,99);
          str[99] = '\0';
          cout << str;
     }
     return 0;
}
--------8<--------

What is your OS?
0
 

Author Comment

by:sibas
Comment Utility
i am working with suse9
i try again but still i have problems
i will try latter and i let you know whats goin on
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:sibas
Comment Utility
Hello  rstaveley
i accept your answer, but i cant make it work
i see the results like this
ÿØÿá
ÿØÿá

any idea about what is wrong
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
They are binary files, and and cout is going to stop printing as soon as it finds a '\0' character in the char buffer. My guess is that ÿØÿá corresponds to something in your image file header, which is followed by a 0x00 byte.

You need to use raw binary mode, if you are going to output binary data to standard output.

There are of course many ways to do this, but I quite like using streambuf_iterators.

e.g.
--------8<--------
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>

using namespace std;

int main(int argc,const char *argv[])
{
/* Open a file, which contains a list of filenames separated by newlines, specified at command line */
     if (argc < 2)
          return 1;
     ifstream filenames(*++argv);
     if (!filenames)
          return 1;
     string filename;
     while (getline(filenames,filename)) {
          if (filename.find('/') != string::npos)
               continue; // Path has a '/' - hacker reject!
          ifstream in(string("data2/somefolder/"+filename).c_str());
          if (!in) {
               cerr << "Error: Unable to open " << filename << '\n';
               continue;
          }
          typedef istreambuf_iterator<char> Iitr; /* Input stream buffer iterator */
          typedef ostreambuf_iterator<char> Oitr; /* Output stream buffer iterator */
          Iitr iend; /* This gives us an object which we can use to test end of input */
          Oitr oitr(cout); /* Output stream buffer iterator for standard output */
          size_t count = 0; /* We are only going to handle the first 99 bytes */
          for (Iitr iitr(in);iitr != iend;++iitr) {
               *oitr = *iitr;
               if (++count == 99) /* Stop after 99 characters - if there are > 99 characters in the file */
                     break;
          }
     }
     return 0;
}
--------8<--------

If you find that this looks a bit freaky, you can use:

  // get length of file:
  in.seekg (0, ios::end);
  int length = in.tellg();
  in.seekg (0, ios::beg);
  char buf[99];
  in.read(buf,min(99,length));
  cout.write(buf,length);
0
 

Author Comment

by:sibas
Comment Utility
this is weird
but like this working

cout << filename << '\n';
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
Was it the filename you wanted... not the contents of the file?
0
 

Author Comment

by:sibas
Comment Utility
no the results is
B3.jpg
D10.jpg
D11.jpg

this is what i have in the text file
0
 

Author Comment

by:sibas
Comment Utility
of course i am still have problem because is string end not char
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
> this is what i have in the text file

...but you wanted the contents of files B3.jpg, D10.jpg etc. Right?
0
 

Author Comment

by:sibas
Comment Utility
i try to say it again (so sorry my english is not so good)

my program read text files and display pictures, text, music, etc

so in pictures.txt i have

data2/somefolder/B3.jpg
data2/somefolder/D10.jpg
...

with
char str[1000];
in.read(str, 999);
str[999] = '\0';
cout << str;

my proggram working just fine

now what i try to find is

how to write in text file only the
B3.jpg
D10.jpg
...
and the rest path somewhere inside the
ifstream in(string("/home/rob/src/"+thistext).c_str()

and when i do
cout << str;
to display all the path like
/home/rob/src/B3.jpg
/home/rob/src/D10.jpg
...

i dont know many thinks about c c++ i like it and i do it for hobby
thank you and sorry if i am trouble
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
I'm still having problems understanding your requirement.

From what can can gather, you start with input text file /home/tests/progr14a/data/Rrpictures, which contains a list of filenames with relative parths:

e.g.
  --------8<--------
  data2/somefolder/B3.jpg
  data2/somefolder/D10.jpg
  --------8<--------

You then want to create two output files.

(1) A list of files without their paths
e.g.
  --------8<--------
  B3.jpg
  D10.jpg
  --------8<--------

(2) A list of files with fully qualified paths
e.g.
  --------8<--------
  /home/tests/progr14a/data/B3.jpg
  /home/tests/progr14a/data/D10.jpg
  --------8<--------

If this is correct, let me know and I'll show you the code to do this. If I've misunderstood what you want, please could you describe what output files you want to create.
0
 

Author Comment

by:sibas
Comment Utility
example

#include <iostream>
#include <fstream>
using namespace std;

int main(){
ifstream in ("Data/testtext.txt", ios::in);

HERE WE READ THE TEXT FILE, INSIDE
data2/somefolder/B3.jpg
data2/somefolder/D10.jpg
...

if(!in) {
cout << "cannot open testtext.\n";
return 1;
}

char str[1000];
in.read(str, 999);
str[999] = '\0';
cout << ' ' << str;

in.close();
return 0;
}

in the file i have something like this

data2/somefolder/picture1
data2/somefolder/picture2

is it possible to put somewhere in the proggram
this
data2/somefolder/
so in the file i write only

picture1
picture2
...
0
 

Author Comment

by:sibas
Comment Utility
Yes i start with  /home/tests/progr14a/data/Rrpictures

inside the Rrpictures i have
  data2/somefolder/B3.jpg
  data2/somefolder/D10.jpg

with str i read this

  data2/somefolder/B3.jpg
  data2/somefolder/D10.jpg

and the proggram read the path and display the pictures

what i want is
in text file to write
B3.jpg
D10.jpg

and the rest path  /data2/somefolder/
to write somewhere inside the proggram

and when i do
cout << str;
then to display all the path
/data2/somefolder/B3.jpg
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
I still don't understand what you want your output files to be.

Do you want everything written to standard output (i.e. cout)?
Do you want anything written to an output file?
0
 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
> and the rest path  /data2/somefolder/
> to write somewhere inside the proggram

That's the bit I can't understand. Do you mean you want to write this to a separate output file?
0
 

Author Comment

by:sibas
Comment Utility
No i dont want it in seperate output file
i want something like

#include <iostream>
#include <fstream>
#include <string>

int main(int argc,const char *argv[])
{
    ifstream in (" /home/tests/progr14a/data/Rrpictures", ios::in);
        if(!in) {
                cout << "cannot open Rrpictures.\n";
                return 1;
        }

ifstream in(string("/data2/somefolder/"+TheNameOfPicture).c_str());

       
          char str[100];
          in.read(str,99);
          str[99] = '\0';
          cout << str;

//and the results of str must be /data2/somefolder/B3.jpg
...

     }
     return 0;
}

and the results of str must be /data2/somefolder/B3.jpg
...
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now