shogo4405 / HaishinKit.swift

Camera and Microphone streaming library via RTMP and SRT for iOS, macOS, tvOS and visionOS.
BSD 3-Clause "New" or "Revised" License
2.77k stars 614 forks source link

adobe authentication for rtmp not implemented #1

Closed mrbemani closed 8 years ago

mrbemani commented 8 years ago

here is my temporary solution:

case "NetConnection.Connect.Rejected":
                    if self.user == "" || self.passwd == "" {
                        break
                    }
                    let cc = (data["description"] as! String).componentsSeparatedByString("?")
                    if (cc.count < 2) {
                        reconnect("/?authmod=adobe&user=\(self.user)")
                    } else if (cc.count > 1) {
                        let p = cc[1] as String
                        let params = p.componentsSeparatedByString("&")

                        var salt = "", challenge = "", opaque = ""
                        for i in 0..<params.count {
                            let pa = params[i]
                            let sIdx = pa.startIndex
                            if pa.substringToIndex(sIdx.advancedBy(5)) == "salt=" {
                                salt = pa.substringFromIndex(sIdx.advancedBy(5))
                            } else if pa.substringToIndex(sIdx.advancedBy(10)) == "challenge=" {
                                challenge = pa.substringFromIndex(sIdx.advancedBy(10))
                            } else if pa.substringToIndex(sIdx.advancedBy(7)) == "opaque=" {
                                opaque = pa.substringFromIndex(sIdx.advancedBy(7))
                            }
                        }

                        let newParams = adobe_auth(self.user, password: self.passwd, salt: salt, opaque: opaque, challenge: challenge)
                        print(newParams)
                        reconnect(newParams)
                    }

and then add a user and passwd properties and adobe_auth method as follow:

func adobe_auth(user:String, password:String, salt:String, opaque:String, challenge:String) -> String {
        var hashstr:String = ""
        let challenge2 = String(format: "%08x", random())

        hashstr = rawMD5Base64("\(user)\(salt)\(password)")
        if challenge != "" || opaque != "" {
            if opaque != "" {
                hashstr = "\(hashstr)\(opaque)"
            } else if challenge != "" {
                hashstr = "\(hashstr)\(challenge)"
            }
        }
        hashstr = rawMD5Base64("\(hashstr)\(challenge2)")

        var q = "/?authmod=adobe&user=\(user)&challenge=\(challenge2)&response=\(hashstr)"

        if opaque != "" {
            q = "\(q)&opaque=\(opaque)"
        }

        return q
    }

    private func rawMD5Base64(s:String) -> String {
        let data = s.dataUsingEncoding(NSUTF8StringEncoding)!
        var digest = [UInt8](count:Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
        CC_MD5(data.bytes, CC_LONG(data.length), &digest)
        let ret = NSData(bytes: digest, length: Int(CC_MD5_DIGEST_LENGTH)).base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
        return ret
    }

but the last method needs an header file:

#import <CommonCrypto/CommonCrypto.h>

added these two methods for connect with auth and reconnect:

public func connectWithUserAndPasswd(command: String, user: String, passwd: String, arguments: Any?...) {
        if let url:NSURL = NSURL(string: command) {
            self.user = user
            self.passwd = passwd
            orgUri = command // orgUri is an extra member variable
            _uri = command
            self.arguments = arguments
            addEventListener(Event.RTMP_STATUS, selector: "rtmpStatusHandler:")
            socket.connect(url.host!, port: url.port == nil ? RTMPConnection.defaultPort : UInt32(url.port!.intValue))
        }
    }

    public func reconnect(query: String) {
        if let url:NSURL = NSURL(string: orgUri + query) {
            _uri = orgUri + query
            socket.connect(url.host!, port: url.port == nil ? RTMPConnection.defaultPort : UInt32(url.port!.intValue))
        }
    }
shogo4405 commented 8 years ago

Thank u. I will implment adobe authn next.

shogo4405 commented 8 years ago

import CommonCrypto/CommonCrypto.h

So difficult. Swift framework project can't include Bridging Header X)

mrbemani commented 8 years ago

Try CryptoSwift

shogo4405 commented 8 years ago

implemented https://github.com/shogo4405/lf.swift/commit/5c8c0a10810028462a68ee90a0cd808d61380910 i can release soon :)

Thank u

shogo4405 commented 8 years ago

released! https://github.com/shogo4405/lf.swift/releases/tag/0.1.4