mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-02-11 00:00:08 +08:00
204 lines
12 KiB
Objective-C
204 lines
12 KiB
Objective-C
//
|
|
// NSError+OpenVPNError.m
|
|
// OpenVPN Adapter
|
|
//
|
|
// Created by Sergey Abramchuk on 17.01.2018.
|
|
//
|
|
|
|
#import "NSError+OpenVPNError.h"
|
|
|
|
#import <mbedtls/error.h>
|
|
|
|
#import "OpenVPNError.h"
|
|
|
|
@implementation NSError (OpenVPNAdapterErrorGeneration)
|
|
|
|
+ (NSError *)ovpn_errorObjectForAdapterError:(OpenVPNAdapterError)adapterError
|
|
description:(NSString *)description
|
|
message:(NSString *)message
|
|
fatal:(BOOL)fatal
|
|
{
|
|
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithDictionary:@{
|
|
NSLocalizedDescriptionKey: description,
|
|
OpenVPNAdapterErrorFatalKey: @(fatal)
|
|
}];
|
|
|
|
NSString *errorReason = [NSError ovpn_reasonForAdapterError:adapterError];
|
|
if (errorReason) {
|
|
userInfo[NSLocalizedFailureReasonErrorKey] = errorReason;
|
|
}
|
|
|
|
if (message.length) {
|
|
userInfo[OpenVPNAdapterErrorMessageKey] = message;
|
|
}
|
|
|
|
return [NSError errorWithDomain:OpenVPNAdapterErrorDomain code:adapterError userInfo:userInfo];
|
|
}
|
|
|
|
+ (OpenVPNAdapterError)ovpn_adapterErrorByName:(NSString *)errorName {
|
|
NSDictionary *errors = @{
|
|
@"NETWORK_RECV_ERROR": @(OpenVPNAdapterErrorNetworkRecvError),
|
|
@"NETWORK_EOF_ERROR": @(OpenVPNAdapterErrorNetworkEOFError),
|
|
@"NETWORK_SEND_ERROR": @(OpenVPNAdapterErrorNetworkSendError),
|
|
@"NETWORK_UNAVAILABLE": @(OpenVPNAdapterErrorNetworkUnavailable),
|
|
@"DECRYPT_ERROR": @(OpenVPNAdapterErrorDecryptError),
|
|
@"HMAC_ERROR": @(OpenVPNAdapterErrorDecryptError),
|
|
@"REPLAY_ERROR": @(OpenVPNAdapterErrorReplayError),
|
|
@"BUFFER_ERROR": @(OpenVPNAdapterErrorBufferError),
|
|
@"CC_ERROR": @(OpenVPNAdapterErrorCCError),
|
|
@"BAD_SRC_ADDR": @(OpenVPNAdapterErrorBadSrcAddr),
|
|
@"COMPRESS_ERROR": @(OpenVPNAdapterErrorCompressError),
|
|
@"RESOLVE_ERROR": @(OpenVPNAdapterErrorResolveError),
|
|
@"SOCKET_PROTECT_ERROR": @(OpenVPNAdapterErrorSocketProtectError),
|
|
@"TUN_READ_ERROR": @(OpenVPNAdapterErrorTUNReadError),
|
|
@"TUN_WRITE_ERROR": @(OpenVPNAdapterErrorTUNWriteError),
|
|
@"TUN_FRAMING_ERROR": @(OpenVPNAdapterErrorTUNFramingError),
|
|
@"TUN_SETUP_FAILED": @(OpenVPNAdapterErrorTUNSetupFailed),
|
|
@"TUN_IFACE_CREATE": @(OpenVPNAdapterErrorTUNIfaceCreate),
|
|
@"TUN_IFACE_DISABLED": @(OpenVPNAdapterErrorTUNIfaceDisabled),
|
|
@"TUN_ERROR": @(OpenVPNAdapterErrorTUNError),
|
|
@"TAP_NOT_SUPPORTED": @(OpenVPNAdapterErrorTAPNotSupported),
|
|
@"REROUTE_GW_NO_DNS": @(OpenVPNAdapterErrorRerouteGatewayNoDns),
|
|
@"TRANSPORT_ERROR": @(OpenVPNAdapterErrorTransportError),
|
|
@"TCP_OVERFLOW": @(OpenVPNAdapterErrorTCPOverflow),
|
|
@"TCP_SIZE_ERROR": @(OpenVPNAdapterErrorTCPSizeError),
|
|
@"TCP_CONNECT_ERROR": @(OpenVPNAdapterErrorTCPConnectError),
|
|
@"UDP_CONNECT_ERROR": @(OpenVPNAdapterErrorUDPConnectError),
|
|
@"SSL_ERROR": @(OpenVPNAdapterErrorSSLError),
|
|
@"SSL_PARTIAL_WRITE": @(OpenVPNAdapterErrorSSLPartialWrite),
|
|
@"ENCAPSULATION_ERROR": @(OpenVPNAdapterErrorEncapsulationError),
|
|
@"EPKI_CERT_ERROR": @(OpenVPNAdapterErrorEPKICertError),
|
|
@"EPKI_SIGN_ERROR": @(OpenVPNAdapterErrorEPKISignError),
|
|
@"HANDSHAKE_TIMEOUT": @(OpenVPNAdapterErrorHandshakeTimeout),
|
|
@"KEEPALIVE_TIMEOUT": @(OpenVPNAdapterErrorKeepaliveTimeout),
|
|
@"INACTIVE_TIMEOUT": @(OpenVPNAdapterErrorInactiveTimeout),
|
|
@"CONNECTION_TIMEOUT": @(OpenVPNAdapterErrorConnectionTimeout),
|
|
@"PRIMARY_EXPIRE": @(OpenVPNAdapterErrorPrimaryExpire),
|
|
@"TLS_VERSION_MIN": @(OpenVPNAdapterErrorTLSVersionMin),
|
|
@"TLS_AUTH_FAIL": @(OpenVPNAdapterErrorTLSAuthFail),
|
|
@"CERT_VERIFY_FAIL": @(OpenVPNAdapterErrorCertVerifyFail),
|
|
@"PEM_PASSWORD_FAIL": @(OpenVPNAdapterErrorPEMPasswordFail),
|
|
@"AUTH_FAILED": @(OpenVPNAdapterErrorAuthFailed),
|
|
@"CLIENT_HALT": @(OpenVPNAdapterErrorClientHalt),
|
|
@"CLIENT_RESTART": @(OpenVPNAdapterErrorClientRestart),
|
|
@"RELAY": @(OpenVPNAdapterErrorRelay),
|
|
@"RELAY_ERROR": @(OpenVPNAdapterErrorRelayError),
|
|
@"N_PAUSE": @(OpenVPNAdapterErrorPauseNumber),
|
|
@"N_RECONNECT": @(OpenVPNAdapterErrorReconnectNumber),
|
|
@"N_KEY_LIMIT_RENEG": @(OpenVPNAdapterErrorKeyLimitRenegNumber),
|
|
@"KEY_STATE_ERROR": @(OpenVPNAdapterErrorKeyStateError),
|
|
@"PROXY_ERROR": @(OpenVPNAdapterErrorProxyError),
|
|
@"PROXY_NEED_CREDS": @(OpenVPNAdapterErrorProxyNeedCreds),
|
|
@"KEV_NEGOTIATE_ERROR": @(OpenVPNAdapterErrorKevNegotiateError),
|
|
@"KEV_PENDING_ERROR": @(OpenVPNAdapterErrorKevPendingError),
|
|
@"N_KEV_EXPIRE": @(OpenVPNAdapterErrorKevExpireNumber),
|
|
@"PKTID_INVALID": @(OpenVPNAdapterErrorPKTIDInvalid),
|
|
@"PKTID_BACKTRACK": @(OpenVPNAdapterErrorPKTIDBacktrack),
|
|
@"PKTID_EXPIRE": @(OpenVPNAdapterErrorPKTIDExpire),
|
|
@"PKTID_REPLAY": @(OpenVPNAdapterErrorPKTIDReplay),
|
|
@"PKTID_TIME_BACKTRACK": @(OpenVPNAdapterErrorPKTIDTimeBacktrack),
|
|
@"DYNAMIC_CHALLENGE": @(OpenVPNAdapterErrorDynamicChallenge),
|
|
@"EPKI_ERROR": @(OpenVPNAdapterErrorEPKIError),
|
|
@"EPKI_INVALID_ALIAS": @(OpenVPNAdapterErrorEPKIInvalidAlias)
|
|
};
|
|
|
|
OpenVPNAdapterError error = errors[errorName] != nil ?
|
|
(OpenVPNAdapterError)[errors[errorName] integerValue] : OpenVPNAdapterErrorUnknown;
|
|
|
|
return error;
|
|
}
|
|
|
|
+ (NSString *)ovpn_reasonForAdapterError:(OpenVPNAdapterError)error {
|
|
switch (error) {
|
|
case OpenVPNAdapterErrorConfigurationFailure: return @"See OpenVPN error message for more details.";
|
|
case OpenVPNAdapterErrorCredentialsFailure: return @"See OpenVPN error message for more details.";
|
|
case OpenVPNAdapterErrorNetworkRecvError: return @"Errors receiving on network socket.";
|
|
case OpenVPNAdapterErrorNetworkEOFError: return @"EOF received on TCP network socket.";
|
|
case OpenVPNAdapterErrorNetworkSendError: return @"Errors sending on network socket";
|
|
case OpenVPNAdapterErrorNetworkUnavailable: return @"Network unavailable.";
|
|
case OpenVPNAdapterErrorDecryptError: return @"Data channel encrypt/decrypt error.";
|
|
case OpenVPNAdapterErrorHMACError: return @"HMAC verification failure.";
|
|
case OpenVPNAdapterErrorReplayError: return @"Error from PacketIDReceive.";
|
|
case OpenVPNAdapterErrorBufferError: return @"Exception thrown in Buffer methods.";
|
|
case OpenVPNAdapterErrorCCError: return @"General control channel errors.";
|
|
case OpenVPNAdapterErrorBadSrcAddr: return @"Packet from unknown source address.";
|
|
case OpenVPNAdapterErrorCompressError: return @"Compress/Decompress errors on data channel.";
|
|
case OpenVPNAdapterErrorResolveError: return @"DNS resolution error.";
|
|
case OpenVPNAdapterErrorSocketSetupFailed: return nil;
|
|
case OpenVPNAdapterErrorSocketProtectError: return @"Error calling protect() method on socket.";
|
|
case OpenVPNAdapterErrorTUNReadError: return @"Read errors on TUN/TAP interface.";
|
|
case OpenVPNAdapterErrorTUNWriteError: return @"Write errors on TUN/TAP interface.";
|
|
case OpenVPNAdapterErrorTUNFramingError: return @"Error with tun PF_INET/PF_INET6 prefix.";
|
|
case OpenVPNAdapterErrorTUNSetupFailed: return @"Error setting up TUN/TAP interface.";
|
|
case OpenVPNAdapterErrorTUNIfaceCreate: return @"Error creating TUN/TAP interface.";
|
|
case OpenVPNAdapterErrorTUNIfaceDisabled: return @"TUN/TAP interface is disabled.";
|
|
case OpenVPNAdapterErrorTUNError: return @"General tun error.";
|
|
case OpenVPNAdapterErrorTAPNotSupported: return @"Dev TAP is present in profile but not supported.";
|
|
case OpenVPNAdapterErrorRerouteGatewayNoDns: return @"redirect-gateway specified without alt DNS servers.";
|
|
case OpenVPNAdapterErrorTransportError: return @"General transport error";
|
|
case OpenVPNAdapterErrorTCPOverflow: return @"TCP output queue overflow.";
|
|
case OpenVPNAdapterErrorTCPSizeError: return @"Bad embedded uint16_t TCP packet size.";
|
|
case OpenVPNAdapterErrorTCPConnectError: return @"Client error on TCP connect.";
|
|
case OpenVPNAdapterErrorUDPConnectError: return @"Client error on UDP connect.";
|
|
case OpenVPNAdapterErrorSSLError: return @"Errors resulting from read/write on SSL object.";
|
|
case OpenVPNAdapterErrorSSLPartialWrite: return @"SSL object did not process all written cleartext.";
|
|
case OpenVPNAdapterErrorEncapsulationError: return @"Exceptions thrown during packet encapsulation.";
|
|
case OpenVPNAdapterErrorEPKICertError: return @"Error obtaining certificate from External PKI provider.";
|
|
case OpenVPNAdapterErrorEPKISignError: return @"Error obtaining RSA signature from External PKI provider.";
|
|
case OpenVPNAdapterErrorHandshakeTimeout: return @"Handshake failed to complete within given time frame.";
|
|
case OpenVPNAdapterErrorKeepaliveTimeout: return @"Lost contact with peer.";
|
|
case OpenVPNAdapterErrorInactiveTimeout: return @"Disconnected due to inactive timer.";
|
|
case OpenVPNAdapterErrorConnectionTimeout: return @"Connection failed to establish within given time.";
|
|
case OpenVPNAdapterErrorPrimaryExpire: return @"Primary key context expired.";
|
|
case OpenVPNAdapterErrorTLSVersionMin: return @"Peer cannot handshake at our minimum required TLS version.";
|
|
case OpenVPNAdapterErrorTLSAuthFail: return @"tls-auth HMAC verification failed.";
|
|
case OpenVPNAdapterErrorCertVerifyFail: return @"Peer certificate verification failure.";
|
|
case OpenVPNAdapterErrorPEMPasswordFail: return @"Incorrect or missing PEM private key decryption password.";
|
|
case OpenVPNAdapterErrorAuthFailed: return @"General authentication failure";
|
|
case OpenVPNAdapterErrorClientHalt: return @"HALT message from server received.";
|
|
case OpenVPNAdapterErrorClientRestart: return @"RESTART message from server received.";
|
|
case OpenVPNAdapterErrorRelay: return @"RELAY message from server received.";
|
|
case OpenVPNAdapterErrorRelayError: return @"RELAY error.";
|
|
case OpenVPNAdapterErrorPauseNumber: return nil;
|
|
case OpenVPNAdapterErrorReconnectNumber: return nil;
|
|
case OpenVPNAdapterErrorKeyLimitRenegNumber: return nil;
|
|
case OpenVPNAdapterErrorKeyStateError: return @"Received packet didn't match expected key state.";
|
|
case OpenVPNAdapterErrorProxyError: return @"HTTP proxy error.";
|
|
case OpenVPNAdapterErrorProxyNeedCreds: return @"HTTP proxy needs credentials.";
|
|
case OpenVPNAdapterErrorKevNegotiateError: return nil;
|
|
case OpenVPNAdapterErrorKevPendingError: return nil;
|
|
case OpenVPNAdapterErrorKevExpireNumber: return nil;
|
|
case OpenVPNAdapterErrorPKTIDInvalid: return nil;
|
|
case OpenVPNAdapterErrorPKTIDBacktrack: return nil;
|
|
case OpenVPNAdapterErrorPKTIDExpire: return nil;
|
|
case OpenVPNAdapterErrorPKTIDReplay: return nil;
|
|
case OpenVPNAdapterErrorPKTIDTimeBacktrack: return nil;
|
|
case OpenVPNAdapterErrorDynamicChallenge: return nil;
|
|
case OpenVPNAdapterErrorEPKIError: return nil;
|
|
case OpenVPNAdapterErrorEPKIInvalidAlias: return nil;
|
|
case OpenVPNAdapterErrorUnknown: return @"Unknown error.";
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation NSError (OpenVPNMbedTLSErrorGeneration)
|
|
|
|
+ (NSError *)ovpn_errorObjectForMbedTLSError:(NSInteger)errorCode description:(NSString *)description {
|
|
size_t length = 1024;
|
|
char *buffer = malloc(length);
|
|
|
|
mbedtls_strerror(errorCode, buffer, length);
|
|
|
|
NSString *reason = [NSString stringWithUTF8String:buffer];
|
|
|
|
free(buffer);
|
|
|
|
return [NSError errorWithDomain:OpenVPNIdentityErrorDomain code:errorCode userInfo:@{
|
|
NSLocalizedDescriptionKey: description,
|
|
NSLocalizedFailureReasonErrorKey: reason
|
|
}];
|
|
}
|
|
|
|
@end
|