SparkLabs Forum.

Community Help.


Use .opvn file extension

Hey,

If I export a VPN-Config the file extension is .conf... Why it isn't standard .ovpn extension?

I only discovered it, because I tried the OpenVPN-App for iOS, which needs config files with the .ovpn extension..

Thanks
Michael
Hi Michael,

Viscosity predates popular use of the .ovpn extension (back when Viscosity was first developed .conf was the way to go). Viscosity's configurations also must store additional Viscosity configurations, bundle in additional scripts, etc., so it would be misleading to indicate that they are simply standard raw OpenVPN config files. We are looking at making an export option designed for the iOS client, however in the meantime here is our recommended method:

1. Select your connection in Viscosity's Preferences window
2. Click on the small cog button near the bottom right and select "Export Connection". Save it to your Desktop.
3. If you are using a Mac, right-click on your saved connection in the Finder and select "Show Package Contents". Under Windows you can simply double-click on the folder.
4. Rename the "config.conf" file to end with ".ovpn" instead (you can give it a different name as well if you wish).
5. Drag all of the files into the OpenVPN Documents section in iTunes (the iOS app doesn't require them all to be a single file).

Cheers,
James
So I had this problem this evening, and I just went ahead and created a gist for it using Python...

https://gist.github.com/brianbruggeman/ ... 1071be5946


Basic steps are:

1. Install click: pip install click
2. Usage:
viscosity-to-openvpn.py <input> <output>

E.g.

a. Export .visc or .visz to desktop
b. python viscosity-to-openvpn.py ~/Desktop/<filename>.vis{c,v}


LICENSE: Public Domain

Code (viscosity-to-openvpn.py):

Code: Select all

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Converts viscosity export files into an open vpn package
Usage: viscosity-to-openvpn.py <input> <output>
"""
import io
import os
import sys
import tarfile

import click

if sys.version.startswith('3'):
    unicode = str


# ----------------------------------------------------------------------
# Exceptions
# ----------------------------------------------------------------------
class ConversionError(Exception):
    """Base conversion error"""
    pass


class NoConnectionName(ConversionError):
    """No connection name was available"""
    pass


class NoCertificateData(ConversionError):
    """No certificate data was found within certificate file"""
    pass


class NoCertificateFile(ConversionError):
    """File was not available within archive"""
    pass

# ----------------------------------------------------------------------
# Command-line Interface
# ----------------------------------------------------------------------
@click.command()
@click.argument('input-path', type=click.Path(exists=True))
@click.argument('output', required=False, type=click.Path(), default=None)
def convert(input_path, output=None):
    '''Converts Viscosity package

    Args:
        input (str): path to folder or file input
        output (str): path to folder output  [default: None]
    '''
    if input_path.endswith('.visc'):
        output = input_path if output is None else output
        if output and not os.path.exists(output):
            output = input_path
        files = [os.path.join(input_path, filename) for filename in os.listdir(input_path)]
        for config_fp in files:
            new_config = []
            if config_fp.endswith('.conf'):
                with io.open(config_fp, encoding='utf-8') as stream:
                    connection_name = extract(stream, new_config, input_path=input_path)

                new_config.insert(0, '# OpenVPN Config for {}'.format(connection_name))
                new_config = '\n'.join(new_config) + '\n'
                output_filepath = os.path.join(output, '{}.ovpn'.format(connection_name))
                with io.open(output_filepath, 'w', encoding='utf-8') as out:
                    out.write(unicode(new_config))

                print('Wrote: {}'.format(output_filepath))

    elif input_path.endswith('.visz'):
        if output is None:
            output = os.path.dirname(input_path)

        data = {}
        with tarfile.open(input_path) as zipped:
            for filepath, fileinfo in zip(zipped.getnames(), zipped.getmembers()):
                if not fileinfo.isfile():
                    continue
                filename = filepath.split(os.path.sep)[-1]
                data[filename] = zipped.extractfile(filepath).read()

        for key in data:
            if not key.endswith('.conf') or key.startswith('.'):
                continue

            import pdb; pdb.set_trace()
            new_config = []
            lines = data[key].split('\n')
            connection_name = extract(lines, new_config, file_data=data)

            new_config.insert(0, '# OpenVPN Config for {}'.format(connection_name))
            new_config = '\n'.join(new_config) + '\n'
            output_filepath = os.path.join(output, '{}.ovpn'.format(connection_name))
            with io.open(output_filepath, 'w', encoding='utf-8') as out:
                out.write(unicode(new_config))

            print('Wrote: {}'.format(output_filepath))


# ----------------------------------------------------------------------
# CLI Support
# ----------------------------------------------------------------------
def extract(data, new_config, input_path=None, file_data={}):
    certificate_files = ['ca', 'cert', 'key', 'tls-auth']
    connection_name = ''
    for line in data:
        line = line.rstrip()

        if not line.strip():
            continue

        # This was an invalid configuration, for some reason
        elif line == 'compress lzo':
            continue

        elif line.startswith('#'):
            if line.startswith('#viscosity name'):
                connection_name = line.split('#viscosity name ', 1)[-1]
                connection_name = connection_name.strip()
            continue

        try:
            key, value = line.split(' ', 1)
            value = value.strip()
        except ValueError:
            key, value = line, ''

        if key in certificate_files:
            if key == 'tls-auth':
                value, direction = value.split(' ', 1)
                if direction:
                    new_config.append('key-direction {}'.format(direction))

            if input_path:
                cert_filepath = os.path.join(input_path, value)
                with io.open(cert_filepath, encoding='utf-8') as cf:
                    certificate = cf.read()
            else:
                if value not in file_data:
                    raise NoCertificateFile('Could not find certificate file in archive')
                certificate = file_data.get(value)

            if not certificate:
                raise NoCertificateData('Could not find certificate data')

            new_config.append('<%s>' % key)
            new_config.append(certificate)
            new_config.append('</%s>' % key)
            continue

        new_config.append(line)

    if not connection_name.strip():
        raise NoConnectionName('Could not find connection name in file.  Aborting')

    return connection_name


if __name__ == '__main__':
    convert()
3 posts Page 1 of 1

Copyright © 2016 SparkLabs Pty Ltd. All Rights Reserved. Privacy Policy