Script d'extraction:
En réponse à la réponse utile de Tamsyn Michael, j'ai créé un petit programme pour automatiser la tâche d'extraction. Il génère les fichiers appropriés nécessaires pour openvpn, puis ajoute ces noms de fichiers au fichier de paramètres d'origine.
//woahguy@askubuntu
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int i = 0;
string buffer, filename, ca, cert, key, auth;
struct _tags { const char* first; const char* last; };
const char* files[] = { "ca.crt", "client.crt", "client.key", "ta.key" };
_tags tags[] = {
{ "<ca>", "</ca>" },
{ "<cert>", "</cert>" },
{ "<key>", "</key>" },
{ "<tls-auth>", "</tls-auth>" }
};
string string_between( string str, const string& from, const string& to ) {
size_t first = str.find(from);
size_t last = str.find(to);
return( str.substr ( first+from.size(),last-first-to.size()));
}
int read_file_to_buffer( string filename )
{
char line[12];
FILE* pFile = fopen( filename.c_str(), "r" );
if( pFile != NULL ) {
while( fgets( line, sizeof( line ), pFile ) ) {
buffer.append( line );
}
} else {
return 1;
}
return 0;
}
int write_buffer_to_file( string buffer, string filename )
{
FILE* pFile = fopen( filename.c_str(), "w" );
if( pFile != NULL ) {
fwrite (buffer.c_str(), sizeof(char), buffer.size(), pFile);
fclose(pFile);
} else {
return 1;
}
return 0;
}
int append_found_tags_to_main( int type )
{
FILE* pFile = fopen( filename.c_str(), "a+" );
if( pFile != NULL ) {
if( type == 1 ) {
fprintf( pFile, "\nca %s\r\ncert %s\r\nkey %s\r\n",
files[0], files[1], files[2] );
} else {
fprintf( pFile, "\nca %s\r\ncert %s\r\nkey %s\r\ntls-auth %s\r\n",
files[0], files[1], files[2], files[3] );
}
fclose(pFile);
}
return 0;
}
int extract_tags( )
{
while (buffer.find(tags[i].first) != std::string::npos ) {
if( i == 0 ) {
ca = string_between( buffer, tags[i].first, tags[i].last);
} else if( i == 1 ) {
cert = string_between( buffer, tags[i].first, tags[i].last);
} else if( i == 2 ) {
key = string_between( buffer, tags[i].first, tags[i].last);
} else if( i == 3 ) {
auth = string_between( buffer, tags[i].first, tags[i].last);
} else {
return 1;
}
i++;
}
return 0;
}
int write_tags( )
{
if( !ca.empty() && !cert.empty() && !key.empty() ) {
write_buffer_to_file( ca, files[0] );
write_buffer_to_file( cert, files[1] );
write_buffer_to_file( key, files[2] );
if( !auth.empty() ) {
write_buffer_to_file( auth, files[3] );
append_found_tags_to_main( 0 );
} else {
append_found_tags_to_main( 1 );
return 1;
}
} else {
return 2;
}
}
int main(int argc, char* argv[])
{
if( argv[1] == NULL ) {
printf("certgrabber<: You need to specify a valid filename to extract from.\r\n");
return 1;
} else {
if( argv[2] != NULL && argv[3] != NULL && argv[4] != NULL && argv[5] != NULL) {
files[0] = argv[2];
files[1] = argv[3];
files[2] = argv[4];
files[2] = argv[5];
}
filename = argv[1];
}
read_file_to_buffer( argv[1] );
if( buffer.empty()){
printf("certgrabber<: You need to specify a valid filename to extract from.\r\n");
return 2;
}
if( extract_tags() == 0 ) {
int result = write_tags();
if( result == 0 ) {
printf("certgrabber<: All certificates and keys successfully extracted.\r\n");
} else if( result == 1 ) {
printf("certgrabber<: Unable to find a TLS auth key, but this isn't exactly an error.\r\n");
} else if( result == 2 ) {
printf("certgrabber<: Something went totally wrong with the certificate files.\r\n");
}
} else {
printf("certgrabber<: Something went wrong while extracting the tags.\r\n");
return 3;
}
return 0;
}
Compilation et construction:
Vous devrez installer g ++ pour construire ceci
sudo apt-get install g++
Puis depuis le terminal
g++ -c main.cpp -o main.o \ g++ -o certgrabber main.o
Vous aurez maintenant le programme 'certgrabber' dans le dossier.
Utilisation du programme:
Extraire vers les noms de fichiers par défaut (ca.crt, client.crt, client.key, tls-auth.key)
./certgrabber settings.ovpn
Extraire vers des noms de fichiers personnalisés
./certgrabber settings.ovpn ca-1.crt client-1.crt client-1.key tls-1.key